DEG-28 DEG-32 [feat] Enemy 상태 머신 생성

This commit is contained in:
fiore 2025-04-16 21:20:05 +09:00
parent f5feee033e
commit e290f9af76
30 changed files with 345 additions and 5 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 705f5cc824e16644497801b43f81b1c1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/JYY/Animator.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 47617fd7d9aae9841b8df03a9c71aab2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5ae32e910b172b4f7b04fbf91607ef7d871adec9ee0233990fd3b38d3be5a807
size 10132

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0a0b0196c516e454bbdb102f6dba08cf
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

8
Assets/JYY/Prefabs.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 622537ed9949f364799229e66b81e7e0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/JYY/Scenes/MonsterTest.unity (Stored with Git LFS)

Binary file not shown.

View File

@ -11,7 +11,8 @@ public abstract class CharacterBase : MonoBehaviour
public float attackPower = 10f; // 공격력
public float defensePower = 5f; // 방어력
public float moveSpeed = 5f; // 이동 속도
public float gravity = -9.81f; // 중력
protected readonly float gravity = -9.81f; // 중력
[Header("상태 이상")]
public List<StatusEffect> statusEffects = new List<StatusEffect>();

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5665d6cc085acce42bfd3d0c921f7718
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,96 @@
using System.Collections.Generic;
using UnityEngine;
public enum EnemyState { None, Idle, Trace, Attack, GetHit, Move, Dead }
[RequireComponent(typeof(Animator))]
public class EnemyController : CharacterBase
{
[Header("AI")]
[SerializeField] private float detectCircleRadius = 10f; // 플레이어 탐지 범위
[SerializeField] private LayerMask targetLayerMask; // 플레이어 레이어 마스크
public Animator EnemyAnimator { get; private set; }
public EnemyState CurrentState { get; private set; }
private EnemyState _currentState = EnemyState.Idle;
// -----
// 상태 변수
private EnemyStateIdle _enemyStateIdle;
private EnemyStateTrace _enemyStateTrace;
private EnemyStateAttack _enemyStateAttack;
private EnemyStateGetHit _enemyStateGetHit;
private EnemyStateDead _enemyStateDead;
private EnemyStateMove _enemyStateMove;
private Dictionary<EnemyState, IEnemyState> _enemyStates;
protected override void Start()
{
base.Start();
EnemyAnimator = GetComponent<Animator>();
// 상태 객체 생성
_enemyStateIdle = new EnemyStateIdle();
_enemyStateTrace = new EnemyStateTrace();
_enemyStateAttack = new EnemyStateAttack();
_enemyStateGetHit = new EnemyStateGetHit();
_enemyStateDead = new EnemyStateDead();
_enemyStateMove = new EnemyStateMove();
_enemyStates = new Dictionary<EnemyState, IEnemyState>
{
{ EnemyState.Idle, _enemyStateIdle },
{ EnemyState.Trace, _enemyStateTrace },
{ EnemyState.Attack, _enemyStateAttack },
{ EnemyState.GetHit, _enemyStateGetHit },
{ EnemyState.Dead, _enemyStateDead },
{ EnemyState.Move, _enemyStateMove}
};
SetState(EnemyState.Idle);
}
private void Update()
{
if (CurrentState != EnemyState.None)
{
_enemyStates[CurrentState].Update();
}
}
public void SetState(EnemyState newState)
{
if (CurrentState != EnemyState.None)
{
_enemyStates[CurrentState].Exit();
}
CurrentState = newState;
_enemyStates[CurrentState].Enter(this);
}
#region
// 일정 반경에 플레이어가 진입하면 플레이어 소리를 감지했다고 판단
public Transform DetectPlayerInCircle()
{
var hitColliders = Physics.OverlapSphere(transform.position,
detectCircleRadius, targetLayerMask);
if (hitColliders.Length > 0)
{
return hitColliders[0].transform;
}
else
{
return null;
}
}
#endregion
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 137423ca7381405581ab4e95d0e272da
timeCreated: 1744796946

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 63a5cd5bb2e90b54192be930aad261db
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
public class EnemyStateAttack : IEnemyState
{
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
}
public void Update()
{
}
public void Exit()
{
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 29b87c92807e4f6b94c8a08ccc510321
timeCreated: 1744799701

View File

@ -0,0 +1,19 @@
public class EnemyStateDead : IEnemyState
{
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
}
public void Update()
{
}
public void Exit()
{
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4846f061be91409096d5517aa2c692fa
timeCreated: 1744799618

View File

@ -0,0 +1,19 @@
public class EnemyStateGetHit: IEnemyState
{
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
}
public void Update()
{
}
public void Exit()
{
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7067b1b0eacf490c863a4cb68c290d3a
timeCreated: 1744799049

View File

@ -0,0 +1,28 @@
using UnityEngine;
public class EnemyStateIdle: IEnemyState
{
private static readonly int Idle = Animator.StringToHash("Idle");
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
_enemyController.EnemyAnimator.SetBool(Idle, true);
}
public void Update()
{
var detectPlayerTransform = _enemyController.DetectPlayerInCircle();
if (detectPlayerTransform)
{
_enemyController.SetState(EnemyState.Trace);
}
}
public void Exit()
{
_enemyController.EnemyAnimator.SetBool(Idle, false);
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: df3f42dea99a423b8e2ec18e07e58767
timeCreated: 1744799656

View File

@ -0,0 +1,19 @@
public class EnemyStateMove : IEnemyState
{
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
}
public void Update()
{
}
public void Exit()
{
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5abb29c9137942fe95bc66670d8ef521
timeCreated: 1744799142

View File

@ -0,0 +1,18 @@
public class EnemyStateTrace : IEnemyState
{
private EnemyController _enemyController;
public void Enter(EnemyController enemyController)
{
_enemyController = enemyController;
}
public void Update()
{
}
public void Exit()
{
_enemyController = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d49fe89f824544eebeb0ad8e364e33d4
timeCreated: 1744797593

View File

@ -0,0 +1,6 @@
public interface IEnemyState
{
void Enter(EnemyController enemyController);
void Update();
void Exit();
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 418026380ec247acaf9ff06190d2fbf2
timeCreated: 1744796715

View File

@ -0,0 +1,19 @@
using System;
using UnityEngine;
public class PldDogController : EnemyController
{
private void Awake()
{
}
private void Update()
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10f85207f9bd92647b5c38d8a408f024
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ae2ce41b02d61d247b6857c4cec7151c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.