📖학습 내용

유니티 개발 학습 및 트러블슈팅 정리

싱글톤 중복 생성 시 DestroyStart() 실행 순서 문제 해결

문제 상황: - 싱글톤 오브젝트의 Awake()에서 중복 인스턴스를 Destroy(gameObject)로 파괴 예약해도, 실제 파괴는 프레임 후반에 일어나므로 해당 중복 인스턴스의 Start() 메서드가 실행되어 이벤트 구독 등 불필요한 초기화 작업 후 NullReferenceException을 유발함

해결 방법:

- **`OnDestroy()`에서 이벤트 해제:**
private void Start()
{
        playerResource = PlayerController.Instance.GetComponent<PlayerResource>();
    if(playerResource != null )
    {
            playerResource.OnGoldChanged += UpdateUI;
        UpdateUI();
    }
}

private void OnDestroy()
{
        playerResource.OnGoldChanged -= UpdateUI;
}

추가 가능 해결책:

  1. DestroyImmediate(): 즉시 파괴하지만 런타임 도중 사용은 예기치 않은 오류 가능성으로 비권장됨.
  2. 중복 인스턴스 플래그 사용: Awake()에서 중복 인스턴스 감지 시, bool isDuplicate = true;와 같은 플래그를 설정하고 Destroy(gameObject); 호출 후 즉시 return; 함.
  3. 생명주기 메서드 실행 차단: Start(), OnEnable(), Update() 등 주요 생명주기 메서드 시작 부분에 if (isDuplicate) return; 구문을 추가하여, 파괴될 예정인 중복 인스턴스가 어떠한 로직도 실행하지 않도록 원천 차단.

PlayOneShot 사운드 미재생 문제 (아이템 즉시 파괴 시)

문제 상황:

  • AudioSource.PlayOneShot() 호출 직후 해당 AudioSource를 가진 게임 오브젝트가 Destroy()되면, 소리가 재생될 충분한 시간을 갖지 못하고 끊기거나 재생되지 않음.

해결 방법: - AudioSource.PlayClipAtPoint(AudioClip clip, Vector3 position, float volume): 가장 간단한 방법. 지정된 위치에 임시 게임 오브젝트와 AudioSource를 생성하여 클립을 재생하고, 재생이 끝나면 자동으로 임시 오브젝트를 파괴.

public void PlaySoundEffect()
  {
      if (audioClip != null)
      {
          AudioSource.PlayClipAtPoint(audioClip,transform.position, 1.0f);
      }
  }

추가 가능 해결책:

  • 사운드 매니저 (AudioManager): 싱글톤 패턴의 사운드 매니저에게 사운드 재생을 요청하는 방식. 사운드 매니저가 실제 재생을 담당하므로 더 체계적인 사운드 관리가 가능.
  • 시각/물리적 요소만 즉시 제거 후 지연 파괴: 아이템의 RendererCollider를 먼저 비활성화하여 플레이어에게는 즉시 사라진 것처럼 보이게 하고, AudioSource.PlayOneShot()으로 소리를 재생한 뒤 Destroy(gameObject, clip.length);를 사용하여 사운드 클립 길이만큼 후에 실제 오브젝트를 파괴.

댓글남기기