ㄴ CameraController.cs 사용하기
1) Main Camera를 Player 산하로 넣는다?
❌ Player가 회전할 때 Camera의 앵글도 함께 바뀌어 어지러움 유발 문제 발생..!
💡 Main Camera를 Player의 산하로 넣지 말고 개별 object로 사용
CameraController.cs로 Player를 계속 촬영하되, Camera의 회전값은 Player를 따라가는 것이 아니라 world좌표를 기준으로 Player와 일정 거리를 유지한 상태로 함께 움직이도록 설정함!
public class CameraController : MonoBehaviour
{
[SerializeField] Define.CameraMode _mode = Define.CameraMode.QuarterView;
[SerializeField] Vector3 _delta;
[SerializeField] GameObject _player;
void Update()
{
//카메라의 위치 설정
transform.position = _player.transform.position + _delta;
}
}
ㄴ 즉, 카메라의 위치 = player 위치 + 떨어져 있는 Vector3값
ㄴ enum으로 정리하는 Define 스크립트 별도 생성 후 사용
public class Define //컴포넌트로 사용 X
{
public enum CameraMode
{
QuarterView,
}
}
⚠️ player가 덜덜 떨리면서 이동하게 됨
-> 현재 playercontroller와 CameraController 모두 Update()에서 실행되고 있는데, 두 스크립트 중에 누가 먼저 연산될지는 랜덤이다. 만약 cameraController가 먼저 연산되면 우리 설계보다 _delta가 조금 더 멀리 가있을 것이고, PlayerController가 먼저 연산되면 우리가 원하는 거리가 유지될 것. 이처럼 1/2확률로 연산 순서가 정해지고 카메라 위치가 결정되기 때문에 player가 덜덜 떨면서 이동하는 것처럼 보여진다..
💡 무조건, PlayerController의 연산이 먼저 진행되도록 설정!
유니티의 Life Cycle을 살펴보면, LateUpdate()가 Update()보다 늦게 실행되는 것을 알 수 있다.
ㄴ 즉, PlayerController의 Update()가 실행 된 후, CameraController가 LateUpdate()로 실행되게 만들면 된다.
public class CameraController : MonoBehaviour
{
//필드 변수 초기화
[SerializeField] Define.CameraMode _mode = Define.CameraMode.QuarterView;
[SerializeField] Vector3 _delta = new Vector3(0.0f, 6.0f, -5.0f);
[SerializeField] GameObject _player = null;
void LateUpdate()
{
if(_mode == Define.CameraMode.QuarterView)
{
//카메라의 위치 설정
transform.position = _player.transform.position + _delta;
//player 주시
transform.LookAt(_player.transform);
}
}
//나중에 QuaterView의 값을 받아올지도 모르니까 만들어 둠
public void SetQuaterView(Vector3 delta)
{
_mode = Define.CameraMode.QuarterView;
_delta = delta;
}
}
InputManager.cs에 MouseAction 이벤트
생성
ㄴ Define.cs에 enum MouseEvent
만듦
PlayerController.cs에 클릭 시 기능 추가
ㄴ 목적지 변수 _destinationPos & 이동상태 확인용 플래그 _moveToDest 필드 추가
ㄴ MouseAction에 OnMouseClicked() 구독 신청
OnMouseClicked() 생성 ㄴ Click되면, 클릭 위치를 _destinationPos로 설정
ㄴ _moveToDest = true;로 이동 상태로 변경
player 실제 이동 구현 코드
⚠️ 현재 코드로 실행을 해보면 목적지에 도착했을 때 캐릭터가 좌우로 와리가리하다 넘어져버리는 문제 발생 ?!!!
💡 Math.Clamp(값, 최소값, 최대값)
을 사용하여 값(_speed * Time.deltaTime)이 최소값보다 작아지면 최소값으로 덮어쓰기되고, 최대값(dir.magnitude)보다 커지면 최대값으로 덮어쓰기되도록 한다.
Quaternion.Slerp(현재 위치, 바라볼 뱡향, 두 회전값의 블렌딩 비율)
을 사용하여 부드러운 회전 구현 카메라에서 player를 향해 발사한 Raycast가 벽과 충돌했다면, 충돌 지점(hit.point)과 플레이어 사이의 거리를 계산한다. 이 거리에 0.8f를 곱해 카메라를 플레이어에 더 가깝게 이동시킨다.
-> 이로써 카메라가 벽에 완전히 가려지는 것을 방지할 수 있다!
-> 만든 Camera를 Prefab화하면 다른 씬에서도 활용할 수 있다.