# Section 2 : 기본 움직임 소개

### 9. 간단한 샌드박스 생성

![](https://velog.velcdn.com/images/biomatrix117/post/9084ac8b-af2d-48cf-b800-734342ab5f76/image.png)

Create > Terrain 터레인 크기 조절 : Terrain > (산+톱니바퀴 아이콘) > Mesh Resolution > Terrain Width, Length 조절 터레인 그리기 : (산+브러시 아이콘)

* 민감도 조절 : Opacity
* 터레인 줄이기 : Shift 누르면서 클릭
* 텍스처로 그리기 : Paint Texture로 변경 > Edit Terrain Layers
* 다른 텍스처 추가 : Edit Terrain Layer > Create Layer > 레이어 선택하고 그리기

터레인 작업할 때 꺼둬야할 것 : Windows > Rendering > Lighting > Auto Generate 안 끄면 터레인 변경할 때마다 라이트맵 다시 만든다. 필요할 때만 Generate Lighting하면 된다.

### 10. 내브메시 에이전트를 활용한 움직임

카메라를 Scene 뷰에서 보이는 시점으로 옮기기 : GameObject > Align With View

AI Navagarion 설치 > Terrain에 Navmesh Surface > Bake > Player에 Navmesh Agent 컴포넌트 추가

![](https://velog.velcdn.com/images/biomatrix117/post/bfb29dee-729b-4fdd-8bca-fa4e49322b43/image.png)

(Troubleshooting) Navmesh 구웠는데 안 보임. 모든 걸 확인했는데 bake가 안됨. 우측 하단 AI Navigation > Surfaces > Show Navmesh 토글 켰더니 보이기 시작.

```cs
public class Mover : MonoBehaviour
{
    [SerializeField] Transform target;
    [SerializeField] NavMeshAgent navMeshAgent;

    void Update()
    {
        navMeshAgent.destination = target.position;
    }
}
```

이러면 Navmesh agent를 붙인 오브젝트가 Navmesh surface를 따라 간다.

### 11. 내브메시 조정

**Window > AI > Navigation**

* Radius : Agent가 이동 가능한 경로의 너비
* Height : Agent가 통과할 수 있는 경로의 최소 높이 (캐릭터의 키)
* Step Height : Agnet가 걸어서 넘을 수 있는 최대 장애물의 높이
* Max Slope : Agent가 올라갈 수 있는 최대 경사 각도

Generated Links

* Drop Height : Agent가 떨어질 수 있는 최대 높이
* Jump Distance : Agent가 점프할 수 있는 최대 거리

강의에선 오브젝트 우측 Static이 설정돼있지 않으면 Navmesh Bake할 때 인식하지 못한다고 했지만, 버전이 올라가서 그런가 알아서 잘 인식해줬음.

동적으로 움직이는 물체를 피해가도록 설정 : (강의에서 말하기론 Static을 풀고) Navmesh Obstacle 컴포넌트 추가. Carve를 설정하면 접근 금지 범위가 넓어진다.

**Navmesh Surface Component**

* Use Geometry : Navmesh 생성할 때 mesh, collider, both 기준을 뭘로 할지.
* Collect Objects : Navmesh에 포함될 오브젝트 선택

Advanced

* Override Voxel Size : Navmesh를 생성할 때 얼마나 세밀하게 생성할지
* Override Tile Size : 한 번에 처리하는 영역 조정.
* Minimum Region Area : Navmesh에 포함될 영역의 최소 크기

### 12. 레이캐스팅 소개

```cs
        if (Input.GetMouseButtonDown(0))
        {
            lastRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        }
        Debug.DrawRay(lastRay.origin, lastRay.direction * 100);
```

### 13. 클릭으로 이동 구현

```cs
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            MoveToCursor();
        }
    }

    private void MoveToCursor()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        bool hasHit = Physics.Raycast(ray, out hit);
        if (hasHit) navMeshAgent.destination = hit.point;
    }
```

파라미터 확인 : 파라미터 괄호에 커서 두고 `Ctrl+Shift+Space` VS Code 키보드 단축키 모음 보기 : Help > Keyboard Shorcuts References

### 14. 고정 팔로우 카메라 생성

```cs
    void Update()
    {
        transform.position = target.position;
    }
```

시네머신 없이 follow camera 구현하기 위해 follow camera라는 빈 게임 오브젝트 생성하고 main camera를 자식으로 두기

### 15. 애니메이션 블랜드 트리

원래 있던 Player 게임 오브젝트에서 Mesh Filter, Collider 지우고 애셋 프리팹 추가해준 후에 Navmesh Agent에서 Base Offset을 0으로 바꿔주고 Radius를 조정함.

Animator 컴포넌트 : Animator Controller를 통해 게임 오브젝트에 애니메이션 할당 Animator Controller : 애니메이션과 애니메이션 전환 모음 (state machine) Blend Tree : 여러 개의 애니메이션 자연스럽게 섞기

Character를 위한 Animator Controller 생성 > Animator 창 우클릭 > Create State > From New Blend Tree > 생성된 노드 더블 클릭 > Inspector에서 Motion의 `+` 버튼, Add Motion Field > (애셋에 있던 motion들 사용) > 우측 하단 Blend Tree에서 재생하고 슬라이더를 조절하여 테스트

### 16. 움직임에 애니메이션 적용

만들었던 Controller 적용하고, 애셋에 있던 Avatar 적용하고, Apply Root Motion 체크 해제 확인

해야 하는 것

* Navmesh Agent에서 속력을 구해온다
* 캐릭터에 대한 local value로 변환한다
* Animator의 blend value를 forward speed와 같게 설정한다

Animation Clip > Inspector > 하단 Average Velocity를 보면 애니메이션의 이동 속력이 있다. Blend Tree의 Inspector > Automate Threshholds > Compute Thresholds > Velocity Z : Average Velocity에 맞게 조정된다. Navmesh Agent 컴포넌트 > Speed를 최고 Threshhold로 변경한다.

InverseTransformDirection : 글로벌을 로컬로 변환 월드 좌표계 기준인 Navmesh Agent의 속도를 현재 게임 오브젝트 기준의 로컬 방향으로 변환한다.

```cs
    private void UpdateAnimator()
    {
        Vector3 velocity = navMeshAgent.velocity;
        Vector3 localVelocity = transform.InverseTransformDirection(velocity);
        float speed = localVelocity.z;
        GetComponent<Animator>().SetFloat("forwardSpeed", speed);
    }
```

Navmesh Agent의 Angular Speed와 Acceleration을 조절하여 움직임 자연스럽게 조정

### 17. 기본적인 움직임 변형

```cs
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            MoveToCursor();
        }
        UpdateAnimator();
    }
```

GetKey : 해당 키 누르는 동안 true 반복적 반환 GetKeyDown : 해당 키 누르면 단 한 번 true 반환 GetKeyUp : 해당 키 누름 해제되면 true 한 번 반환

```cs
    void LateUpdate()
    {
        transform.position = target.position;
    }
```

플레이어가 이동한 후에 카메라를 움직여야 하니까 카메라 이동 로직은 LateUpdate()

### 18. 프로젝트 폴더 구조

![](https://velog.velcdn.com/images/biomatrix117/post/00aa4741-5f7c-4c0f-9830-d390e36a92ce/image.png)

`t:material` 이런 식으로 검색하면 머테리얼만 검색 가능. 물론 검색창 오른쪽에서 태그 설정도 가능.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lazyartisan.gitbook.io/note/main-page/courses/rpg-unity-c/section-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
