Menu
CoddyTech

인터페이스와 TryGetComponent

Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 50개 중 7번째.

TryGetComponent은 한 번의 호출로 컴포넌트를 찾고, 찾았는지도 알려줍니다. 인터페이스에서도 작동하므로, 충돌한 대상이 피해를 받을 수 있는지 확인할 때 일반적으로 사용합니다. 이 지뢰는 주변에 있는 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은 호출 안에서 변수를 선언합니다. 객체에 IDamageable을 구현하는 컴포넌트가 있으면 TryGetComponent는 true를 반환하고 target에 값을 할당합니다. 그렇지 않으면 false를 반환하고 target은 null입니다. 이 메서드는 해당 객체 하나만 확인하며, 부모나 자식 객체는 확인하지 않습니다.

GetComponent는 클래스가 없는 경우와 인터페이스가 없는 경우를 다르게 처리합니다. Editor에서 Rigidbody가 없는 객체에 GetComponent<Rigidbody>()를 호출하면 Unity의 가짜 null을 반환합니다. == null은 true이지만, ?.는 이를 감지하지 못하고 호출 시 MissingComponentException이 발생합니다. 인터페이스에는 가짜 null이 없습니다. GetComponent<IDamageable>()은 실제 C# null을 반환하므로, == null과 ?. 모두 사용할 수 있습니다. TryGetComponent를 사용하면 두 경우 모두 이런 문제를 피할 수 있으며, Editor에서 컴포넌트를 찾지 못해도 메모리를 할당하지 않습니다.

challenge icon

챌린지

쉬움

레이저 타워는 왼쪽 및 오른쪽 화살표 키로 회전하고, Space 키를 누르면 Laser.cs에서 Fire()를 호출합니다. Fire를 작성하세요. 타워의 앞 방향으로 range 단위 길이만큼 광선을 쏘고(Inspector에서 10으로 설정), 다음을 수행하세요:

  • IDamageable이 있는 대상을 맞히면 해당 대상에 TakeDamage(damage)를 호출하고, Hit와 대상의 이름을 로그로 출력합니다(예: Hit Robot).
  • 대상에 IDamageable은 없지만 Rigidbody가 있으면 AddForce(transform.forward * push, ForceMode.Impulse)로 밀고, Pushed와 대상의 이름을 로그로 출력합니다.
  • 그 외의 대상은 Blocked by와 대상의 이름을 로그로 출력합니다(예: Blocked by Pillar). 아무것도 맞히지 못한 광선은 Missed를 로그로 출력합니다.

두 가지 검색 모두에 TryGetComponent를 사용하세요. IDamageable.cs, Robot.cs 및 Balloon.cs는 준비되어 있습니다. Play를 누르고 모든 방향으로 발사한 다음 Check를 누르세요.

직접 해보기

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()
    {
        // 앞쪽으로 range 단위 길이의 광선을 쏘고, 광선에 맞은 대상을 처리합니다
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Unity 게임 아키텍처의 모든 레슨