캐릭터 애니메이선
움직일 때 실제로 걷는 것 처럼 제작

samples는 1초에 몇 프레임을 보여줄 것인가를 의미한다. 기본 세팅은 60 프레임
걷는 이미지를 순서대로 10 씩 간격을 두고 넣어주면 걷는 모션이 완성된다. (만약 너무 부자연스럽다면 첫프레임과 마지막 프레임 사이 간격이 너무 짧아서 일 수 있으니 마지막에 같은 프레임 두 개를 넣어 여유를 좀 주면 자연스러워진다.)
상하좌우 4 모션을 동일하게 만들어준다.

움직이면 모션이 있으면 멈춘 모션도 있어야 한다..
이때는 한 이미지만 넣어주면 되니 동일한 과정으로 stading도 추가해준다.

window에서 매니메이터를 열면 내가 만든 동작들이 보인다.
너무 많으니까 이를 집합시킨다.
블랜드 트리를 이용해 비슷한 것 끼리 묶는다.
(우클릭으로 생성)

제어를 위해 파라미터에 요소들을 추가한다.

2d 니까 설정 투디로 바꿔주고 파라미터에 추가한 x , y를 축으로 이용한다 . 여기에 4개 해당 모션을 추가하고 각 이동 방향에 맞는 값을 준다.

standing도 동일하게 적용한다.

스탠딩 트리를 디폴트로 준다.
make transition 상태변이를 준다 (우클릭)

특정 조건을 만족하면 서로의 상태로 상태 전이가 일어날 수 있다는 의미이다. 이 조건은 화살표를 클릭하면 제어할 수 있다.
컨디션 추가하고 여기에 walk 파라미터로 이동을 제어한다.

movingObject 스크립트 안에 애니메이터를 가져온다.

dirX와 dirY변수에 현재 이동키의 입력을 바탕으로 애니메이션을 수행한다. 상태전이가 일어날 수 있도록 bool함수도 설정해준다.

이를 실행했는데 모션의 전환이 어색하다 why?
has exit time 에 체크가 되어있어 한번 수행한 모션을 끝까지 봐야하기 때문이다. 이를 체크해제해주면 된다.
체크해제하고 duration도 0으로 해준다.

근데 움직임이 좀 부자연스럽다.
막 한발로만 걷는 것 같다.
방향키를 두개 동시에 상하, 좌우를 누르면 이상향 방향으로 움직이는 문제도 있다.
using System.Collections;
using UnityEngine;
public class MovingBehavi : MonoBehaviour
{
public float speed;
public Vector3 vector;
public float runSpeed;
private float applyRunSpeed; //눌렸을 때만 적용.
public int walkCount; //
private int currentWalkCount;
private bool canMove=true;
private bool applyRunFlag=false;
//speed * walkCOunt 픽셀만큼 한번에 이동하겠다.
//while 안에서 walkcount 만큼 currentWalkCount변수를 통해 반복하고 이가 종료되면 한번에 움직인다.
private Animator animator;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
animator = GetComponent<Animator>();
}
IEnumerator MoveCoroutine() {
while (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
{
if (Input.GetKey(KeyCode.LeftShift))
{
applyRunSpeed = runSpeed;
applyRunFlag = true;
}
else
{
applyRunSpeed = 0;
applyRunFlag = false;
}
vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);
if (vector.x != 0)
{
vector.y= 0;
}
if (vector.y != 0)
{
vector.x = 0;
}
animator.SetFloat("DirX", vector.x);
animator.SetFloat("DirY", vector.y);
//상태 전이
animator.SetBool("Walking", true);
while (currentWalkCount < walkCount)
{
if (vector.x != 0)
{
transform.Translate(vector.x * (speed + applyRunSpeed), 0, 0);
}
else if (vector.y != 0)
{
transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
}
if (applyRunFlag)
{
currentWalkCount++;
}
currentWalkCount++;
yield return new WaitForSeconds(0.01f);
}
currentWalkCount = 0;
}
animator.SetBool("Walking", false);
canMove = true;
}
// Update is called once per frame
void Update()//매 프레임 실행
{
if(canMove){
if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
{
canMove = false;
StartCoroutine(MoveCoroutine());
}
}
}
}
코드를 수정해서 수정한다..