Unity/TopdownEngine

Weapon Life cycle Debug

lipnus 2023. 12. 18. 13:38
반응형

특이한 케이스에서 발생하는 엔진 자체의 버그인것 같음

다소 복잡하므로 나중을 대비하여 기록.

 

Error

Enemy의 Weapon이 재장전 상태에 있을 때 Enemy의 시야에서 벗어났다가 다시 재진입하면 공격을 하지 않는 버그

 

Description

Weapon의 Lifecycle은 아래와 같음 (이 순서대로임)

protected virtual void ProcessWeaponState()
		{
			if (WeaponState == null)
			{
				return;
			}

			UpdateAnimator();

			switch (WeaponState.CurrentState)
			{
				case WeaponStates.WeaponIdle:
					CaseWeaponIdle();
					break;

				case WeaponStates.WeaponStart:
					CaseWeaponStart();
					break;

				case WeaponStates.WeaponDelayBeforeUse:
					CaseWeaponDelayBeforeUse();
					break;

				case WeaponStates.WeaponUse:
					CaseWeaponUse();
					break;

				case WeaponStates.WeaponDelayBetweenUses:
					CaseWeaponDelayBetweenUses();
					break;

				case WeaponStates.WeaponStop:
					CaseWeaponStop();
					break;

				case WeaponStates.WeaponReloadNeeded:
					CaseWeaponReloadNeeded();
					break;

				case WeaponStates.WeaponReloadStart:
					CaseWeaponReloadStart();
					break;

				case WeaponStates.WeaponReload:
					CaseWeaponReload();
					break;

				case WeaponStates.WeaponReloadStop:
					CaseWeaponReloadStop();
					break;

				case WeaponStates.WeaponInterrupted:
					CaseWeaponInterrupted();
					break;
			}
		}

 

 

적 Weapon의 공격은 AIBraion의 AIActionShoot3D.cs 에서 통제함.

 

📌사격: Shoot() 

TargetHandleWeaponAbility.ShootStart(_brain.Target);

 

📌 중지(해당 AI State를 벗어났을 때): OnExitState()

TargetHandleWeaponAbility.ForceStop();    

 

 

 

WeaponState가 재장전일때, ForceStop을 하게되면 State가 꼬이게 됨.

(정확히 어떤 WeaponState인지는 까먹음)

 

크게 문제가 되는 Flag은 아래 두가지.

_reloading, _trggerReleased 

해당 경로에서 이 두 Flag가 리셋이 안됨.

 

Solution

AIBrain에 의해 WeaponState가 정지된 경우에는 

ForceStop() 대신 ForceStopFromAI() 매소드를 통해 위 두 Flag까지 리셋시켜주도록 수정.

 

CharacterHandleWeapon.cs

		public virtual void ForceStop()
		{
			StopStartFeedbacks();
			PlayAbilityStopFeedbacks();
			if (CurrentWeapon != null)
			{
				CurrentWeapon.TurnWeaponOff();    
			}
		}

		public virtual void ForceStopFromAI()
		{
			StopStartFeedbacks();
			PlayAbilityStopFeedbacks();
			if (CurrentWeapon != null)
			{
				CurrentWeapon.TurnWeaponOff();
				CurrentWeapon.ForceResetWeapon();
			}
		}

 

Weapon.cs

		public void ForceResetWeapon()
		{
			_reloading = false;
			_triggerReleased = false;
		}

 

 

Diagram

https://drive.google.com/file/d/1YM-YOklXEnLSTRFEl8-jgQkoTfPIb0QC/view?usp=sharing

 

https://drive.google.com/file/d/1lmFF67s5s8A3Vn1YDxTx9Y-prj-qPkPB/view?usp=sharing

 

반응형