[Unity] 구성 요소의 초기화에서 Awake를 사용할지 아니면 자체 제작 방법을 사용할지, 예외적으로 발생할 때의 정지 방법은 다르다

7864 단어 UnityC#
즉석에서 Instantiate 등 생성된 구성 요소를 초기화할 때 크게 두 가지 방법으로 나눌 수 있다고 생각합니다.
  • Awake()처럼 Unity 메시지를 초기화합니다
  • Init () 와 같이 호출 방법을 초기화합니다
  • 둘 다 각자의 장점이 있다.
    예를 들어 Awake가 언제 불리었는지, 간단명료하게 측면과 구성 요소를 생성하는 데 의존하지 않을 수 있는 구조이다.
    다른 한편, 제작 방법을 원한다면 매개 변수를 자유롭게 바꿀 수도 있고 유니티의 독특한 규격에 의존하지 않을 수도 있다.
    Instantiate 및 AddComponent에 비해 성능이 크게 떨어지지 않습니다.
    따라서 매개 변수가 같은 곳에서 부르지 않으면 스타일 이외에는 큰 차이가 없다.
    내 생각엔.

    견본


    그 차이는 이상 처리에 있다.
    다음 두 코드는 위에서 기술한 두 가지 패턴을 재현하는 조합이다.

    모드 1(Awake로 초기화)


    Manager.cs
    public class Manager : MonoBehaviour {
        // ゲーム開始時にキャラクターを生成する
        void Awake() {
            Debug.Log("パターン1(Awakeで初期化)");
    
            var gameCharacter = new GameObject("GameCharacter");
            gameCharacter.AddComponent<GameCharacter>();
    
            Debug.Log("Game Start!");
        }
    }
    
    GameCharacter.cs
    public class GameCharacter : MonoBehaviour {
        // だがそいつは初期化時にエラーを起こしてしまう死のキャラクターだった!
        void Awake() {
            Debug.Log("Initializing GameCharacter");
            throw new System.Exception("GameCharacter: Initialization failed");
        }
    }
    

    모드 2(Init 메서드로 초기화)


    Manager.cs
    public class Manager : MonoBehaviour {
        // ゲーム開始時にキャラクターを生成する
        void Awake() {
            Debug.Log("パターン2(Initメソッドで初期化)");
    
            var gameCharacter = new GameObject("GameCharacter");
            gameCharacter.AddComponent<GameCharacter>().Init();
    
            Debug.Log("Game Start!");
        }
    
    GameCharacter.cs
    public class GameCharacter : MonoBehaviour {
        // だがそいつは初期化時にエラーを起こしてしまう死のキャラクターだった!
        public void Init() {
            Debug.Log("Initializing GameCharacter");
            throw new System.Exception("GameCharacter: Initialization failed");
        }
    }
    

    결과



    관리자를 구성할 때 1은 Game Start에 도달하고 2는 도착하지 않습니다.

    검증


    C#의 규격상 2가 있을 것이다.
    즉 "1은 예외가 발생했을 텐데 멈추지 않았다"는 것이다.
    유니티가 Awake라고 했을 때 뭘 하고 있었을 거야.
    예를 들면 AddComponent입니다. 물론 Instantiate에서 Awake라고 불리는 것도 마찬가지입니다.
    트리로 둘러봐봐.이 다른 부분은 아까와 같다.
    // パターン1 + try-catch
    try {
        var gameCharacter = new GameObject("GameCharacter");
        gameCharacter.AddComponent<GameCharacter>();
    } catch {
        Debug.LogWarning("キャラクター生成できなかったけどいいよね?");
    }
    
    // パターン2 + try-catch
    try {
        var gameCharacter = new GameObject("GameCharacter");
        gameCharacter.AddComponent<GameCharacter>().Init();
    } catch {
        Debug.LogWarning("キャラクター生成できなかったけどいいよね?");
    }
    

    전자는 예외를 포착할 수 없다.포위되지 않은 상태와 완전히 같다.
    또한 로그와 창고 추적을 통해 알 수 있듯이 초기화는 실행을 지연시키는 것이 아니다.
    이것은 "모든 소식이 처음부터 try-catch에 둘러싸여 있었다"는 것입니까? 아니면 같은 것입니까?

    총결산

  • Unity의 C#이상 처리는 Unity가 메시지를 호출할 때마다 분리됩니다
  • 스크립트 과정에서 메시지를 호출하면 메시지 내부에 이상이 있어도 앞의 처리가 멈추지 않습니다
  • 프로그램을 쓸 때 예외가 발생했을 때의 정지 방법을 일부러 의식하지는 않지만, 발표 버전에서 예외가 뚜렷하게 발생한 상태를 만나면 무엇이 움직였고 무엇을 멈추었는지 원인을 확인할 때 유용한 지식이 될 수 있다.
    그럼에도 불구하고 Update처럼 PlayerLoop에서 호출된다는 소식은 당연히 이런 구조지만 Awake 등이 중간에 호출된 경우에도 마찬가지라는 것은 의외다.

    좋은 웹페이지 즐겨찾기