2022. 2. 5. 17:33ㆍProjects/Amnyang
학교에서 일주일간 진행했던 게임 교육 특강을 듣고, 설 연휴도 겹쳐서 작업 스케쥴이 다소 밀렸다. 설 연휴가 끝난 후에 회의를 진행했고, 프로젝트 종료일인 2월 말까지 얼마 남지 않은 탓에 세부적인 디테일은 포기하기로 했다.
캐릭터가 숨는 모션, 적이 찾는 시늉을 하는 모션, 문 열리거나 상호작용하는 모션 등이 있으면 게임 완성도는 올라가지만 시간이 부족하다. 디자이너 님도 한 분밖에 없다보니 UI와 배경작업도 하셔야 하는데 그거까지 할 시간이 없으실 것 같다.
그래서, 우선 게임 플레이에 필수적인 요소들만 먼저 빠르게 구현하기로 했다. 저번 글에서 주인공 캐릭터의 Idle, Walk 애니메이션을 작업했는데, 다음 애니메이션은 달리기(Run)다.
1. 달리기(Run) 애니메이션 제작하기
걷기(Walk)를 한 번 만들어봤던 탓인지, 익숙해져서 달리기(Run) 모션은 그리 오래 걸리지 않았다. 마찬가지로 달리기 모션을 프레임별로 나타낸 그림을 참고하여 만들어봤다. 2D Bone Animation의 한계로 왼손 모양은 어쩔수가 없었다.
달리기 모션이다보니, 조금 빠르게 움직여야 하므로 5 프레임 단위로 구성했다. 달리기를 할 때 상체는 자연스럽게 숙여지므로 숙였고, 다리가 교차하며 바닥에 닿일 때마다 상체 뼈를 움직여 반동을 줬다. 오른손은 휴대폰을 쥐고 있기 때문에, 뛰면서 오는 몸의 반동으로 인한 약간의 움직임만 줬다. 만드는데 30분도 안 걸렸던 것 같다.
애니메이터 구조 변경 (Blend Tree 사용)
Idle, Walk, Run 애니메이션이 생겼다보니, 기존 방법대로는 복잡하고 다루기 힘들 것 같았다. 그래서 블렌드 트리(Blend Tree)를 하나 만들어서 "Move"라고 이름을 지어줬다.
그리고, Float 타입의 매개변수를 생성하고, "Move"라고 이름을 지었다. 이 Move 매개변수 값이 0일 땐 "Idle", 0.5일 땐 "Walk", 1일 땐 "Run"으로 애니메이션 전환이 일어나도록 구성했다.
Automate Thresholds 옵션을 체크 해제하고, 각 Threshold 값에 계획했던 값들을 넣었다. 이제 스크립트를 수정하는 일만 남았다.
2. 스크립트(Script) 수정하기
- 왼쪽 쉬프트(Left Shift)와 방향키 입력이 있다면, 달리기(Run)
- 왼쪽 쉬프트(Left Shift) 입력은 없지만 방향키 입력이 있다면 걷기(Walk)
- 두 입력 모두 없다면 가만히 있기(Idle)
현재 달리는 상태인지를 체크하기 위해 boolean 변수를 하나 추가했다.
private bool isRunning;
Update() 함수에서 왼쪽 쉬프트에 대한 입력을 받았다.
void Update()
{
walkDirection = Input.GetAxisRaw("Horizontal");
isRunning = Input.GetButton("Run"); // 추가
}
물론, Input Manager에서 Run 버튼에 대한 필드를 추가해줬다. 그 부분은 밑에 "더보기" 클릭
Unity Editor의 왼쪽 상단 Edit → Project Settings → Input Manager → Run 필드 추가
기존에 있었던 Walk() 함수를 삭제하고, Move() 함수로 통합했다. 그리고, 약간의 리팩토링 과정을 거쳤다.
void FixedUpdate()
{
bool hasControl = !Mathf.Approximately(walkDirection, 0f);
TurnOtherSide(hasControl);
Move(hasControl);
}
private void Move(bool hasControl) // 0f : Idle, 0.5f : Walk, 1f : Run
{
if (hasControl && isRunning)
{
animator.SetFloat("Move", 1f);
_rigidBody.velocity = new Vector2(walkDirection * walkSpeed * 2f,
_rigidBody.velocity.y);
return;
}
float walkValue = (hasControl && !isRunning) ? 0.5f : 0f;
animator.SetFloat("Move", walkValue);
_rigidBody.velocity = new Vector2(walkDirection * walkSpeed, _rigidBody.velocity.y);
}
이렇게 함으로써, 달리기 애니메이션 제작 및 적용이 완료되었다. 빨리 점프랑 상호작용 하러 가야겠다...
✏️전체 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SujiMoveController : MonoBehaviour
{
public float walkSpeed;
public Transform sujiTransform;
private Animator animator;
private Rigidbody2D _rigidBody;
private float walkDirection;
private float initScaleX;
private bool isRunning;
void Start()
{
_rigidBody = GetComponent<Rigidbody2D>();
animator = GetComponentInChildren<Animator>();
initScaleX = sujiTransform.localScale.x;
}
void Update()
{
walkDirection = Input.GetAxisRaw("Horizontal");
isRunning = Input.GetButton("Run");
}
void FixedUpdate()
{
bool hasControl = !Mathf.Approximately(walkDirection, 0f);
TurnOtherSide(hasControl);
Move(hasControl);
}
private void Move(bool hasControl) // 0f : Idle, 0.5f : Walk, 1f : Run
{
if (hasControl && isRunning)
{
animator.SetFloat("Move", 1f);
_rigidBody.velocity = new Vector2(walkDirection * walkSpeed * 2f,
_rigidBody.velocity.y);
return;
}
float walkValue = (hasControl && !isRunning) ? 0.5f : 0f;
animator.SetFloat("Move", walkValue);
_rigidBody.velocity = new Vector2(walkDirection * walkSpeed, _rigidBody.velocity.y);
}
private void TurnOtherSide(bool hasControl)
{
if (!hasControl)
return;
var scaleX = sujiTransform.localScale.x;
if (Mathf.Approximately(walkDirection * scaleX, initScaleX))
return;
var scaleY = sujiTransform.localScale.y;
var scaleZ = sujiTransform.localScale.z;
sujiTransform.localScale = new Vector3(-scaleX, scaleY, scaleZ);
}
}
'Projects > Amnyang' 카테고리의 다른 글
[압량(Amnyang)] #8. 2D 주인공 이동 중 점프(Move Jump), 착지 후 경직 딜레이 구현하기 (0) | 2022.02.07 |
---|---|
[압량(Amnyang)] #7. 2D 주인공 제자리 점프(Sargent Jump), 착지(Landing) 애니메이션 추가하기 (0) | 2022.02.06 |
[압량(Amnyang)] #5. 2D에서 Y축 회전을 통한 문 열리고 닫는 효과 구현하기 (0) | 2022.01.22 |
[압량(Amnyang)] #4. 키 입력을 받아 2D 캐릭터 좌우 이동 구현하기 (0) | 2022.01.22 |
[압량(Amnyang)] #3. 2D 주인공 캐릭터 Idle, Walk, EyeBlink 애니메이션 클립 만들기 (2) | 2022.01.21 |