[SCC] TIL (13)

suhan0304·2024년 9월 3일

SCC - TIL

목록 보기
13/17
post-thumbnail

Date : 2024.09.03


KnifeHit

  • Boss 별 패턴 구현

자세한 개발 내용은 하단의 개발 로그를 참고하자.

(9) : https://velog.io/@suhan0304/Unity-Knife-Hit-9


NIL (New I Learned)

base Keyword?

클래스를 상속받아 사용할 때 부모 클래스의 메서드에는 어떻게 접근할까? 그냥 단순히 부모 클래스에만 있는 메서드는 이름으로 바로 접근해서 사용가능하다. 물론 접근 제한이 private인 경우는 사용이 불가능하다. 하지만 저번 개발 내용을 보면 아시다시피 base 키워드를 사용해서 현재 클래스의 부모 클래스에 정의된 메서드나 속성을 호출해서 사용했다. 그렇다면 둘이 어떤 차이가 있을까?

둘의 차이는 바로 사용하고자 하는 메서드의 오버라이드 여부에 따라 결정된다.

  1. 직접 메서드나 속성명으로 호출해서 사용하는 방식의 경우 자식 클래스에서 오버라이드되어 있으면, 오버라이드된 메서드나 속성이 호출된다.

  2. base 키워드를 사용하면 현재 클래스의 부모 클래스의 메서드를 호출하는 것은 동일한데, 오버라이드되어 있다 하더라도 부모 클래스의 원래 구현을 호출할 수 있다.

따라서, 자식 클래스에서 오버라이드 시킨 메서드가 아닌 부모 클래스의 메서드를 실행시키고 싶으면 base 키워드를 사용하면 되고 오버라이드 시킨 적 없는 부모 클래스에만 존재하는 단순 메서드의 경우는 단순히 직접 호출해서 사용하면 된다.

물론 이런 클래스 간의 메서드 접근은 접근 제한자에 의해 보호되고 제한된다. 접근 제한자에 대한 내용은 공식 문서를 참고하자.

Call GameObject in Script (Child)

Transform.Find를 사용하면 계층 구조를 쉽게 탐색하여 자식 오브젝트들을 가져올 수 있다. 이때 자식의 자식 오브젝트의 경우 탐색할 때 /를 사용하여 자식의 자식임을 나타내서 가져올 수 있다.

using UnityEngine;

public class Sample : MonoBehaviour
{
    private GameObject child;
    private GameObject grandson1;
    private GameObject grandson2;
    private GameObject grandson3;

    private void Start()
    {
        // 자식 오브젝트를 찾습니다.
        child = transform.Find("child;").gameObject;

        // 손자 오브젝트의 자식들을 찾습니다.
        segment1 = transform.Find("child/grandson1").gameObject;
        segment2 = transform.Find("child/grandson1").gameObject;
        segment3 = transform.Find("child/grandson1").gameObject;


        // 이제 이 오브젝트들을 사용하여 원하는 로직을 구현할 수 있습니다.
    }
}

잊으면 안 되는게 Find 함수의 경우 자식 오브젝트들을 모두 방문하며 이름을 비교하는 것이기 때문에 당연하게도 계층 구조가 깊거나 복잡한 경우 성능에 영향을 줄 수 있다. 계층구조가 깊을때 자주 호출하거나 반복되는 경우 성능 저하를 유발하는 원인이 되기도 한다.

이 외에도 아래와 같은 단점이 있다.

  • 오타 및 경로 오류로 인한 null 반환 문제
  • 런타임 오브젝트만 탐색 가능 (비활성화된 오브젝트 탐색 불가)
  • 계층 구조에 의존한다는 점
  • 이름 중복이나 중첩이 복잡한 경우 탐색 실패

대안으로는

  • Inspector에서 그냥 할당해서 사용하기
  • StartAwake 시점에 캐싱해두기
  • GetComponentInChildren 사용하기

GetComponentInChildren의 경우 Find 메서드와 동일하게 계층 구조의 모든 오브젝트들을 돌면서 탐색하기 때문에 성능이 엄청 좋다고는 할 수 없지만 문자열 경로를 통해 오브젝트를 찾지 않으며 컴포넌트 타입을 기반으로 탐색하기 때문에 더 직접적이고 효율적이다.

Random Direction

랜덤한 방향을 잡는 방법은 다양한데 그 중 제일 쉬운건 유니티에서 제공하는 Random.insideUnitCircle을 사용하는 것이다. Random.insideUnitCircle은 2D 공간에서 반지름이 1인 원 내부에 있는 랜덤한 점을 나타내는 Vector2를 반환한다. 물론 내부에 있는 랜덤한 점이기 때문에 벡터의 크기가 1 이하라서 방향벡터로 쓰고 싶다면 normalized 해주어야 한다.

Vector2 randomDirection = Random.insideUnitCircle.normalized;

이 외에도 3D에서 사용할 수 있는 insodeUnitSphere와 같은 메서드도 있다.

더 자세한 내용은 유니티 공식 문서를 참고하면 좋을 것 같다.

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글