๋ฐ˜์‘ํ˜•

๐ŸŽฏ Unity์˜ TryGetComponent ์ œ๋Œ€๋กœ ์•Œ๊ธฐ

Unity ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์˜ค๋ธŒ์ ํŠธ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•  ์ผ์ด ์ž์ฃผ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด GetComponent<T>()์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ NullReferenceException์„ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ์œ„ํ—˜์„ ํ”ผํ•˜๊ณ ์ž Unity์—์„œ๋Š” ๋ณด๋‹ค ์•ˆ์ „ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” TryGetComponent<T>() ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” TryGetComponent์˜ ๊ธฐ๋ณธ ๊ฐœ๋…, ์‚ฌ์šฉ๋ฒ•, ์‹ค์ œ ํ™œ์šฉ ์˜ˆ์‹œ, ๊ทธ๋ฆฌ๊ณ  GetComponent์™€์˜ ์ฐจ์ด์ ๊นŒ์ง€ ์ƒ์„ธํžˆ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ TryGetComponent๋ž€?

TryGetComponent<T>(out T component)๋Š” ํŠน์ • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ˜„์žฌ GameObject์— ์กด์žฌํ•  ๊ฒฝ์šฐ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

โœ… ๋ฌธ๋ฒ•

public bool TryGetComponent<T>(out T component) where T : Component;
  • T : ๊ฐ€์ ธ์˜ค๋ ค๋Š” ์ปดํฌ๋„ŒํŠธ ํƒ€์ž… (์˜ˆ: Rigidbody, Collider, Animator, ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ ๋“ฑ)
  • component : ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ด์„ out ๋งค๊ฐœ๋ณ€์ˆ˜
  • ๋ฆฌํ„ด๊ฐ’ : ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌํ•˜๋ฉด true, ์—†์œผ๋ฉด false

๐Ÿ” ์™œ TryGetComponent๋ฅผ ์จ์•ผ ํ•˜๋‚˜์š”?

๊ธฐ์กด์˜ GetComponent๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

Rigidbody rb = GetComponent<Rigidbody>();
rb.AddForce(Vector3.up * 10f); // Rigidbody๊ฐ€ ์—†์œผ๋ฉด NullReferenceException!

์ด ์ฝ”๋“œ์—์„œ Rigidbody๊ฐ€ ๋ถ™์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด NullReferenceException์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์กฐ๊ฑด๋ฌธ์„ ๋„ฃ์–ด์•ผ ํ•˜์ฃ :

Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
{
    rb.AddForce(Vector3.up * 10f);
}

ํ•˜์ง€๋งŒ TryGetComponent๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ์ฝ”๋“œ๋ฅผ ๋” ๊น”๋”ํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

if (TryGetComponent<Rigidbody>(out Rigidbody rb))
{
    rb.AddForce(Vector3.up * 10f);
}
  • ์žฅ์ : ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ•„์š” ์—†์Œ
  • ์„ฑ๋Šฅ: ๋‚ด๋ถ€์ ์œผ๋กœ GetComponent๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์•ฝ๊ฐ„ ๋” ๋‚˜์€ ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ์Œ (Unity ๊ณต์‹ ๋ฌธ์„œ ๊ธฐ์ค€)
  • ๊ฐ€๋…์„ฑ: ์กฐ๊ฑด๋ฌธ ์•ˆ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง

๐Ÿ’ก ์‹ค์ „ ์˜ˆ์ œ

๐ŸŽฏ ์˜ˆ์ œ 1: ์ด์•Œ์ด ์ ์—๊ฒŒ ๋ถ€๋”ชํ˜”์„ ๋•Œ ๋ฐ๋ฏธ์ง€ ์ฃผ๊ธฐ

private void OnTriggerEnter(Collider other)
{
    if (other.TryGetComponent<Enemy>(out Enemy enemy))
    {
        enemy.TakeDamage(10f);
        Destroy(gameObject); // ์ด์•Œ ์‚ญ์ œ
    }
}

์ด์•Œ์ด ๋ถ€๋”ชํžŒ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ Enemy ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋ฐ๋ฏธ์ง€๋ฅผ ์ฃผ๊ณ , ์ด์•Œ์€ ํŒŒ๊ดดํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ ์ด ์•„๋‹Œ ์˜ค๋ธŒ์ ํŠธ๋ผ๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐ŸŽฏ ์˜ˆ์ œ 2: ์ธํ„ฐ๋ž™์…˜ ๊ฐ€๋Šฅํ•œ ์˜ค๋ธŒ์ ํŠธ ์ฐพ๊ธฐ

private void Interact(GameObject target)
{
    if (target.TryGetComponent<IInteractable>(out IInteractable interactable))
    {
        interactable.Interact();
    }
}

IInteractable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ์˜ค๋ธŒ์ ํŠธ์™€๋งŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”„ GetComponent vs TryGetComponent

ํ•ญ๋ชฉ GetComponent<T>() TryGetComponent<T>(out T)
๋ฐ˜ํ™˜๊ฐ’ ์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด ๋˜๋Š” null true ๋˜๋Š” false
์˜ˆ์™ธ ์ฒ˜๋ฆฌ null ์ฒดํฌ ํ•„์š” ์˜ˆ์™ธ ์—†์Œ
์„ฑ๋Šฅ ์•ฝ๊ฐ„ ๋А๋ฆด ์ˆ˜ ์žˆ์Œ ์•ฝ๊ฐ„ ๋” ํšจ์œจ์ 
์ฝ”๋“œ ๊ฐ€๋…์„ฑ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์Œ ๊ฐ„๊ฒฐํ•˜๊ณ  ์•ˆ์ „ํ•จ
 

๐Ÿง  ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

TryGetComponent๋Š” Unity ๊ฐœ๋ฐœ์—์„œ ๋ณด๋‹ค ์•ˆ์ „ํ•˜๊ณ  ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ถฉ๋Œ ์ฒ˜๋ฆฌ, ์ƒํ˜ธ์ž‘์šฉ, ์กฐ๊ฑด๋ถ€ ๋กœ์ง ๋“ฑ์—์„œ ๋„ ์˜ˆ์™ธ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

์•ž์œผ๋กœ GetComponent ๋Œ€์‹  TryGetComponent๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์—ฌ๋ณด์„ธ์š”. ์‹ค์ˆ˜๋„ ์ค„๊ณ , ์œ ์ง€๋ณด์ˆ˜๋„ ์‰ฌ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ฐ˜์‘ํ˜•