Unity TPS1

장현태입니다·2025년 5월 17일

PlayerController

  • PlayerMovement
  • PlayerStatus

이렇게 플레이어는 세가지 구분을 해서 플레이어 구현

플레이어구성

플레이어 정보를 담을 빈오브젝트

  • 아바타(플레이어 모형)
  • 플레이어 시점(카메라)

TPS
3인칭 시점 : 플레이어를 직접 움직이는 시점
공격 시점 : 플레이어의 에임을 맞추는 시점

3인칭 시점)

공격시점)

3인칭과 공격시점을 이벤트를 사용해 SetActive를 조절하고, 시네머신의 우선카메라(Priority)를 선정해서 자연스럽게 카메라가 연결되도록 구현

플레이어 스텟 클래스

플레이어 시점마다 속도를 달리 부여하기 위해
WalkSpeed, RunSpeed 구별
마우스 회전에 따른 감도

bool을 이벤트로 적용해서 set 프로퍼티로 변수가 바뀔 때마다 이벤트 함수를 호출하도록 설정

카메라의 위치에 따른 시점 회전을 위해 aim,avatar Transform을 직렬화, Clamp로 회전 최대각을 걸어주기 위해 min,max Pitch, 마우스 감도 mouseSensitivity,
마우스로 회전을 조절하기 때문에 Vector2로 변수를 지정

GetInputDirection : Horizontal, Vertical을 통해 x,z의 -1~1의 값을 가져오기 위ㅎ한 함수
(나중에 애니메이션에서 x,z값에 따라 움직임을 설정하기 위해 따로 구현)

GetMoveDirection : GetInputDirection을 가져와서 해당 입력키에 대한 방향을 위해 구현

SetMove : 방향을 가져와서 x,z * speed를 적용해서 rigid.velocity - 가하는 힘이 바로 적용 될 수 있도록 구현

Vector2에서의 시점과 Vector3에서의 시점을 그린 그림인데 그림실력이 죄송하다...

SetAimRotate : Vector2를 가져오고 마우스 X,Y의 값 * 감도변수 를 통해 x,y에 저장하는데 이 때 y값은 반대로 적용해야 우리가 보는 TPS환경에서 정상작동

이전에 선언했던 Vector2 currentRotation(현재 회전)에 x축에서 회전값은 제한이 없기때문에 그냥 더하면 되고, y축의경우 한바퀴 돌 수 있기 때문에 clamp를 통해 제한하였다.

이때 현재 회전 transform.rotation, 시점의 회전 aim.localEulerAngles의 경우 현재시점의 게임 오브젝트의 회전을 기반으로 돌아갸아 하기때문에 자신의 오브젝트의 global회전각을 잘 보고 설정해야한다

그리고 만약 플레이어가 일반 움직임을 하다 에임을 해야할경우 해당 에임 카메라 방향으로 쳐다봐야 하기때문에 transform.forward를 통해 에임 카메라의 방향을 앞으로 설정 하였고 방향(normalized)을 반환하여 SetAimRotate의 Vector3를 반환하였다.

AvatarRotation : 회전에 대한 정보가 없을경우 즉, Vector3.zero일경우 반환하고, Quaternion.LookRotation을 통해 회전방향을 설정하였다. 회전은 Transform(avartar).rotation을 기준으로, 방향을 저장한 Quaternion으로, 플레이어의 회전 속도(PlayerStatus 클래스)변수를 참조해서 저장하였다.

PlayerController :

  • PlayerMovement
  • PlayerStatus

에서 저장한 정보를 사용할 곳으로

isControllActivate를 통해 플레이어가 움직이면 안될경우에 사용할 변수로 선언
cinemachine 카메라로 선언

이벤트 함수를 구독,구독취소 할 함수를 En,Disable에 넣고 HandlePlayerController를 통해 지속적으로 플레이어에 사용 할 변수를 Update에 넣었다.

이전에 플레이어가 움직이면 안 될 bool 변수를 이곳에 넣었고, 두개의 함수를 HandlePlayerController에 넣어 해당 함수에서 실행하도록 하였다.

플레이어 움직임과 회전을 담당
HandleMovement :

SetAimRotate의 정보를 camRotateDir에 저장 PlayerStatus에서 IsAiming이 true일경우 moveSpeed와 false일경우 moveSpeed를 달리해서 PlayerStatus에서 WalkSpeed, RunSpeed를 가져온다.

정보를 저장한 moveSpeed를 SetMove를 통해 플레이어의 속도를 지정하고,
PlayerStatus에서 IsMoving을 moveDir가 Vector3.zero 아닐경우 true로 설정하였다.

PlayerStatus의 IsAiming이 true일경우 camRotateDir(에임상태), false일경우 moveDir을 avatarDir에 저장하고

이를 PlayerMovement.SetAvatarRotation에 avatarDir을 넣는데 이 때, 에임 상태일경우는 따로 지정해서 회전을 설정하고, 아닐경우 일반적인 플레이어의 움직임으로 회전을 사용한다.

마지막으로 에임상태에서 아까 구현했던 플레이어의 방향 함수를 가지고와서 input에 저장하고 Animator의 변수로 사용해서 blendTree animation을 구현하였다.

HandleAming : PlayerStatus.IsAiming의 true,false를 Input을 통해 결정

SubscribeEvents,UnSubScribeEvents :
구독, 구독취소 함수

SetCam : aimCamera의 활성화 비활성화 여부
나머지 함수는 bool value를 가져와서 이벤트에 넣을 함수이다.

일반시점 움직임)

에임시점)

0개의 댓글