상속
기존에 정의된 클래스(부모 클래스 또는 상위 클래스)의 특성과 동작을 새로운 클래스(자식 클래스 또는 하위 클래스)가 물려받아 그대로 사용하거나 확장하여 새로운 클래스를 정의하는 것.
Attack State
기본적인 AttackState를 하나 만듭니다.
public class EnemyAttackState : EnemyBaseState { protected float lastShootTime; public EnemyAttackState(EnemyStateMachine ememyStateMachine) : base(ememyStateMachine) { } public override void Enter() { lastShootTime = 0f; base.Enter(); StartAnimation(stateMachine.Enemy.AnimationData.AttackParameterHash); } public override void Exit() { base.Exit(); StopAnimation(stateMachine.Enemy.AnimationData.AttackParameterHash); } public override void Update() { Rotate(GetTargetDirection()); } private Vector3 GetTargetDirection() { Vector3 direction = stateMachine.Target.transform.position - stateMachine.Enemy.transform.position; return direction.normalized; } }
AttackState를 상속받을 모든 스테이트가 공통적으로 사용하는 lastShootTime을 protected 로 만들어 총알이 빠르게 발사되지 않도록 만들 계획입니다.
public class EnemyProneAttackState : EnemyAttackState { private EnemyGun weapon; private bool hasAdjustedRotation = false; public EnemyProneAttackState(EnemyStateMachine ememyStateMachine) : base(ememyStateMachine) { if (stateMachine.Enemy.Weapon != null) { weapon = stateMachine.Enemy.Weapon as EnemyGun; } } public override void Enter() { base.Enter(); StartAnimation(stateMachine.Enemy.AnimationData.ProneAttackParameterHash); hasAdjustedRotation = false; } public override void Exit() { base.Exit(); StopAnimation(stateMachine.Enemy.AnimationData.ProneAttackParameterHash); hasAdjustedRotation = false; } public override void Update() { base.Update(); if (stateMachine.Enemy.EnemyHealth.PhaseIndex == 2) { stateMachine.ChangeState(stateMachine.MovePosState); return; } if (IsInAttackRange()) { if (!hasAdjustedRotation) { AdjustWeaponRotation(hitPoint); hasAdjustedRotation = true; } if (Time.time - lastShootTime >= weapon.gunData.fireInterval) { weapon.Shoot(); lastShootTime = Time.time; } } } private void AdjustWeaponRotation(Vector3 hitpoint) { // hitpoint를 향하는 방향으로 회전하는 쿼터니언 생성 weapon.transform.rotation = Quaternion.LookRotation(hitpoint - weapon.transform.position); } }
엎드렸을 때 AttackRange안에 있다면 무기의 방향을 플레이어의 방향을 바라보도록 회전을 시키고 AttackState의 lastShootTime을 이용하여 fireInterval만큼의 시간동안 발사를 대기하도록 만들어줍니다.
stateMachine.Enemy.EnemyHealth.PhaseIndex를 이용해 다음 자세로 변경 시킵니다.
public class EnemyWalkCrouchingAttackState : EnemyAttackState { private EnemyGun weapon; private bool hasAdjustedRotation = false; public EnemyWalkCrouchingAttackState(EnemyStateMachine ememyStateMachine) : base(ememyStateMachine) { if (stateMachine.Enemy.Weapon != null) { weapon = stateMachine.Enemy.Weapon as EnemyGun; } } public override void Enter() { base.Enter(); stateMachine.MovementSpeedModifier = 0.4f; StartAnimation(stateMachine.Enemy.AnimationData.CrouchingAttackParameterHash); hasAdjustedRotation = false; } public override void Exit() { base.Exit(); StopAnimation(stateMachine.Enemy.AnimationData.CrouchingAttackParameterHash); hasAdjustedRotation = false; } public override void Update() { base.Update(); MoveLeftAndRight(); if (IsInAttackRange()) { if (!hasAdjustedRotation) { AdjustWeaponRotation(hitPoint); hasAdjustedRotation = true; } if (Time.time - lastShootTime >= weapon.gunData.fireInterval) { weapon.Shoot(); lastShootTime = Time.time; } } } private void MoveLeftAndRight() { float direction = Mathf.Sin(Time.time); // 시간에 따라 좌우로 움직이도록 함 Move(direction * stateMachine.Enemy.transform.right); } private void AdjustWeaponRotation(Vector3 hitpoint) { // hitpoint를 향하는 방향으로 회전하는 쿼터니언 생성 weapon.transform.rotation = Quaternion.LookRotation(hitpoint - weapon.transform.position); } }
엎드려 쏴 자세와 같이 AdjustWeaponRotation을 이용하여 무기를 돌리고 MoveLeftAndRight함수에서 Mathf.Sin(Time.time);을 이용하여 시간에 따라 1에서 -1의 값을 받아와 stateMachine.Enemy.transform.right를 곱하여 캐릭터를 움직여줍니다. 이렇게 하면 캐릭터가 오른쪽과 왼쪽을 번갈아서 이동하게 됩니다.
좋은 정보 감사합니다