핑퐁 정보를 사용해 현재 위치가 어디인지 파악하고 A와 B 사이에 적용한다.
transform.position = Vector3.Lerp(startPosition, endPosition, movementFactor);
하이어라키 create 3d object에서 지형을 직접 만들 수 있다.
처음 생성된 상태를 보면, 그냥 작은 종이 한 장이 만들어진것 처럼 보이는데, 옆에 큐브하나 생성해서 크기를 비교해보면 상당히 크다는것을 알 수 있다.
브러쉬로 지형을 만들 수 있는데, 클릭하면 솟아오르고, 쉬프트 클릭하면 꺼진다.
그러나 y좌표 기준으로 밑으로 더이상 꺼지진 않는데, 협곡이나 구덩이를 만들고 싶다면, 사용할 수 있는 트릭이 있음.
최대깊이를 100으로 하고싶다면, terrain의 Transform y값을 -100으로 지정한다.
Paint Terrain 컴포넌트의 값을 Set Height로 설정하고, Height에 100을 입력, Flatten Tile클릭.
이렇게 하면 Terrain은 y = -100좌표에서 100만큼 상승한 지점에 위치해 있다.
다시말해 밑으로 꺼지게 할수 있음.
꺼지는 단축키는 컨트롤, a는 오파시티 조절, s는 크기조절, d는 브러쉬 회전으로 바뀐다.
텍스쳐가 존재한다면, Layers - add Layer 에서 지형에 텍스쳐를 추가할 수 있다.
질감이 예상한것과 다르다면, Layer Properties - Tiling Settings를 고쳐보자.
예제에서는 size -> x : 30, y : 30으로 변경해주니 자연스럽게 변함.
추가한 텍스쳐들은 Layer Pallete 에 추가되는데, 팔레트를 저장하고 다른 Terrain에서 불러와 사용 가능.
기본적으로 각 Terrain은 독립적으로 팔레트를 사용하도록 되어있기에 이런식으로 사용해야함.
Window - Sequencing에서 추가.
플러스 버튼 누르고 Animation Track 추가.
생성된 선택창에 타임라인을 주고싶은 옵젝 넣기.
옵젝의 Transform 인스펙터 포지션 우클릭, Add Key 클릭, 시간(혹은 프레임) 조절후 포지션값 재설정 해준뒤 플레이 버튼 눌러보면 간단한 타임라인 생성완료.
하지만 특정시점에서 오브젝트의 회전값을 변경할 땐 문제가 생긴다.
원하는 시점에서 회전을 하는게 아닌 첫 프레임부터 회전값이 바뀌어버리기 때문.
시작지점의 Rotation값을 기억해뒀다

회전을 시작할 타이밍의 키프레임에 붙여넣어주면 된다.

새 프로젝트를 생성하면 기본으로 제공되는 인풋 시스템외에 새롭게 인풋 시스템을 만들 수 있다.
게임 내에 미니게임에 대한 조작이라던지, 인벤토리 등 다른 조작방법이 필요할 때 사용해도 되고, 아예 나만의 인풋 시스템을 구축해도 좋다.
우클릭 - Create - Input Actions
더블클릭해서 열어보면, 액션맵, 액션 등이 있는데, 필요에 따라 이름을 바꿔주고 필요한 행위를 추가해주면 됨.
Actions필드에 디폴트로 적용돼 있는 인풋 시스템을 내가 생성한 인풋 시스템으로 교체,
Behavior필드에 있는 Send Messages는 해당 오브젝트에 있는 스크립트로 지시를 보낸다는 것인데, 특히 OnMove()는 우리가 만든 인풋 시스템의 이동부분과 연결된 부분임. -> 찰떡같이 알아듣자. 설명을 너무 못했는데..!
조작하는 오브젝트가 카메라 내의 특정 부분에서만 움직이게 하고싶을 때 사용하면 좋은 메서드.
움직임 뿐만 아니라 특정 범위로 제한하는 데 사용된다.
float clampedValue = Mathf.Clamp(value, min, max);
value: 제한하고 싶은 값.min: 허용되는 최소값.max: 허용되는 최대값.예제에선 움직임을 제한하는데,
...
[SerializeField] float xClampRange = 5f;
[SerializeField] float yClampRange = 5f;
...
private void ProcessTranslation()
{
float xOffset = controlSpeed * Time.deltaTime * movement.x;
float rawXpos = transform.localPosition.x + xOffset;
float clampedXPos = Mathf.Clamp(rawXpos, -xClampRange, xClampRange);
float yOffset = controlSpeed * Time.deltaTime * movement.y;
float rawYpos = transform.localPosition.y + yOffset;
float clampedYPos = Mathf.Clamp(rawYpos, -yClampRange, yClampRange);
transform.localPosition = new Vector3(clampedXPos, clampedYPos, 0f);
}
이런식으로 오브젝트의 x, y 좌표값을 제한할 수 있다.
플레이어 우주선이 좌우로 이동할 때 기체가 이동 방향에 따라 회전했으면 좋겠다.
private void ProcessRotation()
{
Quaternion targetRotation = Quaternion.Euler(0f, 0f, -controlRollFactor * movement.x);
transform.localRotation = targetRotation;
}
여기서 movement.x 값은 인풋 시스템에서 사전에 만들어 놓은 Value값이다.
상하 좌우 움직임을 Value of Vector2값으로 나타낸 것이다.
따라서 좌우로 회전 할 때 어느 방향으로 기울어져야 하는지 알려줌.
이 때 이전에 학습한 Lerp()을 사용하면 됨.
Lerp()은 Mathf.Lerp(), color.Lerp 등 사용 variation이 많다.
나는 회전에 관한 보정이 필요하므로 Quaternion.Lerp()을 사용할 것이다.
Quaternion.Lerp(startValue, endValue, offset)
private void ProcessRotation()
{
Quaternion targetRotation = Quaternion.Euler(0f, 0f, -controlRollFactor * movement.x);
transform.localRotation = Quaternion.Lerp(transform.localRotation, targetRotation, rotationSpeed * Time.deltaTime);
}
이렇게 수정해줍시다.
--> 회전이 훨씬 세련되고 스무스 해졌다.
추가로 상하 움직임에 대해서도 적용해보자.
...
[SerializeField] float controlRollFactor = 20f;
[SerializeField] float controlPitchFactor = 10f;
[SerializeField] float rotationSpeed = 10f;
...
private void ProcessRotation()
{
float pitch = -controlPitchFactor * movement.y;
float roll = -controlRollFactor * movement.x;
Quaternion targetRotation = Quaternion.Euler(pitch, 0f, roll);
transform.localRotation = Quaternion.Lerp(transform.localRotation, targetRotation, rotationSpeed * Time.deltaTime);
}
이제, 상하 좌우로 이동할 때 기체가 해당 방향의 반대방향으로 기울어져 훨씬 스무스한 움직임이 가능해졌다. Looking Good