Components Working Together
Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 4 of 64.
Small components still need each other. A Jetpack needs Fuel on the same object, so it finds the Fuel once in Awake, keeps it in a field, and talks to it through two small public methods:
public class Fuel : MonoBehaviour
{
public float amount = 10f;
public bool IsEmpty()
{
return amount <= 0f;
}
public void Burn(float units)
{
amount = Mathf.Max(amount - units, 0f);
}
}[RequireComponent(typeof(Fuel))]
public class Jetpack : MonoBehaviour
{
public float lift = 4f;
private Fuel fuel;
void Awake()
{
fuel = GetComponent<Fuel>();
}
void Update()
{
if (Keyboard.current.spaceKey.isPressed && !fuel.IsEmpty())
{
fuel.Burn(Time.deltaTime);
transform.position += Vector3.up * lift * Time.deltaTime;
}
}
}[RequireComponent(typeof(Fuel))] makes Unity add a Fuel whenever a Jetpack is added, in the Editor or with AddComponent, and refuses to remove that Fuel while the Jetpack is there. Unity checks it only at the moment the Jetpack is added, so a Jetpack that was already on an object before you wrote the attribute keeps its old setup. Awake is the place to fetch it: it runs once, and the object's own components are all there by then.
The Jetpack never changes amount itself. Fuel decides what burning means, such as never dropping below 0, and the Jetpack only asks. If Fuel later shows a gauge or refills from pickups, the Jetpack does not change.
Challenge
EasyMake the skater's dash cost stamina.
- In
Stamina, addpublic bool TrySpend(float cost): ifcurrentis at leastcost, take it off and returntrue, elsefalse. - Put
[RequireComponent(typeof(Stamina))]abovepublic class Dash, and fetch it into a field inAwake(). - On Space, dash only if
TrySpend(cost)is true; otherwise logToo tired.
Press Play: after two dashes the Console says Too tired. Then Check.
Try it yourself
using UnityEngine;
using UnityEngine.InputSystem;
public class Dash : MonoBehaviour
{
public float distance = 3f;
public float cost = 40f;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
transform.position += Vector3.forward * distance;
}
}
}
All lessons in Game Architecture in Unity
1Components, Not Hierarchies
Small ComponentsA Base Enemy ScriptAbstract ComponentsComponents Working TogetherRecap: Modular TurretRecap: Twin Cannon4Serialized Data
Serializable ClassesLists in the InspectorEnums in the InspectorRecap: Loot TableRecap: Roll the Loot2Interfaces in Unity
IDamageableInterfaces and TryGetComponentGetComponentsRecap: Interact KeyRecap: Nearest in ReachPractice on your own: Unity playground