캐릭터 준비
유니티 어셋스토어에서 적당한 캐릭터와 8방향 애니메이션이 있는 어셋을 구해서 준비한다.
캐릭터는 빈 오브젝트에 메쉬만 붙어 있는 오브젝트를 추가해서 아래와 같이 월드에 배치해 놓는다.
위 캐릭터의 Hierarchy 에서는 Player 라는 빈 오브젝트에 mesh 오브젝트를 추가했고, 이 mesh 에는 Animator 컴포넌트만 붙어 있는 상태이다.
캐릭터 이동 시키기
위 Player 객체에 CharacterController 컴포넌트를 추가하고, MoveController.cs 스크립트 컴포넌트도 추가한다.
추가한 후에 모습이다.
이 상태로 유저로부터의 이동키(WASD, 방향키)를 입력받아서 Player 객체를 이동시키도록 구현한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveController : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f; // 이동 속도
CharacterController myCC = null;
Animator myAnimator = null;
Vector3 moveDir = Vector3.zero; // 자주 사용하므로 미리 선언
void Awake()
{
myCC = GetComponentInChildren<CharacterController>();
myAnimator = GetComponentInChildren<Animator>();
}
// Update is called once per frame
void Update()
{
float xAxis = Input.GetAxis("Horizontal");
float zAxis = Input.GetAxis("Vertical");
// 전후 이동
moveDir = (xAxis * transform.right + zAxis * transform.forward) * Time.deltaTime * moveSpeed;
// 캐릭터 컨트롤러로 간단하게 이동시키자.
myCC.Move(moveDir);
}
}
이렇게 하면 다음과 같이 캐릭터의 위치를 이동시킬 수 있게 되었다.
Animator Controller 설정
아래에 나와 있는 준비된 애니메이션들 중에서 빨간색 박스 안에 있는 9개의 애니메이션을 이용해서 이동을 구현할 것이다. 이동이 없는 평상시 대기는 아래 애니메이션 중 RPG-Character@2Hand-Sword-Idle 를 사용할 것이다.
사용할 Animator Controller 를 생성하고 이름을 My Animator Controller로 하고 Animator 에 연결한다.
다음은 RPG-Character@2Hand-Sword-Idle 를 기본 애니메이션 노드로 설정한다.
이렇게 하면 기본 플레이되는 애니메이션이 나온다.
다음으로 My Animator Controller 를 더블클릭하여 편집하도록 한다.
우선, Parameters 에 move(Bool), moveX(Float), moveZ(Float) 를 추가한다.
Blend Tree 노드 한개를 추가한다.
이름은 Move Blend Tree 로 변경하고, 2Hand-Sword-Idle 과 Transition 을 아래 그림처럼 연결한다.
위 그림에서 처럼 2Hand-Sword-Idle 에서 Move Blend Tree 로 이동하는 조건은 move 파라미터가 true 가 되는 것이고, 반대로 Move Blend Tree 에서 2Hand-Sword-Idle로 이동하는 조건은 move 파라미터가 false 가 되는 것이다.
Move Blend Tree 를 더블클릭하여 아래 그림과 같이 이동 애니메이션을 추가한다.
Blend Type 은 2D Simple Directional 로 변경하고, Parameters 에는 moveX 와 moveZ 를 선택한다. 이는 moveX 값에 따라서 좌우(-1=Left, +1=Right) 애니메이션이 결정되고, moveZ 값에 따라 전후(+1=Forward, -1=Backward) 애니메이션이 결정된다.즉, Blend Tree 노드는 이 두 값을 이용해서 애니메이션을 서로 합치게 되는 것이다.
마지막으로 MoveController.cs 를 수정하여, 유저로부터 입력받은 값을 Animator Controller 에게 전달해 주는 부분을 구현한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveController : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
CharacterController myCC = null;
Animator myAnimator = null;
Vector3 moveDir = Vector3.zero; // 자주 사용하므로 미리 선언
void Awake()
{
myCC = GetComponentInChildren<CharacterController>();
myAnimator = GetComponentInChildren<Animator>();
}
// Update is called once per frame
void Update()
{
float xAxis = Input.GetAxis("Horizontal");
float zAxis = Input.GetAxis("Vertical");
// 좌우 이동 값
myAnimator.SetFloat("moveX", xAxis);
// 전후 이동 값
myAnimator.SetFloat("moveZ", zAxis);
// 입력이 있는지 판단해서 이동상태인지를 전달해 준다.
myAnimator.SetBool("move", (xAxis != 0f || zAxis != 0f));
// 전후 이동
moveDir = (xAxis * transform.right + zAxis * transform.forward) * Time.deltaTime * moveSpeed;
// 이동하자!!
myCC.Move(moveDir);
}
}
아래는 결과 이미지이다.
혹 위 결과와 다르게 동작을 한다면 Player-mesh 에 있는 Animator 컴포넌트에서 Apply Root Motion 을 체크해제하고, Animator Controller 에서 2Hand-Sword-idle 에서 Move Blend Tree 로의 Transition 에서 Has Exit Time 을 체크해제하도록 한다.
참조 리소스
캐릭터 : https://assetstore.unity.com/packages/3d/animations/rpg-character-mecanim-animation-pack-free-65284
나무 : https://assetstore.unity.com/packages/3d/vegetation/trees/low-poly-tree-pack-57866
'Unity' 카테고리의 다른 글
Unity 2022.3.20f1 에서 빌드 시 에러 (0) | 2024.03.12 |
---|---|
CommandInvokationFailure: Failed to update Android SDK package list. (0) | 2024.02.23 |
경고 메시지 : androidx.fragment:fragment (androidx.fragment:fragment) (0) | 2023.12.16 |
[UNITY] HP 바 구현 - #2 (0) | 2022.09.12 |
[UNITY] HP 바 구현 - #1 (0) | 2022.09.12 |