..
This commit is contained in:
parent
7967bfb405
commit
2e401f1042
|
|
@ -146660,6 +146660,9 @@ PrefabInstance:
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 2123637860}
|
addedObject: {fileID: 2123637860}
|
||||||
m_AddedComponents:
|
m_AddedComponents:
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 1432447527}
|
||||||
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 1432447519}
|
addedObject: {fileID: 1432447519}
|
||||||
|
|
@ -146672,9 +146675,6 @@ PrefabInstance:
|
||||||
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 1432447533}
|
addedObject: {fileID: 1432447533}
|
||||||
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
|
||||||
insertIndex: -1
|
|
||||||
addedObject: {fileID: 1432447527}
|
|
||||||
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 1432447531}
|
addedObject: {fileID: 1432447531}
|
||||||
|
|
@ -146787,8 +146787,9 @@ MonoBehaviour:
|
||||||
pAnim: {fileID: 1432447533}
|
pAnim: {fileID: 1432447533}
|
||||||
playerHealth: {fileID: 1432447526}
|
playerHealth: {fileID: 1432447526}
|
||||||
weaponHitBox: {fileID: 1938848879}
|
weaponHitBox: {fileID: 1938848879}
|
||||||
attackCooldown: 0.4
|
attackCooldown: 0.5
|
||||||
fullChargeTime: 3
|
fullChargeTime: 3
|
||||||
|
postComboDelay: 1.2
|
||||||
--- !u!114 &1432447528
|
--- !u!114 &1432447528
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,14 @@ ModelImporter:
|
||||||
mirror: 0
|
mirror: 0
|
||||||
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
||||||
curves: []
|
curves: []
|
||||||
events: []
|
events:
|
||||||
|
- time: 0.26926506
|
||||||
|
functionName: OnAttackEnd
|
||||||
|
data:
|
||||||
|
objectReferenceParameter: {instanceID: 0}
|
||||||
|
floatParameter: 0
|
||||||
|
intParameter: 0
|
||||||
|
messageOptions: 0
|
||||||
transformMask: []
|
transformMask: []
|
||||||
maskType: 3
|
maskType: 3
|
||||||
maskSource: {instanceID: 0}
|
maskSource: {instanceID: 0}
|
||||||
|
|
|
||||||
|
|
@ -65218,14 +65218,14 @@ AnimationClip:
|
||||||
m_HasMotionFloatCurves: 0
|
m_HasMotionFloatCurves: 0
|
||||||
m_Events:
|
m_Events:
|
||||||
- time: 0.6333333
|
- time: 0.6333333
|
||||||
functionName: OnAttackShake
|
functionName: StartWeaponCollision
|
||||||
data:
|
data:
|
||||||
objectReferenceParameter: {fileID: 0}
|
objectReferenceParameter: {fileID: 0}
|
||||||
floatParameter: 0
|
floatParameter: 0
|
||||||
intParameter: 0
|
intParameter: 0
|
||||||
messageOptions: 0
|
messageOptions: 0
|
||||||
- time: 0.6333333
|
- time: 0.65
|
||||||
functionName: StartWeaponCollision
|
functionName: OnAttackShake
|
||||||
data:
|
data:
|
||||||
objectReferenceParameter: {fileID: 0}
|
objectReferenceParameter: {fileID: 0}
|
||||||
floatParameter: 0
|
floatParameter: 0
|
||||||
|
|
|
||||||
|
|
@ -47825,7 +47825,7 @@ AnimationClip:
|
||||||
floatParameter: 0
|
floatParameter: 0
|
||||||
intParameter: 0
|
intParameter: 0
|
||||||
messageOptions: 0
|
messageOptions: 0
|
||||||
- time: 0.43333334
|
- time: 0.45
|
||||||
functionName: OnAttackShake
|
functionName: OnAttackShake
|
||||||
data:
|
data:
|
||||||
objectReferenceParameter: {fileID: 0}
|
objectReferenceParameter: {fileID: 0}
|
||||||
|
|
|
||||||
|
|
@ -67324,14 +67324,14 @@ AnimationClip:
|
||||||
m_HasMotionFloatCurves: 0
|
m_HasMotionFloatCurves: 0
|
||||||
m_Events:
|
m_Events:
|
||||||
- time: 0.2
|
- time: 0.2
|
||||||
functionName: OnAttackShake
|
functionName: StartWeaponCollision
|
||||||
data:
|
data:
|
||||||
objectReferenceParameter: {fileID: 0}
|
objectReferenceParameter: {fileID: 0}
|
||||||
floatParameter: 0
|
floatParameter: 0
|
||||||
intParameter: 0
|
intParameter: 0
|
||||||
messageOptions: 0
|
messageOptions: 0
|
||||||
- time: 0.20410536
|
- time: 0.21666667
|
||||||
functionName: StartWeaponCollision
|
functionName: OnAttackShake
|
||||||
data:
|
data:
|
||||||
objectReferenceParameter: {fileID: 0}
|
objectReferenceParameter: {fileID: 0}
|
||||||
floatParameter: 0
|
floatParameter: 0
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.AI;
|
using UnityEngine.AI;
|
||||||
|
using System.Collections; // ⭐ IEnumerator 사용을 위해 추가
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
public class MonsterClass : MonoBehaviour, IDamageable
|
public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
|
|
@ -18,6 +19,11 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
protected AudioSource audioSource;
|
protected AudioSource audioSource;
|
||||||
protected bool isHit;
|
protected bool isHit;
|
||||||
protected bool isDead;
|
protected bool isDead;
|
||||||
|
protected bool isAttacking;
|
||||||
|
|
||||||
|
[Header("AI 설정 (공격 후 휴식)")]
|
||||||
|
[SerializeField] protected float attackRestDuration = 1.5f; // ⭐ 공격 후 쉬는 시간 (초)
|
||||||
|
protected bool isResting; // ⭐ 현재 쉬고 있는 상태인지 확인
|
||||||
|
|
||||||
[Header("경험치")]
|
[Header("경험치")]
|
||||||
[SerializeField] protected int expReward = 10;
|
[SerializeField] protected int expReward = 10;
|
||||||
|
|
@ -33,7 +39,6 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
[Header("--- 드랍 설정 ---")]
|
[Header("--- 드랍 설정 ---")]
|
||||||
[SerializeField] private GameObject potionPrefab;
|
[SerializeField] private GameObject potionPrefab;
|
||||||
[SerializeField][Range(0f, 100f)] private float potionDropChance = 30f;
|
[SerializeField][Range(0f, 100f)] private float potionDropChance = 30f;
|
||||||
|
|
||||||
[Space(10)]
|
[Space(10)]
|
||||||
[SerializeField] private GameObject[] weaponPrefabs;
|
[SerializeField] private GameObject[] weaponPrefabs;
|
||||||
[SerializeField][Range(0f, 100f)] private float weaponDropChance = 5f;
|
[SerializeField][Range(0f, 100f)] private float weaponDropChance = 5f;
|
||||||
|
|
@ -47,15 +52,23 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
OnHealthChanged?.Invoke(currentHP, maxHP);
|
OnHealthChanged?.Invoke(currentHP, maxHP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐ [애니메이션 버그 해결] 매 프레임 속도를 체크해서 애니메이터에 전달합니다.
|
|
||||||
protected virtual void Update()
|
protected virtual void Update()
|
||||||
{
|
{
|
||||||
if (isDead) return;
|
if (isDead) return;
|
||||||
|
|
||||||
if (agent != null && animator != null)
|
// ⭐ [수정] 피격(isHit), 공격(isAttacking), 또는 휴식(isResting) 중이면 이동을 멈춥니다.
|
||||||
|
bool shouldStop = isHit || isAttacking || isResting;
|
||||||
|
|
||||||
|
if (agent != null && agent.isOnNavMesh)
|
||||||
{
|
{
|
||||||
// 에이전트의 현재 이동 속도를 가져와서 "Speed" 파라미터에 넣어줍니다.
|
agent.isStopped = shouldStop;
|
||||||
float currentSpeed = agent.velocity.magnitude;
|
if (shouldStop) agent.velocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animator != null)
|
||||||
|
{
|
||||||
|
// 멈췄을 때는 속도를 0으로 전달하여 Idle 애니메이션이 나오게 합니다.
|
||||||
|
float currentSpeed = (agent != null && !shouldStop) ? agent.velocity.magnitude : 0f;
|
||||||
animator.SetFloat("Speed", currentSpeed);
|
animator.SetFloat("Speed", currentSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,12 +88,37 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
protected virtual void StartHit()
|
protected virtual void StartHit()
|
||||||
{
|
{
|
||||||
isHit = true;
|
isHit = true;
|
||||||
|
isAttacking = false;
|
||||||
|
isResting = false; // ⭐ 맞으면 쉬는 걸 중단하고 바로 아파해야 합니다.
|
||||||
|
StopAllCoroutines(); // 진행 중인 휴식 루틴을 끕니다.
|
||||||
|
|
||||||
if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; }
|
if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; }
|
||||||
|
|
||||||
animator.Play(Monster_GetDamage, 0, 0f);
|
animator.Play(Monster_GetDamage, 0, 0f);
|
||||||
if (hitEffect) hitEffect.Play();
|
if (hitEffect) hitEffect.Play();
|
||||||
if (hitSound) audioSource.PlayOneShot(hitSound);
|
if (hitSound) audioSource.PlayOneShot(hitSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnAttackStart() { isAttacking = true; isResting = false; }
|
||||||
|
|
||||||
|
// ⭐ [수정] 공격이 끝나면 바로 움직이는 게 아니라 '휴식' 코루틴을 실행합니다.
|
||||||
|
public virtual void OnAttackEnd()
|
||||||
|
{
|
||||||
|
isAttacking = false;
|
||||||
|
if (!isDead && !isHit)
|
||||||
|
{
|
||||||
|
StartCoroutine(RestAfterAttack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐ 공격 후 대기 코루틴
|
||||||
|
private IEnumerator RestAfterAttack()
|
||||||
|
{
|
||||||
|
isResting = true;
|
||||||
|
yield return new WaitForSeconds(attackRestDuration); // 설정한 시간만큼 대기
|
||||||
|
isResting = false;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void OnHitEnd() { isHit = false; if (agent && agent.isOnNavMesh) agent.isStopped = false; }
|
public virtual void OnHitEnd() { isHit = false; if (agent && agent.isOnNavMesh) agent.isStopped = false; }
|
||||||
|
|
||||||
protected virtual void Die()
|
protected virtual void Die()
|
||||||
|
|
@ -88,7 +126,6 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
if (isDead) return;
|
if (isDead) return;
|
||||||
isDead = true;
|
isDead = true;
|
||||||
|
|
||||||
// 아이템 날아감 방지: 몬스터 시체의 충돌을 끕니다.
|
|
||||||
Collider col = GetComponent<Collider>();
|
Collider col = GetComponent<Collider>();
|
||||||
if (col != null) col.enabled = false;
|
if (col != null) col.enabled = false;
|
||||||
|
|
||||||
|
|
@ -97,7 +134,6 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
|
|
||||||
if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; }
|
if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; }
|
||||||
animator.Play(Monster_Die, 0, 0f);
|
animator.Play(Monster_Die, 0, 0f);
|
||||||
Debug.Log("애니메이션테스트");
|
|
||||||
if (deathSound) audioSource.PlayOneShot(deathSound);
|
if (deathSound) audioSource.PlayOneShot(deathSound);
|
||||||
|
|
||||||
Destroy(gameObject, 1.5f);
|
Destroy(gameObject, 1.5f);
|
||||||
|
|
@ -105,11 +141,7 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
|
|
||||||
private void TryDropItems()
|
private void TryDropItems()
|
||||||
{
|
{
|
||||||
if (potionPrefab != null && UnityEngine.Random.Range(0f, 100f) <= potionDropChance)
|
if (potionPrefab != null && UnityEngine.Random.Range(0f, 100f) <= potionDropChance) SpawnItem(potionPrefab);
|
||||||
{
|
|
||||||
SpawnItem(potionPrefab);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (weaponPrefabs != null && weaponPrefabs.Length > 0 && UnityEngine.Random.Range(0f, 100f) <= weaponDropChance)
|
if (weaponPrefabs != null && weaponPrefabs.Length > 0 && UnityEngine.Random.Range(0f, 100f) <= weaponDropChance)
|
||||||
{
|
{
|
||||||
int randomIndex = UnityEngine.Random.Range(0, weaponPrefabs.Length);
|
int randomIndex = UnityEngine.Random.Range(0, weaponPrefabs.Length);
|
||||||
|
|
@ -121,20 +153,13 @@ public class MonsterClass : MonoBehaviour, IDamageable
|
||||||
{
|
{
|
||||||
Vector3 spawnPos = transform.position + Vector3.up * 0.5f;
|
Vector3 spawnPos = transform.position + Vector3.up * 0.5f;
|
||||||
GameObject item = Instantiate(prefab, spawnPos, Quaternion.identity);
|
GameObject item = Instantiate(prefab, spawnPos, Quaternion.identity);
|
||||||
|
|
||||||
// ✅ [유저 요청] 배율 없이 프리팹의 원래 크기를 100% 그대로 적용
|
|
||||||
item.transform.localScale = prefab.transform.localScale;
|
item.transform.localScale = prefab.transform.localScale;
|
||||||
|
|
||||||
if (item.TryGetComponent<Rigidbody>(out var rb))
|
if (item.TryGetComponent<Rigidbody>(out var rb))
|
||||||
{
|
{
|
||||||
// 튀어오르는 힘은 유저님이 설정하신 0.02f 유지
|
|
||||||
Vector3 popDir = Vector3.up * 0.02f + UnityEngine.Random.insideUnitSphere * 0.02f;
|
Vector3 popDir = Vector3.up * 0.02f + UnityEngine.Random.insideUnitSphere * 0.02f;
|
||||||
rb.AddForce(popDir, ForceMode.Impulse);
|
rb.AddForce(popDir, ForceMode.Impulse);
|
||||||
|
if (prefab != potionPrefab) rb.AddTorque(UnityEngine.Random.insideUnitSphere * 0.3f, ForceMode.Impulse);
|
||||||
if (prefab != potionPrefab)
|
|
||||||
{
|
|
||||||
rb.AddTorque(UnityEngine.Random.insideUnitSphere * 0.3f, ForceMode.Impulse);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,10 @@ public class NormalMonster : MonsterClass
|
||||||
[SerializeField] private float damage = 10f;
|
[SerializeField] private float damage = 10f;
|
||||||
[SerializeField] private float attackRange = 2f;
|
[SerializeField] private float attackRange = 2f;
|
||||||
[SerializeField] private float attackDelay = 1.5f;
|
[SerializeField] private float attackDelay = 1.5f;
|
||||||
[SerializeField] private float postAttackDelay = 1.5f;
|
// [SerializeField] private float postAttackDelay = 1.5f; // ⭐ MonsterClass의 attackRestDuration을 사용하므로 삭제 권장
|
||||||
|
|
||||||
private float lastAttackTime;
|
private float lastAttackTime;
|
||||||
|
|
||||||
// ⭐ MonsterClass에 OnHealthChanged가 있으므로 여기서는 삭제합니다.
|
|
||||||
|
|
||||||
[Header("공격 애니메이션")]
|
[Header("공격 애니메이션")]
|
||||||
[SerializeField] private string[] attackAnimations = { "Monster_Attack_1" };
|
[SerializeField] private string[] attackAnimations = { "Monster_Attack_1" };
|
||||||
[Header("이동 애니메이션")]
|
[Header("이동 애니메이션")]
|
||||||
|
|
@ -33,12 +31,15 @@ public class NormalMonster : MonsterClass
|
||||||
|
|
||||||
private Transform player;
|
private Transform player;
|
||||||
private int attackIndex;
|
private int attackIndex;
|
||||||
private bool isAttacking;
|
|
||||||
|
// ❌ [삭제] bool isAttacking;
|
||||||
|
// ⭐ 부모(MonsterClass)에 이미 있으므로 자식에서 또 선언하면 에러가 납니다!
|
||||||
|
|
||||||
private bool isPlayerInZone;
|
private bool isPlayerInZone;
|
||||||
|
|
||||||
protected override void Start()
|
protected override void Start()
|
||||||
{
|
{
|
||||||
base.Start();
|
base.Start(); // 부모의 Start 실행
|
||||||
player = GameObject.FindWithTag("Player")?.transform;
|
player = GameObject.FindWithTag("Player")?.transform;
|
||||||
agent.stoppingDistance = attackRange - 0.4f;
|
agent.stoppingDistance = attackRange - 0.4f;
|
||||||
animator.applyRootMotion = false;
|
animator.applyRootMotion = false;
|
||||||
|
|
@ -46,13 +47,17 @@ public class NormalMonster : MonsterClass
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
|
// ⭐ 부모의 Update(이동 제한 로직)를 먼저 실행합니다.
|
||||||
|
base.Update();
|
||||||
|
|
||||||
if (isDead || player == null) return;
|
if (isDead || player == null) return;
|
||||||
|
|
||||||
// ⭐ CS0103 에러 해결: 아래 정의된 Patrol()을 호출
|
// 피격 중이거나 공격 중, 혹은 쉬는 중(isResting)에는 AI 로직을 타지 않습니다.
|
||||||
|
if (isHit || isAttacking || isResting) return;
|
||||||
|
|
||||||
if (isPlayerInZone) HandlePlayerTarget();
|
if (isPlayerInZone) HandlePlayerTarget();
|
||||||
else Patrol();
|
else Patrol();
|
||||||
|
|
||||||
// ⭐ CS0103 에러 해결: 아래 정의된 UpdateMovementAnimation()을 호출
|
|
||||||
UpdateMovementAnimation();
|
UpdateMovementAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,21 +65,12 @@ public class NormalMonster : MonsterClass
|
||||||
{
|
{
|
||||||
float distance = Vector3.Distance(transform.position, player.position);
|
float distance = Vector3.Distance(transform.position, player.position);
|
||||||
|
|
||||||
if (distance <= agent.stoppingDistance + 0.05f)
|
// 공격 범위 안에 들어왔을 때
|
||||||
{
|
|
||||||
agent.isStopped = true;
|
|
||||||
agent.velocity = Vector3.zero;
|
|
||||||
}
|
|
||||||
else if (!isAttacking)
|
|
||||||
{
|
|
||||||
agent.isStopped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance <= attackRange - stopBuffer)
|
if (distance <= attackRange - stopBuffer)
|
||||||
{
|
{
|
||||||
if (!isAttacking) TryAttack();
|
TryAttack();
|
||||||
}
|
}
|
||||||
else if (Time.time >= nextRepathTime && !isAttacking)
|
else if (Time.time >= nextRepathTime)
|
||||||
{
|
{
|
||||||
agent.SetDestination(player.position);
|
agent.SetDestination(player.position);
|
||||||
nextRepathTime = Time.time + repathInterval;
|
nextRepathTime = Time.time + repathInterval;
|
||||||
|
|
@ -89,41 +85,33 @@ public class NormalMonster : MonsterClass
|
||||||
string attackName = attackAnimations[attackIndex];
|
string attackName = attackAnimations[attackIndex];
|
||||||
attackIndex = (attackIndex + 1) % attackAnimations.Length;
|
attackIndex = (attackIndex + 1) % attackAnimations.Length;
|
||||||
|
|
||||||
isAttacking = true;
|
// ⭐ 부모의 OnAttackStart를 호출하여 isAttacking을 true로 만들고 이동을 멈춥니다.
|
||||||
agent.isStopped = true;
|
OnAttackStart();
|
||||||
agent.velocity = Vector3.zero;
|
|
||||||
animator.Play(attackName, 0, 0f);
|
animator.Play(attackName, 0, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐ CS0506 해결: 부모의 virtual 메서드를 정상적으로 재정의
|
// ⭐ [수정] 부모의 가상 메서드를 오버라이드합니다.
|
||||||
public override void TakeDamage(float amount)
|
public override void OnAttackStart()
|
||||||
{
|
{
|
||||||
base.TakeDamage(amount); // 부모의 OnDamaged(UI 신호 포함)를 실행
|
base.OnAttackStart(); // 부모의 isAttacking = true 로직 실행
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnAttackEnd()
|
// ⭐ [수정] 부모의 가상 메서드를 오버라이드하여 '휴식' 기능을 활성화합니다.
|
||||||
|
public override void OnAttackEnd()
|
||||||
{
|
{
|
||||||
StartCoroutine(PostAttackWait());
|
base.OnAttackEnd(); // 부모의 'n초간 휴식' 코루틴을 실행합니다!
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator PostAttackWait()
|
public void OnAttackHit() // 애니메이션 이벤트 (공격 판정 시점)
|
||||||
{
|
{
|
||||||
yield return new WaitForSeconds(postAttackDelay);
|
if (player == null || isHit || isDead) return;
|
||||||
isAttacking = false;
|
|
||||||
if (agent && agent.isOnNavMesh) agent.isStopped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAttackHit()
|
|
||||||
{
|
|
||||||
if (player == null) return;
|
|
||||||
PlayerHealth playerHealth = player.GetComponent<PlayerHealth>();
|
PlayerHealth playerHealth = player.GetComponent<PlayerHealth>();
|
||||||
if (playerHealth != null) playerHealth.TakeDamage(damage);
|
if (playerHealth != null) playerHealth.TakeDamage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐ 복구된 이동 애니메이션 함수
|
|
||||||
void UpdateMovementAnimation()
|
void UpdateMovementAnimation()
|
||||||
{
|
{
|
||||||
if (isAttacking || isHit) return;
|
if (isAttacking || isHit || isResting) return;
|
||||||
|
|
||||||
if (agent.velocity.magnitude < 0.1f)
|
if (agent.velocity.magnitude < 0.1f)
|
||||||
animator.Play(Monster_Idle);
|
animator.Play(Monster_Idle);
|
||||||
|
|
@ -131,7 +119,6 @@ public class NormalMonster : MonsterClass
|
||||||
animator.Play(Monster_Walk);
|
animator.Play(Monster_Walk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐ 복구된 순찰 함수
|
|
||||||
void Patrol()
|
void Patrol()
|
||||||
{
|
{
|
||||||
if (Time.time < nextPatrolTime) return;
|
if (Time.time < nextPatrolTime) return;
|
||||||
|
|
@ -155,11 +142,4 @@ public class NormalMonster : MonsterClass
|
||||||
{
|
{
|
||||||
if (other.CompareTag("Player")) isPlayerInZone = false;
|
if (other.CompareTag("Player")) isPlayerInZone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void StartHit()
|
|
||||||
{
|
|
||||||
isAttacking = false;
|
|
||||||
if (agent && agent.isOnNavMesh) agent.isStopped = false;
|
|
||||||
base.StartHit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user