Model
// Assets/Scripts/Model/CharacterStateModel.cs
using System;
public enum CharacterState
{
Idle,
Walking,
Attacking,
Skilling,
Dying
}
public class CharacterStateModel
{
public event Action<CharacterState> OnStateChanged;
private CharacterState currentState;
public void ChangeState(CharacterState newState)
{
if (currentState != newState)
{
currentState = newState;
OnStateChanged?.Invoke(currentState); // 상태 변경 시 이벤트 발생
}
}
}CharacterState 를 enum으로 저장한다.
OnStateChanged 액션으로 액션 변경을 알리도록 하고
CharacterState currentState로 현재 상태를 저장한다.
View
// Assets/Scripts/View/ICharacterStateView.cs
public interface ICharacterStateView
{
void PlayIdleAnimation();
void PlayWalkAnimation();
void PlayAttackAnimation();
void PlaySkillAnimation();
void PlayDieAnimation();
}CharacterStateView에서 재생해야 하는 Animation을 Interface로 만들어 놓는다.
Idle,Walk,Attack,Skill,Die에 대한 애니메이션이다.
// Assets/Scripts/View/CharacterStateView.cs
using UnityEngine;
public class CharacterStateView : MonoBehaviour, ICharacterStateView
{
[SerializeField] private Animator animator;
// 코드와 Animator 파라미터 이름을 일치시킵니다.
private const string IdleTrigger = "Idle";
private const string WalkTrigger = "Walk";
private const string AttackTrigger = "Attack";
private const string SkillTrigger = "Skill";
private const string DieTrigger = "Die";
void Awake()
{
if (animator == null)
{
animator = GetComponent<Animator>();
}
}
// Presenter의 지시에 따라 Animator의 트리거를 설정합니다.
public void PlayIdleAnimation() => animator.SetTrigger(IdleTrigger);
public void PlayWalkAnimation() => animator.SetTrigger(WalkTrigger);
public void PlayAttackAnimation() => animator.SetTrigger(AttackTrigger);
public void PlaySkillAnimation() => animator.SetTrigger(SkillTrigger);
public void PlayDieAnimation() => animator.SetTrigger(DieTrigger);
}실행시킬 코드이다. animator.SetTrigger를 이용해서 Trigger를 활성화시켜 애니메이션을 재생한다.
Presenter
// Assets/Scripts/Presenter/CharacterPresenter.cs
using UnityEngine;
public class CharacterPresenter : MonoBehaviour
{
[SerializeField] private CharacterStateView characterStateView;
private CharacterStateModel model;
private ICharacterStateView characterStateViewInterface;
void Start()
{
model = new CharacterStateModel();
characterStateViewInterface = characterStateView;
model.OnStateChanged += OnStateChanged; // Model 이벤트 구독
model.ChangeState(CharacterState.Idle); // 초기 상태 설정
}
private void OnStateChanged(CharacterState newState)
{
// Model의 상태에 따라 View에게 재생할 애니메이션 지시
switch (newState)
{
case CharacterState.Idle:
viewInterface.PlayIdleAnimation();
break;
case CharacterState.Walking:
viewInterface.PlayWalkAnimation();
break;
case CharacterState.Attacking:
viewInterface.PlayAttackAnimation();
break;
case CharacterState.Skilling:
viewInterface.PlaySkillAnimation();
break;
case CharacterState.Dying:
viewInterface.PlayDieAnimation();
break;
}
}
// 테스트용 사용자 입력 처리
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) model.ChangeState(CharacterState.Idle);
if (Input.GetKeyDown(KeyCode.Alpha2)) model.ChangeState(CharacterState.Walking);
if (Input.GetKeyDown(KeyCode.Alpha3)) model.ChangeState(CharacterState.Attacking);
if (Input.GetKeyDown(KeyCode.Alpha4)) model.ChangeState(CharacterState.Skilling);
if (Input.GetKeyDown(KeyCode.Alpha5)) model.ChangeState(CharacterState.Dying);
}
}OnStateChanged 때 Statte가 변경되었으면 해당 Animation을 재생하게 된다.
애니메이션을 재생할 애니메이터도 설정해야 한다.
1. Animator Controller 생성 : 프로젝트 창에서 마우스 우클릭 -> Create -> Animator Controller 선택 이름은 characterAnimController로 지정
2. 캐릭터에 할당: 씬의 캐릭터 모델을 선택하고, Animator 컴포넌트의 Controller 필드에 생성한 characterAnimController를 드래그해서 할당한다.
View의 SerializeField의 Animator에도 할당한다.
3. 애니메이션 클립 추가: Animator 창을 열어 프로젝트에 있는 Idle,Walk,Attack,Skill, Die 애니메이션 클립들을 드래그하여 상태(State)로 추가한다.
4. 기본 상태 설정: Idle 상태를 마우스 우클릭 -> Set as Layer Default State를 선택
5. 파라미터 추가: Animator 창의 Parameters 탭에서 + 버튼을 눌러, 코드와 동일한 이름의 Trigger 파라미터 5개를 추가함 (대소문자 일치 할 것)
Idle, Walk, Attack, Skill, Die
6. 트랜지션 설정: Any State에서 각 애니메이션 상태로 트랜지션을 만든다.
Any State에서 Idle로 드래그하여 트랜지션 생성
해당 트랜지션을 선택하여 인스펙터의 Conditions에 Idle 트리거를 추가하고 Has Exit Time 체크해제
다른 상태(State)도 동일하게 Any State에서 연결하고 해당 트리거 조건에 맞게 설정한다.
테스트는 숫자 1-5를 눌러서 할 수 있다.
구글 AI의 도움을 받아 작성하였습니다.
댓글 없음:
댓글 쓰기