Player
- 메시가 없는 상태로 플레이어 캐릭터의 위치와 충돌등을 계산하는 오브젝트이다.
- PlayerCtrl.cs 스크립트는 여기에 붙인다.
Player > PlayerModel
- Player의 자식으로 단독적으로 플레이어 캐릭터의 메시가 되어 애니메이션과, 캐릭터 모습의 회전을 담당한다.
Player > CameraArm
- Player의 자식으로 CameraArm은 Player 오브젝트의 중심에 위치한다.
- MainCamera는 CameraArm에 붙이며 거리와 각도를 의도한대로 적절히 조절하여 사용한다.
//PlayerCtrl.cs
...
//플레이어가 이동할 때 이동속도 [SerializeField] private float mSpeed;
//플레이어에게 붙어있는 카메라 암
[SerializeField] private Transform mCameraArm;
//플레이어의 모델 오브젝트이다. 위치가 아닌 애니메이션을 위한 오브젝트.
[SerializeField] private GameObject mPlayerObject;
//플레이어 이동 입력 결과값을 저장하기 위한 변수 private Vector3 mMoveInput; //매 프레임마다 플레이어의 입력에 따라 카메라암의 회전과 이동을 처리한다.
private void Update()
{
...
mMoveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
LookAround();
Move();
...
}
//마우스의 움직임 값을 실시간으로 계산하여 카메라암을 회전시킨다.
//카메라 암은 X(좌우), Y(상하) 방향만 조정하면 된다. Z좌표는 고려하지 않아도 충분함.
private void LookAround()
{
Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
Vector3 camAngle = mCameraArm.rotation.eulerAngles;
float x = camAngle.x - mouseDelta.y;
if (x < 180f)
{
x = Mathf.Clamp(x, -1f, 45f);
}
else
{
x = Mathf.Clamp(x, 320f, 361f);
}
mCameraArm.rotation = Quaternion.Euler(x, camAngle.y + mouseDelta.x, camAngle.z);
}
...
|
cs |
[SerializeField] private float mSpeed;
- Move() 함수가 호출될 때 이동시키는 크기를 결정하는 변수이다.
[SerializeField] private Transform mCameraArm;
- 인스펙터에서 CameraArm 오브젝트가 들어가는 변수이다.
[SerializeField] private GameObject mPlayerObject;
- 인스펙터에서 플레이어 캐릭터의 외형인 메시를 담당하는 PlayerModel 오브젝트가 들어가는 변수이다.
private Vector3 mMoveInput;
- 플레이어의 이동 관련 입력에 대한 결과값이 저장되는 변수이다.
private void Update()
- 매 프레임마다 이동 관련 입력을 mMoveInput에 저장한다.
- LookAround()함수를 호출하여 마우스 입력에따라 카메라암이 회전하도록 한다.
- Move()함수를 호출하여 이동 입력이 있을경우 처리하도록 한다.
private void LookAround()
- 마우스의 움직임을 계산하여 카메라암의 각도를 조절하여 시점을 이동시킨다.
- 카메라암의 각도를 범위로 제한하여 자연스러운 시점이동을 구현한다.
- mouseDelta는 마우스가 얼마나 움직였는지 값을 측정한다.
float x = camAngle.x - mouseDelta.y
- 현재 카메라 암의 각도에서 상하 마우스 이동값의 차이로 카메라암이 상하로 얼마나 회전해야 하는지 저장하는 변수이다. camAngle.x - mouseDelta.y처럼 x에서 y를 빼는 이유는 카메라암이 Player 오브젝트에 붙어있을 때 상하 방향이 x축이기 때문이다.
Mathf.Clamp
- 카메라의 각도를 제한하기 위해 사용한다. 정면이 0도(360도)이기때문에 이를 반으로 나눠 180보다 작은 경우와 큰 경우에 따라 각도를 제한한다.
mCameraArm.rotation = Quaternion.Euler
- 카메라 암의 회전값을 최종적으로 계산된 x, y축의 각도로 변경시킨다. z축은 변함이 없다.
//PlayerCtrl.cs
... //카메라가 바라보는 방향을 기준으로 이동하도록 한다.
private void Move()
{
bool isMove = mMoveInput.magnitude != 0;
if (isMove && !isJumping)
{
Vector3 lookFoward = new Vector3(mCameraArm.forward.x, 0f, mCameraArm.forward.z).normalized;
Vector3 lookRight = new Vector3(mCameraArm.right.x, 0f, mCameraArm.right.z).normalized;
Vector3 moveDir = lookFoward * mMoveInput.y + lookRight * mMoveInput.x;
Quaternion viewRot = Quaternion.LookRotation(moveDir.normalized);
mPlayerObject.transform.rotation = Quaternion.Lerp(mPlayerObject.transform.rotation, viewRot, Time.deltaTime * 20);
transform.position += moveDir * mSpeed * Time.deltaTime;
}
}
...
|
cs |
private void Move()
- PlayerCtrl.cs의 Update()에서 매 프레임마다 호출되는 함수이다.
- 플레이어의 이동관련 입력에 따라 플레이어 캐릭터의 위치를 적절하게 옮기는 함수이다.
bool isMove
Update()에서 계산된 mMoveInput의 크기를 측정하여 0이 아닌경우(입력이 있는경우) 다음 처리를 이어서 한다.
- 입력이 없을 때 불필요한 계산을 줄이기 위해 사용하였음.
Vector3 lookForward, lookRight
- 카메라암의 정면 방향과 측면 방향에 대한 방향을 저장하는 변수이다. 플레이어 캐릭터의 현 방향이 아닌 카메라가 바라보고 있는 방향을 기준으로 회전하기때문에 사용한다.
Vector3 moveDir
- 벡터 연산에 의해 카메라 암의 정면 방향 * y축 이동입력 + 카메라 암의 측면방향 * x축 이동입력을 더하여 방향을 결정한다.
Quternion viewRot
- 이동 방향과 별개로 플레이어의 모습을 담당하는 PlayerModel의 방향을 움직이는 방향으로 회전시키기 위해 바라보는 방향을 구한다.
mPlayerObject.transform.rotation = Quaternion.Lerp(mPlayerObject.transform.rotation, viewRot, Time.deltaTime * 20);
- PlayerModel 오브젝트의 방향을 움직이는 방향인 viewRot으로 한다. Lerp를 사용하면 부드러운 방향 전환이 가능하다.
- deltaTime에 곱한 20은 방향을 바라보는 회전속도를 나타낸다.
transform.position += moveDir * mSpeed * Time.deltaTime;
- 최종적으로 방향과 속도와 deltaTime을 곱해 플레이어 캐릭터를 이동시킨다.
'unity game modules' 카테고리의 다른 글
[유니티] 카메라 흔들림 효과 (0) | 2022.07.17 |
---|---|
[유니티] 안개 효과 (던전 입장 효과) (0) | 2022.07.16 |
[유니티] 공격(스킬) 범위 표시 (0) | 2022.07.16 |
[유니티] 오브젝트 풀 (Object Pool) (0) | 2022.07.16 |
[유니티] 아이템 사용하기 (0) | 2022.03.05 |