모델링의 리깅의 Animation Type을 설정해줄 수 있다.
Lagacy은 말 그대로 예전에 쓰던 것이다. 가장 빠르기에 쓰기도 하지만 거의 안 쓴다.
Generic은 거미나 사족보행 동물 등 이것저것에 쓰인다. 다만 모델링에 맞는 애니메이션이 필요하다.
Humanoid은 말 그대로 인간형 모델링을 의미한다. 인간에게 필요한 모든 관절이 있어야 사용할 수 있다.
다음은 애니메이션 Transition에 대한 설명이다.
Has Exit Time 토글은 어느시점에서 나가게 하는 것을 킬 것인지 적용시키는 것이다.
Exit Time은 특정 위치에서 나가게 하는 것이다. 0.6이면 이 애니메이션이 60% 실행된 후 애니메이션을 변경 시켜주는 것이다.
Transition Duration은 애니메이션끼리 변경이 될때 어느정도의 시간을 줄 것인지 적어주는 곳이다.
AgentAnimator스크립트를 만들어주었다.
우선 int형 변수를 생성하여 아까 Animator에서 생성한 해쉬값을 가져온다. 이런 방식을 사용하면 조금 더 메모리에 좋다.
그리고 public으로 함수 두개를 만들어서 다른 스크립트에서도 변경할 수 있도록 해준다.
using UnityEngine;
public class AgentAnimator : MonoBehaviour
{
private readonly int _speedHash = Animator.StringToHash("speed");
private readonly int _isAirboneHash = Animator.StringToHash("is_airbone");
private Animator _animator;
public Animator Animator => _animator;
private void Awake()
{
_animator = GetComponent<Animator>();
}
public void SetSpeed(float value)
{
_animator.SetFloat(_speedHash, value);
}
public void SetAirbone(bool value)
{
_animator.SetBool(_isAirboneHash, value);
}
}
Awake에서 _stateDictionary에 StateType, IState를 가지고 있는 Dictionary을 넣어준다.
이후 플레이어 아래있는 States오브젝트를 찾아서 넣어주고, StateType에 있는 모든 상태를 _stateDictionary에 넣어준다.
그러던 중 stateScript에 있는 SetUp함수를 지금 transform을 넣어서 적용시켜준디.
using Core;
using System;
using System.Collections.Generic;
using UnityEngine;
public class AgentController : MonoBehaviour
{
private Dictionary<StateType, IState> _stateDictionary = null; //가지고 있는 상태들 저장
private IState _currentState; //현재 상태 저장
private void Awake()
{
_stateDictionary = new Dictionary<StateType, IState>();
Transform stateTrm = transform.Find("States");
foreach( StateType state in Enum.GetValues(typeof (StateType)) )
{
IState stateScript = stateTrm.GetComponent($"{state}State") as IState;
if(stateScript == null)
{
Debug.LogError($"There is no script : {state}");
return;
}
stateScript.SetUp(transform);
_stateDictionary.Add(state, stateScript);
}
}
private void Start()
{
ChangeState(StateType.Normal);
}
private void ChangeState(StateType type)
{
_currentState?.OnExitState(); //현재 상태 나가고
_currentState = _stateDictionary[type];
_currentState?.OnEnterState(); //다음상태 시작
}
private void Update()
{
_currentState.UpdateState();
}
}
AgentInput 스크립트를 만들어 인풋을 받아주고 Action형 변수를 만들어서 실행시킨다.
그러고 AgentMovement에서 인풋 받은 것을 대체해준다.
using System;
using UnityEngine;
public class AgentInput : MonoBehaviour
{
public event Action<Vector3> OnMovementKeyPress = null;
private void Update()
{
UPdateMoveInput();
}
private void UPdateMoveInput()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
OnMovementKeyPress?.Invoke(new Vector3(horizontal, 0, vertical));
}
}
이후 IState를 만들어서 특정 함수들을 만들어둔다.
using UnityEngine;
public interface IState
{
public void OnEnterState();
public void OnExitState();
public void UpdateState();
public void SetUp(Transform agentRoot);
}
이후 IState를 상속 받는 추상클래스 CommonState를 만들어준다.
using UnityEngine;
public abstract class CommonState : MonoBehaviour, IState
{
public abstract void OnEnterState();
public abstract void OnExitState();
public abstract void UpdateState();
protected AgentAnimator _animator;
protected AgentInput _agentInput;
protected AgentController _agentController;
public virtual void SetUp(Transform agentRoot)
{
_animator = agentRoot.Find("Visual").GetComponent<AgentAnimator>();
_agentInput = agentRoot.GetComponent<AgentInput>();
_agentController = agentRoot.GetComponent<AgentController>();
}
//피격처리시 사용할 것
public void OnHitHandle(Vector3 hitPoint, Vector3 Normal)
{
}
}
이후 CommonState를 상속 받는 NormalState를 만들어주고
특정 스테이트에서 해야할 것을 넣어준다.
using UnityEngine;
public class NormalState : CommonState
{
protected AgentMovement _agentMovement;
public override void OnEnterState()
{
_agentMovement?.StopImmediately();
_agentInput.OnMovementKeyPress += OnMovementHandle;
}
public override void OnExitState()
{
_agentMovement?.StopImmediately();
_agentInput.OnMovementKeyPress -= OnMovementHandle;
}
private void OnMovementHandle(Vector3 obj)
{
_agentMovement?.SetMovementVelocity(obj);
}
public override void SetUp(Transform agentRoot)
{
base.SetUp(agentRoot);
_agentMovement = agentRoot.GetComponent<AgentMovement>();
}
public override void UpdateState()
{
}
}
'GGM > 엔진' 카테고리의 다른 글
20230327 - 엔진 - Navigation (0) | 2023.03.29 |
---|---|
20230320 - 엔진 - Combo, Rolling (0) | 2023.03.21 |
20230315 - 엔진 - RayCast, 애니메이션 (0) | 2023.03.16 |
20230308 - 엔진 - 플레이어 움직이게, 쉐이더 (0) | 2023.03.08 |
20230306 - 엔진 - mesh, Materials (0) | 2023.03.06 |
댓글