몬스터 애니메이션 연동 버그 수정

This commit is contained in:
윤기주_playm 2026-02-21 03:19:49 +09:00
parent 9d2873644b
commit 2a033581a0
14 changed files with 35195 additions and 9147 deletions

BIN
.plastic/plastic.changes Normal file

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -903,6 +903,10 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z propertyPath: m_LocalEulerAnglesHint.z
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 9500000, guid: 74236a73e891a4540a264993ac8d337b, type: 3}
propertyPath: m_Avatar
value:
objectReference: {fileID: 9000000, guid: 62d084832da52460c8e4037dbeb673a9, type: 3}
- target: {fileID: 9500000, guid: 74236a73e891a4540a264993ac8d337b, type: 3} - target: {fileID: 9500000, guid: 74236a73e891a4540a264993ac8d337b, type: 3}
propertyPath: m_Controller propertyPath: m_Controller
value: value:
@ -992,9 +996,9 @@ MonoBehaviour:
expReward: 10 expReward: 10
moveSpeed: 3.5 moveSpeed: 3.5
myWeapon: {fileID: 0} myWeapon: {fileID: 0}
Monster_Idle: scavenger_idle Monster_Idle: 'scavenger_idle '
Monster_GetDamage: scavenger_damage Monster_GetDamage: 'scavenger_damage '
Monster_Die: scavenger_die Monster_Die: 'scavenger_die '
hitRecoverFallback: 1 hitRecoverFallback: 1
attackRestDuration: 1.5 attackRestDuration: 1.5
detectionRange: 10 detectionRange: 10
@ -1012,8 +1016,9 @@ MonoBehaviour:
fuseEffect: {fileID: 0} fuseEffect: {fileID: 0}
fuseSound: {fileID: 0} fuseSound: {fileID: 0}
explosionSound: {fileID: 0} explosionSound: {fileID: 0}
runAnim: scavenger_run runAnim: 'scavenger_run '
fuseAnim: scavenger_Fuse fuseAnim: scavenger_Fuse
showExplodeDebugLog: 1
--- !u!136 &4824808582826185509 --- !u!136 &4824808582826185509
CapsuleCollider: CapsuleCollider:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -1388,9 +1388,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9eb5b341f7503494e9b0f88cc4b1c17d, type: 3} m_Script: {fileID: 11500000, guid: 9eb5b341f7503494e9b0f88cc4b1c17d, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
healthSource: {fileID: 1727176290165168055} targetObject: {fileID: 0}
hpFillImage: {fileID: 197665650599347112}
hpText: {fileID: 6986518538193087157}
--- !u!1 &3511228176158128295 --- !u!1 &3511228176158128295
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1989,7 +1987,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
optimizationDistance: 40 optimizationDistance: 40
maxHP: 150 maxHP: 100
attackDamage: 20 attackDamage: 20
expReward: 8 expReward: 8
moveSpeed: 3.5 moveSpeed: 3.5
@ -1997,7 +1995,10 @@ MonoBehaviour:
Monster_Idle: ghoul_idle Monster_Idle: ghoul_idle
Monster_GetDamage: ghoul_gethit Monster_GetDamage: ghoul_gethit
Monster_Die: ghoul_die Monster_Die: ghoul_die
hitRecoverFallback: 1
attackRestDuration: 1.5 attackRestDuration: 1.5
detectionRange: 10
showDebugGizmos: 0
hitSound: {fileID: 0} hitSound: {fileID: 0}
deathSound: {fileID: 0} deathSound: {fileID: 0}
deathEffectPrefab: {fileID: 0} deathEffectPrefab: {fileID: 0}
@ -2013,9 +2014,6 @@ MonoBehaviour:
attackAnimations: attackAnimations:
- ghoul_attack - ghoul_attack
Monster_Walk: ghoul_walk Monster_Walk: ghoul_walk
stopBuffer: 0.3
patrolRadius: 5
patrolInterval: 2
--- !u!195 &8274003280596335008 --- !u!195 &8274003280596335008
NavMeshAgent: NavMeshAgent:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -1544,7 +1544,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
optimizationDistance: 40 optimizationDistance: 40
maxHP: 300 maxHP: 100
attackDamage: 10 attackDamage: 10
expReward: 10 expReward: 10
moveSpeed: 3.5 moveSpeed: 3.5
@ -1552,6 +1552,7 @@ MonoBehaviour:
Monster_Idle: Monster_Idle Monster_Idle: Monster_Idle
Monster_GetDamage: Monster_GetDamage Monster_GetDamage: Monster_GetDamage
Monster_Die: Monster_Die Monster_Die: Monster_Die
hitRecoverFallback: 1
attackRestDuration: 1.5 attackRestDuration: 1.5
detectionRange: 10 detectionRange: 10
showDebugGizmos: 1 showDebugGizmos: 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7cea8855ca3183f4abf3654fdff23011
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -171,12 +171,12 @@ AnimatorStateMachine:
- serializedVersion: 1 - serializedVersion: 1
m_State: {fileID: 1071916381367737375} m_State: {fileID: 1071916381367737375}
m_Position: {x: 220, y: 350, z: 0} m_Position: {x: 220, y: 350, z: 0}
- serializedVersion: 1
m_State: {fileID: 1597451026196869062}
m_Position: {x: 310, y: 450, z: 0}
- serializedVersion: 1 - serializedVersion: 1
m_State: {fileID: -5161057755351849107} m_State: {fileID: -5161057755351849107}
m_Position: {x: 190, y: 290, z: 0} m_Position: {x: 190, y: 290, z: 0}
- serializedVersion: 1
m_State: {fileID: 6957203282615137037}
m_Position: {x: 270, y: 450, z: 0}
m_ChildStateMachines: [] m_ChildStateMachines: []
m_AnyStateTransitions: [] m_AnyStateTransitions: []
m_EntryTransitions: [] m_EntryTransitions: []
@ -187,32 +187,6 @@ AnimatorStateMachine:
m_ExitPosition: {x: 800, y: 120, z: 0} m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 4817866092193183352} m_DefaultState: {fileID: 4817866092193183352}
--- !u!1102 &1597451026196869062
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ghoul_walk
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: 6aa2008e4fe28b443b5c93d5b9f768d7, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &4817866092193183352 --- !u!1102 &4817866092193183352
AnimatorState: AnimatorState:
serializedVersion: 6 serializedVersion: 6
@ -239,3 +213,29 @@ AnimatorState:
m_MirrorParameter: m_MirrorParameter:
m_CycleOffsetParameter: m_CycleOffsetParameter:
m_TimeParameter: m_TimeParameter:
--- !u!1102 &6957203282615137037
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ghoul_walk
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: 7cea8855ca3183f4abf3654fdff23011, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:

View File

@ -23,6 +23,7 @@ public class ExplodeMonster : MonsterClass // 클래스를 선언할거에요 ->
[SerializeField] private bool showExplodeDebugLog = true; // 변수를 선언할거에요 -> 디버그 로그 on/off를 [SerializeField] private bool showExplodeDebugLog = true; // 변수를 선언할거에요 -> 디버그 로그 on/off를
private bool hasExploded = false; // 변수를 선언할거에요 -> 폭발 완료 여부를 private bool hasExploded = false; // 변수를 선언할거에요 -> 폭발 완료 여부를
private string _lastLoggedState = ""; // 변수를 선언할거에요 -> 직전 로그 State 이름을
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────
// AI 로직 // AI 로직
@ -39,7 +40,6 @@ public class ExplodeMonster : MonsterClass // 클래스를 선언할거에요 ->
else // 조건이 틀리면 실행할거에요 -> 멀면 else // 조건이 틀리면 실행할거에요 -> 멀면
ChasePlayer(); // 실행할거에요 -> 추격을 ChasePlayer(); // 실행할거에요 -> 추격을
} }
private string _lastLoggedState = ""; // 변수를 선언할거에요 -> 직전 로그 State 이름을
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────
// 초기화 // 초기화
@ -115,6 +115,11 @@ public class ExplodeMonster : MonsterClass // 클래스를 선언할거에요 ->
} }
} }
// ─────────────────────────────────────────────────────────
// 추격
// ─────────────────────────────────────────────────────────
private void ChasePlayer() // ← 빠져있던 메서드 선언부 복원
{ {
if (agent != null && agent.isOnNavMesh) // 조건이 맞으면 실행할거에요 -> 에이전트가 정상이면 if (agent != null && agent.isOnNavMesh) // 조건이 맞으면 실행할거에요 -> 에이전트가 정상이면
{ {

View File

@ -65,6 +65,15 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
protected virtual void Awake() // 함수를 실행할거에요 -> 컴포넌트 캐싱을 protected virtual void Awake() // 함수를 실행할거에요 -> 컴포넌트 캐싱을
{ {
animator = GetComponent<Animator>(); // 가져올거에요 -> 애니메이터를
agent = GetComponent<NavMeshAgent>(); // 가져올거에요 -> 에이전트를
audioSource = GetComponent<AudioSource>(); // 가져올거에요 -> 오디오 소스를
mobRenderer = GetComponentInChildren<Renderer>(); // 가져올거에요 -> 렌더러를
// statusProcessor = GetComponent<StatusEffectProcessor>(); // 가져올거에요 -> 상태이상 처리기를
if (agent != null) agent.speed = moveSpeed; // 설정할거에요 -> 이동 속도를
Init(); // 실행할거에요 -> 자식 클래스 추가 초기화를
} }
protected virtual void OnEnable() // 함수를 실행할거에요 -> 활성화/스폰될 때마다 protected virtual void OnEnable() // 함수를 실행할거에요 -> 활성화/스폰될 때마다
@ -77,8 +86,6 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
protected virtual void Init() { } // 가상 함수를 선언할거에요 -> 자식 클래스 전용 추가 초기화를 protected virtual void Init() { } // 가상 함수를 선언할거에요 -> 자식 클래스 전용 추가 초기화를
protected virtual void Init() { } // 비워둘거에요 -> MobUpdateManager가 OnManagedUpdate를 담당하니까
protected virtual void OnDisable() // 함수를 실행할거에요 -> 비활성화 시 protected virtual void OnDisable() // 함수를 실행할거에요 -> 비활성화 시
{ {
if (MobUpdateManager.Instance != null) MobUpdateManager.Instance.UnregisterMob(this); // 해제할거에요 -> 매니저에서 if (MobUpdateManager.Instance != null) MobUpdateManager.Instance.UnregisterMob(this); // 해제할거에요 -> 매니저에서
@ -124,6 +131,7 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
agent.SetDestination(playerTransform.position); // 이동할거에요 -> 플레이어에게 agent.SetDestination(playerTransform.position); // 이동할거에요 -> 플레이어에게
} }
} }
protected abstract void ExecuteAILogic(); // 추상 함수를 선언할거에요 -> 자식이 반드시 구현해야 하는 AI를 protected abstract void ExecuteAILogic(); // 추상 함수를 선언할거에요 -> 자식이 반드시 구현해야 하는 AI를
protected virtual void OnResetStats() { } // 가상 함수를 선언할거에요 -> 자식 클래스 추가 리셋을 protected virtual void OnResetStats() { } // 가상 함수를 선언할거에요 -> 자식 클래스 추가 리셋을
@ -179,6 +187,7 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
if (!animator.GetCurrentAnimatorStateInfo(0).IsName(Monster_Idle)) if (!animator.GetCurrentAnimatorStateInfo(0).IsName(Monster_Idle))
animator.Play(Monster_Idle, 0, 0f); // 재생할거에요 -> 대기 애니를 animator.Play(Monster_Idle, 0, 0f); // 재생할거에요 -> 대기 애니를
} }
} // ← 빠져있던 닫는 중괄호 복원
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────
// 피격 처리 // 피격 처리
@ -216,6 +225,7 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
OnHealthChanged?.Invoke(currentHP, maxHP); // 알릴거에요 -> UI에 OnHealthChanged?.Invoke(currentHP, maxHP); // 알릴거에요 -> UI에
} }
private void StartHit() // ← 빠져있던 메서드 선언부 복원
{ {
isHit = true; // 설정할거에요 -> 피격 상태를 isHit = true; // 설정할거에요 -> 피격 상태를
isAttacking = false; // 해제할거에요 -> 공격 상태를 isAttacking = false; // 해제할거에요 -> 공격 상태를
@ -271,6 +281,7 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
if (myWeapon != null) myWeapon.DisableHitBox(); // 끌거에요 -> 무기 판정을 if (myWeapon != null) myWeapon.DisableHitBox(); // 끌거에요 -> 무기 판정을
} }
public virtual void OnHitEnd() // ← 빠져있던 메서드 선언부 복원
{ {
isHit = false; // 해제할거에요 -> 피격 상태를 isHit = false; // 해제할거에요 -> 피격 상태를
_hitCoroutine = null; // 초기화할거에요 -> 코루틴 핸들을 _hitCoroutine = null; // 초기화할거에요 -> 코루틴 핸들을
@ -323,6 +334,7 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
if (myWeapon != null) myWeapon.EnableHitBox(); // 켤거에요 -> 무기 판정을 if (myWeapon != null) myWeapon.EnableHitBox(); // 켤거에요 -> 무기 판정을
} }
public virtual void OnAttackEnd() // ← 빠져있던 메서드 선언부 복원
{ {
if (myWeapon != null) myWeapon.DisableHitBox(); // 끌거에요 -> 무기 판정을 if (myWeapon != null) myWeapon.DisableHitBox(); // 끌거에요 -> 무기 판정을
isAttacking = false; // 해제할거에요 -> 공격 상태를 isAttacking = false; // 해제할거에요 -> 공격 상태를
@ -331,6 +343,9 @@ public abstract class MonsterClass : MonoBehaviour, IDamageable // 추상 클래
protected virtual IEnumerator RestAfterAttack() // 코루틴을 선언할거에요 -> 공격 후 휴식 로직을 protected virtual IEnumerator RestAfterAttack() // 코루틴을 선언할거에요 -> 공격 후 휴식 로직을
{ {
isResting = true; // 설정할거에요 -> 휴식 상태를
yield return new WaitForSeconds(attackRestDuration); // 기다릴거에요 -> 휴식 시간만큼
isResting = false; // 해제할거에요 -> 휴식 상태를
} }
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────

View File

@ -58,7 +58,16 @@ public class MeleeMonster : MonsterClass // 클래스를 선언할거에요 ->
} }
} }
private void TryAttack() // ← 빠져있던 메서드 선언부 복원
{ {
if (Time.time - lastAttackTime < attackDelay) return; // 중단할거에요 -> 딜레이 안 지났으면
lastAttackTime = Time.time; // 갱신할거에요 -> 마지막 공격 시간을
if (agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; } // 멈출거에요 -> 이동을
Vector3 dir = (playerTransform.position - transform.position).normalized; // 계산할거에요 -> 방향을
dir.y = 0; // 수평으로 보정할거에요
transform.rotation = Quaternion.LookRotation(dir); // 회전할거에요 -> 플레이어를 바라보게
string animName = attackAnimations[attackIndex]; // 가져올거에요 -> 애니 이름을 string animName = attackAnimations[attackIndex]; // 가져올거에요 -> 애니 이름을
attackIndex = (attackIndex + 1) % attackAnimations.Length; // 갱신할거에요 -> 인덱스를 attackIndex = (attackIndex + 1) % attackAnimations.Length; // 갱신할거에요 -> 인덱스를

View File

@ -41,7 +41,12 @@ public class UniversalRangedMonster : MonsterClass // 클래스를 선언할거
} }
} }
private void TryAttack() // ← 빠져있던 메서드 선언부 복원
{ {
if (Time.time - lastAttackTime < attackDelay) return; // 중단할거에요 -> 딜레이 안 지났으면
lastAttackTime = Time.time; // 갱신할거에요 -> 마지막 공격 시간을
if (agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; } // 멈출거에요 -> 이동을
Vector3 dir = (playerTransform.position - transform.position).normalized; dir.y = 0; // 계산할거에요 -> 방향을 Vector3 dir = (playerTransform.position - transform.position).normalized; dir.y = 0; // 계산할거에요 -> 방향을
transform.rotation = Quaternion.LookRotation(dir); // 회전할거에요 -> 방향대로 transform.rotation = Quaternion.LookRotation(dir); // 회전할거에요 -> 방향대로