728x90
반응형
이제 기존의 Enemy 3총사를 사용하여
새로운 적인 Skeleton을 만들어보겠습니다.
기존의 코드에서 볼 수 있듯이
새로운 적의 타입별로 Controller가 필요하므로 이를 수행하겠습니다.
1) SkeletonController
public class SkeletonController : EnemyController
{
// Skeleton States
public SkeletonStateIdle _idleState { get; private set; }
public SkeletonStateMove _moveState { get; private set; }
public SkeletonStateEngage _engageState { get; private set; }
public SkeletonStateAttack _attackState { get; private set; }
// Awake에서는 Skeleton이 가질 State들을 설정함
protected override void Awake()
{
base.Awake();
_idleState = new SkeletonStateIdle(this, _stateMachine, "Idle", this);
_moveState = new SkeletonStateMove(this, _stateMachine, "Move", this);
_engageState = new SkeletonStateEngage(this, _stateMachine, "Move", this);
_attackState = new SkeletonStateAttack(this, _stateMachine, "Attack", this);
}
// 초기 Skeleton은 IdleState에서 시작함
protected override void Start()
{
base.Start();
_stateMachine.Init(_idleState);
}
protected override void Update()
{
base.Update();
}
}
2) 땅을 딛고 서 있는 SkeletonStateGrounded
public class SkeletonStateGrounded : EnemyState
{
// Skeleton의 State이므로 SkeletonContoller가 필요함
// 추가적으로 Player를 탐지해야 하므로 Player를 갖고 있음
protected SkeletonController _skeletonController;
protected Transform _player;
// 생성자에서는 추가적으로 SkeletonController를 설정함
public SkeletonStateGrounded(EnemyController enemyBaseController, EnemyStateMachine enemyStateMachine, string animatorBoolParamName, SkeletonController enemyController)
: base(enemyBaseController, enemyStateMachine, animatorBoolParamName)
{
this._skeletonController = enemyController;
}
// StateGrouned에 들어가면 Player를 탐색하여 변수를 설정
// 그러나 GameObject.Find는 좋은 연산이 아니므로 후에 수정할 예정
public override void Enter()
{
base.Enter();
_player = GameObject.Find("Player").transform;
}
public override void Exit()
{
base.Exit();
}
// StateGrounded에서는 매 프레임마다
// 플레이어가 탐지되었는지 또는 플레이어와 Skeleton의 거리가 2보다 작은지를 판단하여
// State를 EngageState로 변환함
public override void Update()
{
base.Update();
if (_skeletonController.DoDetectPlayer() || Vector2.Distance(_skeletonController.transform.position, _player.position) < 2)
_enemyStateMachine.ChangeState(_skeletonController._engageState);
}
}
3) 가만히 서 있는 SkeletonStateIdle
public class SkeletonStateIdle : SkeletonStateGrounded
{
public SkeletonStateIdle(EnemyController enemyBaseController, EnemyStateMachine enemyStateMachine, string animatorBoolParamName, SkeletonController enemyController)
: base(enemyBaseController, enemyStateMachine, animatorBoolParamName, enemyController)
{
}
// IdleState에서는 들어간 순간에 _stateTimer를 _idleTimer 값으로 설정함
public override void Enter()
{
base.Enter();
_stateTimer = _enemyBaseController._idleTime;
}
public override void Exit()
{
base.Exit();
}
// 매 프레임마다 실행하는 Update에서는 _stateTimer가 0보다 작다면 IdleState를 탈출하고 MoveState로 들어감
public override void Update()
{
base.Update();
if (_stateTimer < 0)
{
_enemyStateMachine.ChangeState(_skeletonController._moveState);
}
}
}
4) 이동하는 상태의 SkeletonStateMove
public class SkeletonStateMove : SkeletonStateGrounded
{
public SkeletonStateMove(EnemyController enemyBaseController, EnemyStateMachine enemyStateMachine, string animatorBoolParamName, SkeletonController enemyController)
: base(enemyBaseController, enemyStateMachine, animatorBoolParamName, enemyController)
{
}
public override void Enter()
{
base.Enter();
}
public override void Exit()
{
base.Exit();
}
// 매 프레임마다 실행되는 MoveState의 Update함수의 경우 다음과 같이 처리함
public override void Update()
{
base.Update();
// 기본적으로 Skeleton을 움지이게끔 하되,
_skeletonController.SetVelocity(_enemyBaseController._moveSpeed * _skeletonController._facingDir, _rigidbody2D.velocity.y);
// 만약 벽을 마주하고 있거나, 땅을 딛고 있지 않다면
if (_skeletonController.DoDetectIsFacingWall() || !_skeletonController.DoDetectIsGrounded())
{
// 방향을 전환하고 IdleState로 변환함
_skeletonController.Flip();
_enemyStateMachine.ChangeState(_skeletonController._idleState);
}
}
}
728x90
반응형
'유니티 > 게임 프로젝트' 카테고리의 다른 글
2D RPG - (11) 피격에 따른 효과 구현하기 (0) | 2024.12.30 |
---|---|
2D RPG - (10) 스켈레톤 만들기 (마무리) (0) | 2024.12.18 |
2D RPG - (8) 적을 위한 세팅 (1) | 2024.12.18 |
2D RPG - (7) 무한반복되는 배경 만들기 (0) | 2024.12.11 |
2D RPG - (6) Tilemap을 통한 배경 그리기 + Cinemachine (0) | 2024.12.11 |