Interfaces and TryGetComponent
Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 7 of 50.
TryGetComponent asks for a component and tells you whether it found one, in one call. It works with interfaces too, which makes it the usual way to ask whatever you hit whether it can be hurt. This mine hurts everything around it that is IDamageable:
public class Mine : MonoBehaviour
{
public float radius = 3f;
public int damage = 5;
void OnTriggerEnter(Collider other)
{
foreach (Collider c in Physics.OverlapSphere(transform.position, radius))
{
if (c.TryGetComponent(out IDamageable target))
{
target.TakeDamage(damage);
}
}
Destroy(gameObject);
}
}out IDamageable target declares the variable inside the call. TryGetComponent returns true and fills target when the object has a component that implements IDamageable; otherwise it returns false and target is null. It looks only at that one object, never its parent or children.
GetComponent reports a missing class and a missing interface differently. In the Editor, GetComponent<Rigidbody>() on an object with no Rigidbody returns Unity's fake null: == null is true, but ?. does not see it and the call throws MissingComponentException. An interface has no fake null: GetComponent<IDamageable>() returns a real C# null, so == null and ?. both work on it. TryGetComponent avoids the question for both, and it allocates nothing in the Editor when the component is missing.
Challenge
EasyThe laser tower turns with the left and right arrows, and Space calls Fire() in Laser.cs. Write Fire. Cast a ray from the tower along its forward direction, range units long (the Inspector sets 10), then:
- If it hits something that has an IDamageable, call
TakeDamage(damage)on it and logHitand the object's name, such asHit Robot. - If the thing has no IDamageable but has a Rigidbody, push it with
AddForce(transform.forward * push, ForceMode.Impulse)and logPushedand its name. - Anything else logs
Blocked byand its name, such asBlocked by Pillar. A ray that hits nothing logsMissed.
Use TryGetComponent for both lookups. IDamageable.cs, Robot.cs and Balloon.cs are ready. Press Play and fire in every direction, then Check.
Try it yourself
using UnityEngine;
using UnityEngine.InputSystem;
public class Laser : MonoBehaviour
{
public float range = 10f;
public int damage = 1;
public float push = 5f;
public float turnSpeed = 90f;
private InputAction moveAction;
void Start()
{
moveAction = InputSystem.actions.FindAction("Move");
}
void Update()
{
float turn = moveAction.ReadValue<Vector2>().x;
transform.Rotate(0f, turn * turnSpeed * Time.deltaTime, 0f);
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
Fire();
}
}
void Fire()
{
// Cast a ray forward, range units long, and deal with what it hits
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Game Architecture in Unity
1Components, Not Hierarchies
Small ComponentsA Base Enemy ScriptAbstract ComponentsComponents Working TogetherRecap: Modular Turret10Project: Arena Survivor
The HeroEnemy Types