오늘 학습 키워드

유니티 입문 팀 프로젝트 4일차

오늘 학습 한 내용을 나만의 언어로 정리하기

사운드 매니저 만들기

  • 기본적인 틀은 저번에 만들었던 TopDown에서 가져왔음.
// SoundManager.cs
public class SoundManager : MonoBehaviour
{
    public static SoundManager instance;
    [SerializeField][Range(0f, 1f)] private float soundEffectVolume;
    [SerializeField][Range(0f, 1f)] private float musicVolume;
 
    private AudioSource musicAudioSource;
    public AudioClip musicClip;
 
    public SoundSource soundSourcePrefab;
 
    private void Awake()
    {
        instance = this;
        DontDestroyOnLoad(gameObject);
        musicAudioSource = GetComponent<AudioSource>();
        musicAudioSource.volume = musicVolume;
        musicAudioSource.loop = true;
    }
 
    private void Start()
    {
        ChangeBackGroundMusic(musicClip);
    }
 
    public void ChangeBackGroundMusic(AudioClip clip)
    {
        musicAudioSource.Stop();
        musicAudioSource.clip = clip;
        musicAudioSource.Play();
    }
 
    public static AudioSource PlayClip(AudioClip clip, bool loop)
    {
        SoundSource obj = Instantiate(instance.soundSourcePrefab);
        SoundSource soundSource = obj.GetComponent<SoundSource>();
        return soundSource.Play(clip, instance.soundEffectVolume, loop);
    }
}
public class SoundSource : MonoBehaviour
{
    private AudioSource _audioSource;
 
    public AudioSource Play(AudioClip clip, float soundEffectVolume, bool loop)
    {
        if (_audioSource == null)
            _audioSource = GetComponent<AudioSource>();
 
        CancelInvoke();
        _audioSource.clip = clip;
        _audioSource.volume = soundEffectVolume;
        _audioSource.loop = loop;
        _audioSource.Play();
 
        if(!loop) Invoke("Disable", clip.length + 2);
        return _audioSource;
    }
 
    public void Disable()
    {
        _audioSource?.Stop();
        Destroy(this.gameObject);
    }
}

슬라이드 소리 처리

  • 슬라이드는 키를 누르고 있으면 계속 함수를 호출하다보니 AudioSource가 너무 많이 생성되는 문제가 있었음.
  • 그래서 차라리 AudioSource를 플레이어가 가지고 있게 하도록 했음.
  • 플레이어가 Slide Source를 가지고 있으면 슬라이드 소리를 출력하지 않도록 함
// 슬라이드 키 누르고 있을 때 작동되는 부분
public void StartSliding()
{
    // Debug.Log("Slide");
    if (slideSource == null) slideSource = SoundManager.PlayClip(slideSound, true);
    isSlide = true;
    StartSlide();
    jumpCount = 0;
    
}
 
// 슬라이드 키 뗄 때 작동되는 부분
public void StopSliding(InputAction.CallbackContext context)
{
    // Debug.Log("Stop Slide");
    isSlide = false;
    OnSlideAnimationEnd();
    if(slideSource != null)
    {
        slideSource.gameObject.GetComponent<SoundSource>()?.Disable();
        slideSource = null;
    }
}

맞으면 다른 행동 못하게 잠깐 막기

  • 이거 어떻게 해야하나 고민 많이 했는데, 같은 팀원분들이 이런 코드가 있다고 해서 좀 찾아봄
InputAction targetAction = inputActions.FindAction(actionName); // 이걸로 특정 액션 찾고
targetAction.Disable(); // 비활성화
targetAction.Enable();
  • 그래서 좀 더 찾아봐서, 모든 입력이 안되도록 만들어봄
// 그냥 맞은거
public void StartInvincible()
{
    CancelInvoke("EndInvincible");
    if (!isInvincible) aniHandler.StartInvincible();
    isInvincible = true;
 
    playerInput.currentActionMap.Disable(); // 그냥 맞은거면 Disable
    Invoke("EndInvincible", invincibleTime);
}
 
// 아이템 써서 무적 시작부분
public void StartInvincible(float itemInvincibleTime)
{
    
    CancelInvoke("EndInvincible");
    if (!isInvincible) aniHandler.StartInvincible();
    isInvincible = true;
    Invoke("EndInvincible", itemInvincibleTime);
}
 
public void EndInvincible()
{
    // 무적 끝나는 부분
    // Debug.Log("End Invincible");
    playerInput.currentActionMap.Enable();
    isInvincible = false;
    aniHandler.EndInvincible();
}

학습하며 겪었던 문제점 & 에러

문제 1

  • 문제&에러에 대한 정의

플레이어가 공격 판정을 할 때 Attack Pivot을 활성화 시켜, 그 안에 있는 콜라이더와의 접촉 여부를 체크하려 했음. 하지만 Attack Pivot의 OnTriggerEnter와 플레이어의 OnTriggerEnter가 동시에 일어나는 것으로 보임

  • 해결 방법

Player의 자식 오브젝트로 Attack Pivot이 있어서 생긴 일입니다. 자식에서 충돌이 일어나면 부모도 그 충돌을 감지하기 때문에, Attack Pivot을 Player의 자식 오브젝트가 아닌 형제 오브젝트로 있도록 변경하기

  • 새롭게 알게 된 점

자식 오브젝트의 콜라이더에 부딪혀도 부모도 인지한다!!!

문제 2

  • 문제&에러에 대한 정의

애니메이터가 싹 다 사라졌다.. 그리고는 오류가 났다.

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.Graphs.AnimationStateMachine.Graph.GenerateConnectionKey (UnityEditor.Graphs.Node srcNode, UnityEditor.Graphs.Node dstNode) (at <4017f98979a4402db3b23276f8a9e04e>:0)
  • 내가 한 시도

일단 애니메이터를 복붙해서 그 파일은 괜찮은지 확인해 보았으나 여전히 오류가 남.

  • 해결 방법

껏다 키니 나았음.

  • 새롭게 알게 된 점

애니메이터 파일은 YAML 형식으로 되어있다. 그러니 깨진 것 같으면 한번 메모장으로 열어보자.

  • 이 문제&에러를 다시 만나게 되었다면?

애니메이터 파일 열어보고 별 문제 없으면 그냥 껐다 켜보자.

문제 3

  • 문제&에러에 대한 정의

슬라이드 키를 뗐을 때 빠르게 일어나지 않았음. + 제대로 끝나지 않았을 때 버벅임

원래 코드는 아래와 같았음. 기존의 슬라이드는 키가 입력되고 있을 때 계속 부르는 방식이었음 (fixed update에서 키 확인받고 호출)

private void FixedUpdate()
{
    ...
    if (slideAction.action.IsPressed()) StartSliding();
}
  • 내가 한 시도

기존의 방식에서 바꿔서 action.started 에 StartSlide를 할당했음

private void Start()
{
	...
    // 슬라이드 액션 설정
    slideAction.action.started += StartSliding;
    slideAction.action.canceled += StopSliding;
}
  • 해결 방법

저 시도를 하니까 자연스럽게 됐음!

  • 새롭게 알게 된 점

어차피 키가 눌리는 동안 실행되는거라면 키가 눌렸을 때 (Started), 키를 뗐을 때 (Canceled) 각각 설정해 두는 것도 답이다.

  • 이 문제&에러를 다시 만나게 되었다면?

내가 구현할 애니메이션의 형태에 따라 방법을 잘 생각해 봐야겠다.

내일 학습 할 것은 무엇인지

속도 증가 / 맞으면서 딜넣는거 막기 / 피 감소