티스토리 뷰
위의 이미지에서 키보드 a 와 d 자판은 Horizontal 이라는 이름의 버튼으로 할당 되어있다.
여기서 Input.GetAxis("Horizontal")를 사용하면 -1 에서 1 까지의 float 값을 반환 받을 수 있다.
이것에 관한 설정은 이하의 설정을 따르는데,
키가 입력되면 Sensitivity에 설정한 만큼 값이 서서히 -1이나 1에 도달한다.
그러다 입력이 중단되면 Gravity에 설정한 만큼 값이 서서히 0으로 되돌아간다.
그러다 Dead에 설정한 값에 도달하면 입력이 없는 것으로 한다.
사람들은 Input.GetAxis를 Horizontal이나 Vertical 과 같이 캐릭터의 조작에 사용한다.
transform.position += new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
위와 같은 코드 한 줄로 방향키 입력에 따라 x축과 z축을 이동할 수 있다.
이러한 방식으로 캐릭터가 이동해야할 방향을 구할 수 있는 것이다.
float rotationSpeed = 1;
private void Update()
{
Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
transform.position += direction;
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
이렇게 구한 이동 방향을 사용하여 캐릭터가 자연스럽게 회전하게 만들 수 있다.
float rotationSpeed = 1;
private void Update()
{
Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
if (direction != Vector3.zero)
{
transform.position += direction * Time.deltaTime;
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
}
하지만 캐릭터가 항상 이동하는 것은 아니므로
direction 이 0,0,0 인 경우 예외 처리를 해주어야 한다.
그런데 아마 이동을 해보면 대각선 이동을 할 때 속도가 빠르다는 것을 느낄 수 있다.
float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
private void Update()
{
Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// 방향 벡터를 정규화하여 대각선 이동 시 속도가 증가하지 않도록 합니다.
if (direction != Vector3.zero)
{
direction.Normalize();
transform.position += direction * moveSpeed * Time.deltaTime;
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
}
normalize를 하여 방향 벡터값을 정규화하는 것으로
모든 방향에 대한 이동 속도를 같게 만들 수 있다.
그러나 정규화를 해버린 것 때문에
조작을 시작한 순간부터 빠른 속도로 이동하는 것을 볼 수 있다.
원래대로였다면 자연스럽게 속도가 올랐어야 한다.
float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
private void Update()
{
// 입력 값에 따라 방향 벡터를 생성합니다.
Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
if (direction != Vector3.zero)
{
// 방향 벡터를 정규화합니다.
direction.Normalize();
// 정규화된 방향 벡터에 입력 값을 곱하여 이동 방향을 조정합니다.
direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// 위치 업데이트
transform.position += direction * moveSpeed * Time.deltaTime;
// 목표 회전 계산
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
}
이것은 정규화하여 구한 방향 벡터에
다시 Input.GetAxis 를 곱하여 점진적으로 높아지게 하여 해결할 수 있다.
중요한 것은 여기서부터이다.
Direction 값을 매 프레임마다 Update 문에서 조정하는데,
이것은 대각선 이동 중에 Horizontal 버튼과 Vertical 버튼을 동시에 떼지 않는 이상
한 프레임 차이로 인해 그 방향이 수직과 수평으로 고정되게 된다.
float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
Vector3 dir = Vector3.zero; // 이동 방향을 저장할 변수
private void Update()
{
// 키 입력이 있는 경우에만 방향을 업데이트합니다.
if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 norDir = new Vector3(x, 0, z).normalized;
dir = new Vector3(norDir.x * Mathf.Abs(x), 0, norDir.z * Mathf.Abs(z));
}
// 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
if (dir != Vector3.zero)
{
transform.position += dir * moveSpeed * Time.deltaTime;
Quaternion targetRotation = Quaternion.LookRotation(dir, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
}
이것은 Direction 을 캐싱하고 키 입력이 하나도 없는 경우
Direction 을 새로 정의하지 않게 하는 것으로 해결할 수 있다.
float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
float dead = 0.1f; // 감속 속도를 조절할 float 변수
Vector3 dir = Vector3.zero; // 이동 방향을 저장할 변수
private void Update()
{
// 키 입력이 있는 경우에만 방향을 업데이트합니다.
if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 norDir = new Vector3(x, 0, z).normalized;
dir = new Vector3(norDir.x * Mathf.Abs(x), 0, norDir.z * Mathf.Abs(z));
}
else
{
// 키 입력이 없을 경우 direction 값을 서서히 0으로 줄어듭니다.
dir = Vector3.Lerp(dir, Vector3.zero, dead * Time.deltaTime);
}
// 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
if (dir != Vector3.zero)
{
transform.position += dir * moveSpeed * Time.deltaTime;
Quaternion targetRotation = Quaternion.LookRotation(dir, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
}
}
마지막으로 Mathf.lerp를 사용하여 아무런 입력이 없을 때
이동하는 방향은 유지한 채, 속도가 서서히 0으로 떨어지게 만들 수 있다.
'유니티 > C# Code' 카테고리의 다른 글
Mesh Bake를 배웠습니다. (0) | 2024.08.31 |
---|---|
RaycastAll과 Array.Sort (0) | 2024.08.31 |
GPT >> Application의 path 종류에 대해 설명해줘 (0) | 2024.06.19 |
(학원과제) Array vs List vs ArrayList (0) | 2024.05.20 |
포켓몬 상성 계산 구현 x 이차원 배열 (20240519 c#으로 업데이트) (0) | 2024.05.14 |