Post

유니티3D - 4

유니티3D - 4

이번 목표

TODO 리스트에 있는 감속과 애니메이션 회전을 마무리하고자한다.

감속, 방향전환 문제

현상: 진행 방향에서 반대키 입력 시 감속 후 역방향으로 넘어가며 어색함이 느껴진다. 멈춤 애니메이션을 추가하거나 게임성 위주로 즉시 반전 중 하나를 선택할 수 있다. 전자는 콘텐츠 필요, 후자는 제어 로직으로 해결 가능하다. 문제는 MoveTowards가 목표 벡터 쪽으로 점진적으로 이동하며, 부호 반전 구간에서 시간이 길게 느껴지는 점이다. 예: 1 → 0.5 → 0 → -0.5 → -1

1
horizontalVelocity = Vector3.MoveTowards(horizontalVelocity, moveDir * maxSpeed, acceleration * Time.deltaTime);

가속/감속 계수를 키우면 체감은 개선되지만 디테일 제어가 어렵다. “현재 속도 방향과 목표 방향이 반대”인 경우 수평 속도를 즉시 0으로 리셋하는 방식은 반응성은 좋지만 튐이 크다. 절충안으로 보간 방식을 바꾼다. MoveTowards() 함수를 이용하지않고 Lerp() 함수를 이용해서 전환하는 방법으로 해야겠다.

1
2
Vector3 targetVelocity = moveDir * maxSpeed;
horizontalVelocity = Vector3.Lerp(horizontalVelocity, targetVelocity, acceleration * Time.deltaTime);

확실히 방향 전환이 더 자연스러워진다. 멈춤 애니메이션을 보강하면 시각적 이질감도 줄어든다.

애니메이션 방향문제

언리얼처럼 소스 애니메이션에 키를 새로 넣는 방식은 FBX 임포트 특성상 어렵다. 대신 에이밍 시 메쉬 로컬 Y 회전으로 보정하는 방법을 썼다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    void OnAiming()
    {
        animator.SetBool("Aiming", true);
        targetWeight = 1f;
        isBlending = true;
        transform.localRotation = Quaternion.Euler(0f, 50f, 0f);
    }

    void OffAiming()
    {
        animator.SetBool("Aiming", false);
        targetWeight = 0f;
        isBlending = true;
        transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
    }

잘된다 하지만 처음에 localRotation으로 하지 않고 Rotation값을 했다가 Y축방향으로 계속 +50 되는 현상이 일어나는걸 보고 월드 좌표계에서 되는구나 하고 찾아냈다.

회전조정

생각보다 간단한 문제들이였던것… 추가로 오늘은 총소리를 추가하고 끝내보도록해보자

총소리 추가

일단 소리 재생시키기 위해서는 메인카메라에 Audio Listener 컴포넌트가 있어야한다 추가시켜줬다. AuidoClip
AudioClip은 재생하려는 소리 파일을 나타내는 클래스이고 WAV, MP3, OGG 등 다양한 형식의 오디오 파일을 지원합니다.

AudioSource AudioSource 컴포넌트는 AudioClip을 재생하는 역할을 한다.
AudioSource 에서 소리가 재생되어 3D사운드 설정, 볼륨 설정, 거리 설정, 등등을 해준다.

1
2
3
4
5
6
7
8
9
   private void Awake()
   {
       data.source = GetComponent<AudioSource>();
       data.source.clip = data.GunShotClip;
       data.source.spatialBlend = 1f; // 3D사운드
       data.source.minDistance = 1f;
       data.source.maxDistance = 15f;
       data.source.volume = 0.5f;
   }

근데 처음에는 Start() 함수에서 실행했는데 null값이 나오는 것이였다. 그래서 Awaker()로 바꾸니까 잘 반영되었다.
문제해결은 했지만 그 이유가 궁금해서 찾아봤다.
직렬화 과정에서 Start() 보다 struct값이 먼저 덮어씌어져서 그럴수도 있다고했는데 이건 내가 Null값을 넣었을 때 현상이다.
그래서 문제가 내가 실수를 했겠구나 하고 디버깅을 해보니 Start()함수자체가 호출이안되는거였다.
아마 상속받은 자식클래스에서 Super콜을 하지않아서 그런거였다.

This post is licensed under CC BY 4.0 by the author.