2024. 12. 30. 15:16ㆍUnity/Unity 학습정리
캐릭터가 대쉬를 할 때 속도가 올라가고 대쉬를 멈추면 속도가 내려간다. 그럴 때 속도가 갑자기 올라가거나 떨어지면 게임 체감이 좋지 않을것이다. 이럴 때 사용하기 좋은 방법이 선형보간 방법인데 해당 방법을 이용하면 속도가 목표까지 서서히 올라가거나 떨어지게 할 수 있다.
목차
- 개념
- Move()메서드에서의 활용
- 배운점
개념
개념을 살펴보기전에 메서드의 생김새를 볼 필요가 있다.
Mathf.Lerp(float a, float b, float t)
Vector2.Lerp(Vector2 a, Vector2 b, float t)
Vector3.Lerp(Vector3 a, Vector3 b, float t)
Quaternion.Lerp(Quaternion a, Quaternion b, float t)
공통적으로 마지막 매개변수 float t 를 가지고 있다. 선형이기 때문에 일차함수를 떠올리면 편하다.
첫 번째 매개변수 a는 일차 함수의 시작 값
두 번째 매개변수 b는 일차 함수의 끝 값
마지막 매개변수 t는 a,b 값 사이의 위치(비율 : 0~1)를 나타낸다.
따라서, Lerp()메서드는 어느 두 값 사이의 위치를 가져오는것이다. 그럼 t의 값을 작은 단위로 올리거나 내리면 두 값 사이의 위치를 연속하게끔 가져올 수 있게 만들 수 있다.
Move()메서드에서의 활용
Move()메서드는 현재 Update()에서 호출되고 있으므로 매 프레임마다 호출 되고 있다.
private void Move()
{
//목표속도
float targetSpeed = _input.sprint ? sprintSpeed : movementSpeed;
if (_input.move == Vector2.zero) targetSpeed = 0.0f;
//현재속도
float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.y).magnitude;
float speedOffset = 0.1f;
float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
if(currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
{
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * speedChangeRate);
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed;
}
Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
if(_input.move != Vector2.zero)
{
inputDirection = transform.right * _input.move.x + transform.forward * _input.move.y;
}
//move Player
_controller.Move(inputDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
}
Lerp가 사용된 부분 부터 보자면
if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
{
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed;
}
currentHorizontalSpeed(현재속도), targetSpeed * InputManitude(타겟속도)를 SpeedChangeRate(속도변환비율)만큼 선형 보간하는 것이다. 한 마디로 현재속도에서 타겟속도까지 정해놓은 속도 변화량만큼 자연스럽게 변화시키는 것이다.
변화를 시키다가 타겟속도와 현재속도와 차이가 없다면 if문을 실행하지 않고 else문을 실행시킨다.
targetSpeed는 Sprint의 여부에 따라서 바뀐다. Sprint를 하거나 하지 않을때 현재 속도(currntHorizontalSpeed)와 비교해서 타겟속도(TargeSpeed)와 다르다면 타겟속도까지 선형보간을 하는것이다.
배운점
글을 찾다보니 선형보간을 위 방식말고 다른 방식으로도 활용한 방법이 많다. float t값을 조절하면 개발자가 원하는 이동을 표현할 수 있기 때문이다. 또한 시간에 따라 초기 위치에서 목적지까지 일정한 시간에 도달하기 위해서도 Lerp()메서드를 사용할 수 있다. 3D의 이동을 처음 구현해보는데 실제로 에이펙스 레전드라는 게임에서 캐릭터가 달리거나 속도가 줄어들 때 점차 줄어드는 것을 어떻게 표현하지라는 고민을 많이 했는데 해당 기술을 이용해 구현할 수 있게 되었다.
마지막으로 참고한 블로그 글을 올리며 마무리하겠다.
https://seongju0007.tistory.com/210
'Unity > Unity 학습정리' 카테고리의 다른 글
Unity - 몬스터 모드 변경 (0) | 2024.07.11 |
---|---|
Unity - Interface로 원하는 동작 해보기 (0) | 2024.07.10 |
플레이어를 쫓아다니는 몬스터 AI 구현 (0) | 2024.07.04 |
FSM StateMachine 상속 (0) | 2024.07.01 |
Unity - Behaviour Tree (1) (0) | 2024.06.25 |