20241120 / Unity_6차 11주차 수요일
오늘 한 일
1. 몬스터 스테이트 머신
public class MonsterStateMachine : StateMachine
{
public Monster Monster { get; private set; }
public MonsterBaseState State_Idle { get; private set; }
public MonsterBaseState State_Spawning { get; private set; }
public MonsterBaseState State_Taunting { get; private set; }
public MonsterBaseState State_Chase { get; private set; }
public MonsterBaseState State_Attack { get; private set; }
public MonsterBaseState State_Hit { get; private set; }
public MonsterBaseState State_Dead { get; private set; }
public MonsterStateMachine(Monster monster)
{
this.Monster = monster;
State_Idle = new MonsterState_Idle(this);
State_Spawning = new MonsterState_Spawning(this);
State_Taunting = new MonsterState_Taunting(this);
State_Chase = new MonsterState_Chase(this);
State_Attack = new MonsterState_Attack(this);
State_Dead = new MonsterState_Dead(this);
}
}
// 스테이트(예시)
public class MonsterState_Chase : MonsterBaseState
{
public MonsterState_Chase(MonsterStateMachine stateMachine) : base(stateMachine)
{
transform = stateMachine.Monster.transform;
}
private Transform transform;
private Vector3 targetPosition;
private float targetDistance;
private float chaseTimeRemain;
public override void Enter()
{
stateMachine.Monster.SetNextSkill();
stateMachine.Monster.OnHit += Hit;
chaseTimeRemain = stateMachine.Monster.Stat.chasePeriod;
if (stateMachine.Monster.ValidAnimator)
{
stateMachine.Monster.AnimationController.SetRun(true);
}
}
public override void Update()
{
// TODO Player
//targetPosition = Managers.Game.Player.transform.position;
targetPosition = stateMachine.Monster.TestPlayer.transform.position;
targetDistance = Vector3.Distance(transform.position, targetPosition);
if (chaseTimeRemain >= 0) chaseTimeRemain -= Time.deltaTime;
// 추적 중단
if (chaseTimeRemain < 0 && targetDistance > stateMachine.Monster.Stat.attractDistance)
{
stateMachine.ChangeState(stateMachine.State_Idle);
}
// 이동
else if (targetDistance > stateMachine.Monster.NextSkillRange)
{
// Look, Y축 회전만 적용
Vector3 vectorLook = targetPosition - transform.position;
vectorLook.y = 0f;
if (vectorLook != Vector3.zero)
{
Quaternion rotation = Quaternion.LookRotation(vectorLook);
transform.rotation = Quaternion.Euler(0, rotation.eulerAngles.y, 0);
}
// Move
transform.Translate(stateMachine.Monster.Stat.moveSpeed * Vector3.forward * Time.deltaTime, Space.World);
}
// 공격 개시
else
{
stateMachine.ChangeState(stateMachine.State_Attack);
}
}
public override void Exit()
{
stateMachine.Monster.OnHit -= Hit;
if (stateMachine.Monster.ValidAnimator)
{
stateMachine.Monster.AnimationController.SetRun(false);
}
}
private void Hit(bool isStagger)
{
if (isStagger)
{
stateMachine.ChangeState(stateMachine.State_Hit);
}
else
{
chaseTimeRemain = stateMachine.Monster.Stat.chasePeriod;
}
}
}
2. 몬스터 스포너