캐릭터(Character) 이동(Move)
W,A,S,D를 사용해서 이동하는 캐릭터를 만들어 줄 것이다
일단 오브젝트를 하나 만들어서 Player라는 스크립트를 하나 생성해준다.
생성하고 열어보면 다음과 같이 Start()와 Update()가 존재하는데
사용하지 않으면 지워주는 것이 좋다
특히 Update()는 매프레임 마다 돌아가기 때문에 지워주는 것이 좋다
그리고 깔끔한 코드를 작성 해주기 위해서는
private나 public 등 접근 제한자를 항상 명시 해주는 것이 좋다
W,A,S,D를 입력 했음을 계속 확인 해주기 위해서
Update문이 필요하기 때문에 private 형식으로 하나 만들어 준다.
private void Update()
{
//매 프레임 마다 계속 호출된다.
}
이제 Update에서 키를 입력 받았을 때 어떻게 동작해야할지를 작성 해주어야 한다
Input.GetKey()는 키보드 입력 이벤트로 받은 값을 받아오는 메소드를 사용해서
W,A,S,D 값을 작성해준다.
Vector2 inputVector = new Vector2(0,0);
//왼쪽
if (Input.GetKey(KeyCode.A))
{
inputVector.x = -1f;
}
//오른쪽
if (Input.GetKey(KeyCode.D))
{
inputVector.x = 1f;
}
//위
if (Input.GetKey(KeyCode.W))
{
inputVector.y = 1f;
}
//아래
if (Input.GetKey(KeyCode.S))
{
inputVector.y= -1f;
}
Input.GetKey()는 해당 버튼을 누르고 있으면 계속 입력되기 때문에
위의 코드를 분석하면
Vector2 inputVector = new Vector2(0,0);
inputVector의 값은 매프레임 마다 0,0으로 초기화 되고
방향에 따라서 x축과 y축 값을 넣어 값을 변경해준다.
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
inputVector = inputVector.normalized;
transform.position += moveDir* moveSpeed * Time.deltaTime;
이제 오브젝트를 원하는 쪽으로 이동하기 위해서
moveDir Vector3를 하나 만들어서 동작하도록 해준다.
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
transform.position += moveDir* moveSpeed * Time.deltaTime;
오브젝트를 앞뒤 옆으로 이동하기 위해서 사용하는 벡터는 x 와 z의 값을 바꿔 주어야하기 때문에
inputVector.x의 값을 moveDir의 x 안에 넣어주고 inputVector.y의 값을 moveDir의 z 안에 넣어주면
우리가 생각하는 앞뒤로 이동하는 것을 확인 할 수 있다.
위의 코드만 작성했을 때 두개의키를 동시에 눌렀을 때
한개를 눌렀을 때 보다 빠르게 이동하는 것을 볼 수 있다.
이것은 값을 평균화 해주지 않아서 생기는 부분으로 다음 Vector값을 정규화 해주면
평균값으로 이동하는 것을 확인 할 수 있다.
inputVector = inputVector.normalized;
캐릭터 회전(Rotation)
캐릭터를 회전시키는 방법은 다양하지만
transform.forward를 사용해서 위에서 만든Vector3 moveDir의 방향으로
오브젝트를 회전 시키면 키보드를 누른 방향으로 캐릭터가 회전 하게 된다.
[전체 코드]
public class Player : MonoBehaviour
{
[SerializeField] private float moveSpeed = 7f;
private void Update()
{
Vector2 inputVector = new Vector2(0,0);
//왼쪽
if (Input.GetKey(KeyCode.A))
{
inputVector.x = -1f;
}
//오른쪽
if (Input.GetKey(KeyCode.D))
{
inputVector.x = 1f;
}
//위
if (Input.GetKey(KeyCode.W))
{
inputVector.y = 1f;
}
//아래
if (Input.GetKey(KeyCode.S))
{
inputVector.y= -1f;
}
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
inputVector = inputVector.normalized;
transform.position += moveDir* moveSpeed * Time.deltaTime;
//회전
transform.forward = moveDir;
Debug.Log(inputVector);
}
}
Vector3.Lerf()와 Vector3.Slerp() 사용하기
위의 두개를 사용해서 캐릭터가 방향을 틀었을때 부드럽게 회전할 수 있게 만들수있다.
두 방법은 두 지점 사이의 위치를 계산하는함수이다.
차이는 선형 보간법을 사용하는 Lerp와 구면선형 보간법으로는 Slerp를 사용한다.
Lerp 는 두 지점을 선으로 연결해서 두 지점 사이의 위치를 파악한다면
Slerp는 두지점의 사이의 위치를 곡선(호)으로 파악한다
참고
https://ko.wikipedia.org/wiki/%EC%84%A0%ED%98%95_%EB%B3%B4%EA%B0%84%EB%B2%95
간단하게 Lerp는 두개의 점 사이의 가장 짧은 호를 따라 직선을 그려준다 라고 생각하면될거같다..
예를들어 피자가 있으면 8각형의 피자가 있다고 생각하면 선형 보간에 따라서 피자 모양을 나타낸다고 하면
빵끝이 직선으로 잘린형태라고 생각하면되고 보간을 많이 하면 할수록
우리가 생각하는 둥근 모양의 피자가 된다고 생각하면 될 듯
결론은 Lerp는 부드러운 회전이 불가능하다~
하지만 Slerp는 두 점 사이의 각을 일정하게 보간한다.
회전값 적용하기
Vector3.Lerp(Vector a, Vector b, float t) 사용
float roateSpeed = 10f;
transform.forward = Vector3.Lerp(transform.forward, moveDir, Time.deltaTime * roateSpeed);
Vector3.Slerp(Vector a, Vector b, float t) 사용
float roateSpeed = 10f;
transform.forward = Vector3.Slerp(transform.forward, moveDir,Time.deltaTime* roateSpeed);
'PROGRAMING📚 > Unity📑' 카테고리의 다른 글
[UNITY]Input System Refactor(리펙터링) - 구조 재조정 (0) | 2023.06.01 |
---|---|
[UNITY]시네머신(Cinemachine)사용해서 카메라가 캐릭터 따라 다니게 만들기 (0) | 2023.05.31 |
[UNITY]포스트프로세싱(Post Processing)으로 시각적 효과 주기 (0) | 2023.05.25 |
유니티(Unity3D) 작업 단축키 팁 TIP (0) | 2023.05.24 |
[유니티 Unity]다른 스크립트 함수,변수 가져오는 방법 (0) | 2023.05.11 |
댓글