- 부채꼴 가로 베기 - 직선 횡 베기 - 근접 원형 공격 - 원거리 폭탄
This commit is contained in:
parent
05bdaafce2
commit
9c03bfd00a
BIN
Assets/JYY/Animator/PldDogControl.controller
(Stored with Git LFS)
BIN
Assets/JYY/Animator/PldDogControl.controller
(Stored with Git LFS)
Binary file not shown.
8
Assets/JYY/Models.meta
Normal file
8
Assets/JYY/Models.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac3af37988877784e91ab90c4ade37d9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Models/Y Bot.fbx
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Models/Y Bot.fbx
(Stored with Git LFS)
Normal file
Binary file not shown.
109
Assets/JYY/Models/Y Bot.fbx.meta
Normal file
109
Assets/JYY/Models/Y Bot.fbx.meta
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: decb96f75d6a2344baa18f902f21a131
|
||||||
|
ModelImporter:
|
||||||
|
serializedVersion: 22200
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
materials:
|
||||||
|
materialImportMode: 2
|
||||||
|
materialName: 0
|
||||||
|
materialSearch: 1
|
||||||
|
materialLocation: 1
|
||||||
|
animations:
|
||||||
|
legacyGenerateAnimations: 4
|
||||||
|
bakeSimulation: 0
|
||||||
|
resampleCurves: 1
|
||||||
|
optimizeGameObjects: 0
|
||||||
|
removeConstantScaleCurves: 0
|
||||||
|
motionNodeName:
|
||||||
|
rigImportErrors:
|
||||||
|
rigImportWarnings:
|
||||||
|
animationImportErrors:
|
||||||
|
animationImportWarnings:
|
||||||
|
animationRetargetingWarnings:
|
||||||
|
animationDoRetargetingWarnings: 0
|
||||||
|
importAnimatedCustomProperties: 0
|
||||||
|
importConstraints: 0
|
||||||
|
animationCompression: 3
|
||||||
|
animationRotationError: 0.5
|
||||||
|
animationPositionError: 0.5
|
||||||
|
animationScaleError: 0.5
|
||||||
|
animationWrapMode: 0
|
||||||
|
extraExposedTransformPaths: []
|
||||||
|
extraUserProperties: []
|
||||||
|
clipAnimations: []
|
||||||
|
isReadable: 0
|
||||||
|
meshes:
|
||||||
|
lODScreenPercentages: []
|
||||||
|
globalScale: 1
|
||||||
|
meshCompression: 0
|
||||||
|
addColliders: 0
|
||||||
|
useSRGBMaterialColor: 1
|
||||||
|
sortHierarchyByName: 1
|
||||||
|
importPhysicalCameras: 1
|
||||||
|
importVisibility: 1
|
||||||
|
importBlendShapes: 1
|
||||||
|
importCameras: 1
|
||||||
|
importLights: 1
|
||||||
|
nodeNameCollisionStrategy: 1
|
||||||
|
fileIdsGeneration: 2
|
||||||
|
swapUVChannels: 0
|
||||||
|
generateSecondaryUV: 0
|
||||||
|
useFileUnits: 1
|
||||||
|
keepQuads: 0
|
||||||
|
weldVertices: 1
|
||||||
|
bakeAxisConversion: 0
|
||||||
|
preserveHierarchy: 0
|
||||||
|
skinWeightsMode: 0
|
||||||
|
maxBonesPerVertex: 4
|
||||||
|
minBoneWeight: 0.001
|
||||||
|
optimizeBones: 1
|
||||||
|
meshOptimizationFlags: -1
|
||||||
|
indexFormat: 0
|
||||||
|
secondaryUVAngleDistortion: 8
|
||||||
|
secondaryUVAreaDistortion: 15.000001
|
||||||
|
secondaryUVHardAngle: 88
|
||||||
|
secondaryUVMarginMethod: 1
|
||||||
|
secondaryUVMinLightmapResolution: 40
|
||||||
|
secondaryUVMinObjectScale: 1
|
||||||
|
secondaryUVPackMargin: 4
|
||||||
|
useFileScale: 1
|
||||||
|
strictVertexDataChecks: 0
|
||||||
|
tangentSpace:
|
||||||
|
normalSmoothAngle: 60
|
||||||
|
normalImportMode: 0
|
||||||
|
tangentImportMode: 3
|
||||||
|
normalCalculationMode: 4
|
||||||
|
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||||
|
blendShapeNormalImportMode: 1
|
||||||
|
normalSmoothingSource: 0
|
||||||
|
referencedClips: []
|
||||||
|
importAnimation: 1
|
||||||
|
humanDescription:
|
||||||
|
serializedVersion: 3
|
||||||
|
human: []
|
||||||
|
skeleton: []
|
||||||
|
armTwist: 0.5
|
||||||
|
foreArmTwist: 0.5
|
||||||
|
upperLegTwist: 0.5
|
||||||
|
legTwist: 0.5
|
||||||
|
armStretch: 0.05
|
||||||
|
legStretch: 0.05
|
||||||
|
feetSpacing: 0
|
||||||
|
globalScale: 1
|
||||||
|
rootMotionBoneName:
|
||||||
|
hasTranslationDoF: 0
|
||||||
|
hasExtraRoot: 1
|
||||||
|
skeletonHasParents: 1
|
||||||
|
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||||
|
autoGenerateAvatarMappingIfUnspecified: 1
|
||||||
|
animationType: 3
|
||||||
|
humanoidOversampling: 1
|
||||||
|
avatarSetup: 1
|
||||||
|
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||||
|
importBlendShapeDeformPercent: 1
|
||||||
|
remapMaterialsIfMaterialImportModeIsNone: 0
|
||||||
|
additionalBone: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Prefabs/AoE Indicator Chariot.prefab
(Stored with Git LFS)
BIN
Assets/JYY/Prefabs/AoE Indicator Chariot.prefab
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Assets/JYY/Prefabs/AoE Indicator Vertical.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/AoE Indicator Vertical.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Assets/JYY/Prefabs/Charge slash red.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/Charge slash red.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/JYY/Prefabs/Charge slash red.prefab.meta
Normal file
7
Assets/JYY/Prefabs/Charge slash red.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a0ddc8dd6d760e4e93999c4d49dc16c
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Prefabs/Explosion.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/Explosion.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/JYY/Prefabs/Explosion.prefab.meta
Normal file
7
Assets/JYY/Prefabs/Explosion.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ccd5acc2f6d74d4bb687fd2ee94b9de
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Prefabs/Red energy explosion 1.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/Red energy explosion 1.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/JYY/Prefabs/Red energy explosion 1.prefab.meta
Normal file
7
Assets/JYY/Prefabs/Red energy explosion 1.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 49ada3fea2be23f4a988d4bc21dcaa32
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Prefabs/Snow slash 1.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/JYY/Prefabs/Snow slash 1.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/JYY/Prefabs/Snow slash 1.prefab.meta
Normal file
7
Assets/JYY/Prefabs/Snow slash 1.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 03a874e2d684ee04a9729b8363fdbb9c
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/JYY/Scenes/MonsterTest.unity
(Stored with Git LFS)
BIN
Assets/JYY/Scenes/MonsterTest.unity
(Stored with Git LFS)
Binary file not shown.
109
Assets/Scripts/Character/Enemy/BossPattern/AoeControllerBase.cs
Normal file
109
Assets/Scripts/Character/Enemy/BossPattern/AoeControllerBase.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct DamageEffectData
|
||||||
|
{
|
||||||
|
public int damage;
|
||||||
|
public float radius;
|
||||||
|
public float delay;
|
||||||
|
public LayerMask targetLayer;
|
||||||
|
public GameObject explosionEffectPrefab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AOE 범위 공격의 공통 로직을 처리하는 추상 베이스 클래스입니다.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class AoeControllerBase : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("경고 이펙트")]
|
||||||
|
[SerializeField] protected GameObject warningEffectInstance;
|
||||||
|
|
||||||
|
protected DamageEffectData _data;
|
||||||
|
private Action _slashAction;
|
||||||
|
private Action _destroyAction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 범위 공격 이펙트를 설정하고, 딜레이 후 폭발을 실행합니다.
|
||||||
|
/// </summary>
|
||||||
|
public void SetEffect(DamageEffectData data, Action slashAction, Action destroyAction)
|
||||||
|
{
|
||||||
|
_data = data;
|
||||||
|
_slashAction = slashAction;
|
||||||
|
_destroyAction = destroyAction;
|
||||||
|
|
||||||
|
ShowWarningEffect();
|
||||||
|
StartCoroutine(ExplodeAfterDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ShowWarningEffect()
|
||||||
|
{
|
||||||
|
if (warningEffectInstance != null)
|
||||||
|
warningEffectInstance.SetActive(true);
|
||||||
|
|
||||||
|
float diameter = _data.radius * 2f;
|
||||||
|
transform.localScale = new Vector3(diameter, 1f, diameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator ExplodeAfterDelay()
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(_data.delay);
|
||||||
|
Explode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 폭발 이펙트 생성, 데미지 처리, 콜백 호출 순서로 실행합니다.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void Explode()
|
||||||
|
{
|
||||||
|
// 경고 이펙트 숨기기
|
||||||
|
if (warningEffectInstance != null)
|
||||||
|
warningEffectInstance.SetActive(false);
|
||||||
|
|
||||||
|
ShowDamageEffect();
|
||||||
|
|
||||||
|
// 슬래시 액션(애니메이션 트리거) 호출
|
||||||
|
_slashAction?.Invoke();
|
||||||
|
|
||||||
|
// 범위 내 데미지 처리
|
||||||
|
HitCheck();
|
||||||
|
|
||||||
|
// 패턴 클리어 콜백
|
||||||
|
_destroyAction?.Invoke();
|
||||||
|
|
||||||
|
// 자기 자신 제거
|
||||||
|
Destroy(gameObject, 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void HitCheck()
|
||||||
|
{
|
||||||
|
var hits = Physics.OverlapSphere(transform.position, _data.radius, _data.targetLayer);
|
||||||
|
foreach (var hit in hits)
|
||||||
|
{
|
||||||
|
if (hit.CompareTag("Player"))
|
||||||
|
{
|
||||||
|
Debug.Log($"{hit.name}에게 {_data.damage} 데미지 적용");
|
||||||
|
// TODO: 실제 데미지 처리 로직 호출
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ShowDamageEffect()
|
||||||
|
{
|
||||||
|
// 폭발 이펙트 생성
|
||||||
|
if (_data.explosionEffectPrefab != null)
|
||||||
|
{
|
||||||
|
var effect = Instantiate(_data.explosionEffectPrefab, transform.position, transform.rotation);
|
||||||
|
effect.transform.localScale = new Vector3(_data.radius, _data.radius, _data.radius);
|
||||||
|
Destroy(effect, 2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Gizmos.DrawWireSphere(transform.position, _data.radius);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1dd40dca214a4038be21f64ce645e5d9
|
||||||
|
timeCreated: 1745393630
|
@ -0,0 +1,4 @@
|
|||||||
|
public class BoomAoeController : AoeControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e32c2002701d49df83faa36b3da55436
|
||||||
|
timeCreated: 1745395178
|
@ -1,85 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct DamageEffectData
|
public class ChariotAoeController : AoeControllerBase
|
||||||
{
|
{
|
||||||
public int damage;
|
protected override void ShowDamageEffect()
|
||||||
public float radius;
|
|
||||||
public float delay;
|
|
||||||
public LayerMask targetLayer;
|
|
||||||
|
|
||||||
public GameObject explosionEffectPrefab;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChariotAoeController : MonoBehaviour
|
|
||||||
{
|
|
||||||
[SerializeField] private GameObject warningEffectInstance;
|
|
||||||
|
|
||||||
private DamageEffectData _data;
|
|
||||||
private Action _destroyAction;
|
|
||||||
private Action _slashAction;
|
|
||||||
|
|
||||||
public void SetEffect(DamageEffectData data, Action slashAction, Action destroyAction)
|
|
||||||
{
|
{
|
||||||
_data = data;
|
// 폭발 이펙트 생성
|
||||||
_slashAction = slashAction;
|
if (_data.explosionEffectPrefab != null)
|
||||||
_destroyAction = destroyAction;
|
|
||||||
|
|
||||||
ShowWarningEffect();
|
|
||||||
Invoke(nameof(Explode), _data.delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowWarningEffect()
|
|
||||||
{
|
|
||||||
warningEffectInstance.SetActive(true);
|
|
||||||
float diameter = _data.radius * 2f;
|
|
||||||
gameObject.transform.localScale = new Vector3(diameter, 1f, diameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Explode()
|
|
||||||
{
|
|
||||||
var effect = Instantiate(_data.explosionEffectPrefab, transform.position, Quaternion.identity);
|
|
||||||
|
|
||||||
// 공격 전조 제거
|
|
||||||
warningEffectInstance.SetActive(false);
|
|
||||||
|
|
||||||
// 공격 애니메이션 실행
|
|
||||||
_slashAction.Invoke();
|
|
||||||
|
|
||||||
effect.transform.localScale = new Vector3(_data.radius, _data.radius, _data.radius);
|
|
||||||
|
|
||||||
// 폭발 반경 내의 모든 콜라이더 가져오기
|
|
||||||
Collider[] hitColliders = Physics.OverlapSphere(transform.position, _data.radius, _data.targetLayer);
|
|
||||||
foreach (Collider hit in hitColliders)
|
|
||||||
{
|
{
|
||||||
if (hit.CompareTag("Player"))
|
var effect = Instantiate(_data.explosionEffectPrefab, transform.position, transform.rotation);
|
||||||
{
|
effect.transform.localScale = new Vector3(2f, 2f, 2f);
|
||||||
// TODO : 데미지 부여
|
Destroy(effect, 2f);
|
||||||
Debug.Log(hit.name +"에게 공격 적중");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit(effect);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void Exit(GameObject effect)
|
|
||||||
{
|
|
||||||
Destroy(effect, 2f);
|
|
||||||
Destroy(gameObject, 2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
_destroyAction.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDrawGizmosSelected()
|
|
||||||
{
|
|
||||||
Gizmos.color = Color.red;
|
|
||||||
Gizmos.DrawWireSphere(transform.position, _data.radius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class HorizontalAoeController : AoeControllerBase
|
||||||
|
{
|
||||||
|
private float slashAngle = 270f;
|
||||||
|
private int gizmoSegments = 20;
|
||||||
|
protected override void HitCheck()
|
||||||
|
{
|
||||||
|
var hits = Physics.OverlapSphere(transform.position, _data.radius, _data.targetLayer);
|
||||||
|
foreach (var hit in hits)
|
||||||
|
{
|
||||||
|
if (!hit.CompareTag("Player")) continue;
|
||||||
|
|
||||||
|
Vector3 dir = hit.transform.position - transform.position;
|
||||||
|
dir.y = 0;
|
||||||
|
float angleToForward = Vector3.Angle(transform.forward, dir);
|
||||||
|
|
||||||
|
if (angleToForward <= slashAngle * 0.5f)
|
||||||
|
{
|
||||||
|
Debug.Log($"{hit.name}이(가) 횡적 슬래시 데미지 범위에 있습니다.");
|
||||||
|
Debug.Log($"{hit.name}에게 {_data.damage} 데미지 적용");
|
||||||
|
// TODO: 실제 데미지 처리 로직 호출
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
// 부채꼴 형태 기즈모 드로잉
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Vector3 origin = transform.position;
|
||||||
|
float halfAngle = slashAngle * 0.5f;
|
||||||
|
float step = slashAngle / gizmoSegments;
|
||||||
|
|
||||||
|
// 시작 포인트
|
||||||
|
Vector3 prevDir = Quaternion.AngleAxis(-halfAngle, Vector3.up) * transform.forward;
|
||||||
|
Vector3 prevPoint = origin + prevDir.normalized * _data.radius;
|
||||||
|
Gizmos.DrawLine(origin, prevPoint);
|
||||||
|
|
||||||
|
for (int i = 1; i <= gizmoSegments; i++)
|
||||||
|
{
|
||||||
|
float currentAngle = -halfAngle + step * i;
|
||||||
|
Vector3 currDir = Quaternion.AngleAxis(currentAngle, Vector3.up) * transform.forward;
|
||||||
|
Vector3 currPoint = origin + currDir.normalized * _data.radius;
|
||||||
|
Gizmos.DrawLine(prevPoint, currPoint);
|
||||||
|
prevPoint = currPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 마지막 라인
|
||||||
|
Gizmos.DrawLine(origin, prevPoint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e77da766410d47f9a7effebd30fd33f6
|
||||||
|
timeCreated: 1745394588
|
@ -0,0 +1,51 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class VerticalAoeController : AoeControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
protected override void ShowWarningEffect()
|
||||||
|
{
|
||||||
|
if (warningEffectInstance != null)
|
||||||
|
warningEffectInstance.SetActive(true);
|
||||||
|
|
||||||
|
var centerCap = Vector3.forward * _data.radius;
|
||||||
|
float diameter = _data.radius * 2f;
|
||||||
|
transform.localScale = new Vector3(_data.radius, 1f, diameter);
|
||||||
|
transform.Translate(centerCap, Space.Self);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ShowDamageEffect()
|
||||||
|
{
|
||||||
|
// 폭발 이펙트 생성
|
||||||
|
if (_data.explosionEffectPrefab != null)
|
||||||
|
{
|
||||||
|
var effect = Instantiate(_data.explosionEffectPrefab, transform.position, transform.rotation);
|
||||||
|
effect.transform.localScale = new Vector3(_data.radius, _data.radius, _data.radius);
|
||||||
|
Destroy(effect, 2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void HitCheck()
|
||||||
|
{
|
||||||
|
// 박스 판정 (사각형 직선)
|
||||||
|
Vector3 halfExtents = new Vector3(_data.radius, 1f, _data.radius * 2f);
|
||||||
|
Collider[] hits = Physics.OverlapBox(transform.position, halfExtents, transform.rotation, _data.targetLayer);
|
||||||
|
|
||||||
|
foreach (var hit in hits)
|
||||||
|
{
|
||||||
|
if (!hit.CompareTag("Player")) continue;
|
||||||
|
Debug.Log($"{hit.name} 사각형 범위에 있어 데미지 적용");
|
||||||
|
// TODO: 데미지 로직
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Vector3 center = transform.position;
|
||||||
|
Vector3 size = new Vector3(_data.radius, 1f, _data.radius * 2f);
|
||||||
|
Gizmos.matrix = Matrix4x4.TRS(center, transform.rotation, Vector3.one);
|
||||||
|
Gizmos.DrawWireCube(Vector3.zero, size);
|
||||||
|
Gizmos.matrix = Matrix4x4.identity;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8eb40ee5f0d943469026d2b6522dbe46
|
||||||
|
timeCreated: 1745393484
|
@ -18,6 +18,16 @@ public abstract class EnemyController : CharacterBase
|
|||||||
public EnemyState CurrentState {get; private set;}
|
public EnemyState CurrentState {get; private set;}
|
||||||
public LayerMask TargetLayerMask => targetLayerMask;
|
public LayerMask TargetLayerMask => targetLayerMask;
|
||||||
public float MoveSpeed => moveSpeed;
|
public float MoveSpeed => moveSpeed;
|
||||||
|
public bool IsMeleeCombat { get; protected set; }
|
||||||
|
|
||||||
|
// -----
|
||||||
|
// 애니메이션 관련
|
||||||
|
private int _currentAnimationTrigger = -1;
|
||||||
|
|
||||||
|
// 애니메이션 파라미터 해시값
|
||||||
|
public static readonly int Idle = Animator.StringToHash("Idle");
|
||||||
|
public static readonly int Dead = Animator.StringToHash("Dead");
|
||||||
|
public static readonly int Trace = Animator.StringToHash("Trace");
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
// 상태 변수
|
// 상태 변수
|
||||||
@ -55,7 +65,7 @@ public abstract class EnemyController : CharacterBase
|
|||||||
SetState(EnemyState.Idle);
|
SetState(EnemyState.Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Update()
|
protected virtual void Update()
|
||||||
{
|
{
|
||||||
if (CurrentState != EnemyState.None)
|
if (CurrentState != EnemyState.None)
|
||||||
{
|
{
|
||||||
@ -98,5 +108,38 @@ public abstract class EnemyController : CharacterBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 애니메이션 제어
|
||||||
|
|
||||||
|
// Trigger
|
||||||
|
public void SetAnimation(int hashName)
|
||||||
|
{
|
||||||
|
if (_currentAnimationTrigger != -1)
|
||||||
|
{
|
||||||
|
EnemyAnimator.ResetTrigger(_currentAnimationTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnemyAnimator.SetTrigger(hashName);
|
||||||
|
_currentAnimationTrigger = hashName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool
|
||||||
|
public void SetAnimation(int hashName, bool value)
|
||||||
|
{
|
||||||
|
EnemyAnimator.SetBool(hashName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float
|
||||||
|
public void SetAnimation(int hashName, float value)
|
||||||
|
{
|
||||||
|
EnemyAnimator.SetFloat(hashName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integer
|
||||||
|
public void SetAnimation(int hashName, int value)
|
||||||
|
{
|
||||||
|
EnemyAnimator.SetInteger(hashName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,11 @@ using UnityEngine;
|
|||||||
public class EnemyStateAttack : IEnemyState
|
public class EnemyStateAttack : IEnemyState
|
||||||
{
|
{
|
||||||
private EnemyController _enemyController;
|
private EnemyController _enemyController;
|
||||||
private Animator _animator;
|
|
||||||
|
|
||||||
public void Enter(EnemyController enemyController)
|
public void Enter(EnemyController enemyController)
|
||||||
{
|
{
|
||||||
_enemyController = enemyController;
|
_enemyController = enemyController;
|
||||||
_animator = _enemyController.EnemyAnimator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@ -20,7 +19,6 @@ public class EnemyStateAttack : IEnemyState
|
|||||||
|
|
||||||
public void Exit()
|
public void Exit()
|
||||||
{
|
{
|
||||||
_animator = null;
|
|
||||||
_enemyController = null;
|
_enemyController = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
public void Enter(EnemyController enemyController)
|
public void Enter(EnemyController enemyController)
|
||||||
{
|
{
|
||||||
_enemyController = enemyController;
|
_enemyController = enemyController;
|
||||||
_enemyController.EnemyAnimator.SetTrigger("Dead");
|
_enemyController.SetAnimation(EnemyController.Dead);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
public class EnemyStateIdle: IEnemyState
|
public class EnemyStateIdle: IEnemyState
|
||||||
{
|
{
|
||||||
private static readonly int Idle = Animator.StringToHash("Idle");
|
|
||||||
private EnemyController _enemyController;
|
private EnemyController _enemyController;
|
||||||
|
|
||||||
public void Enter(EnemyController enemyController)
|
public void Enter(EnemyController enemyController)
|
||||||
{
|
{
|
||||||
_enemyController = enemyController;
|
_enemyController = enemyController;
|
||||||
_enemyController.EnemyAnimator.SetBool(Idle, true);
|
Debug.Log("## Idle 상태 진입");
|
||||||
|
_enemyController.SetAnimation(EnemyController.Idle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@ -22,7 +23,7 @@ public class EnemyStateIdle: IEnemyState
|
|||||||
|
|
||||||
public void Exit()
|
public void Exit()
|
||||||
{
|
{
|
||||||
_enemyController.EnemyAnimator.SetBool(Idle, false);
|
_enemyController.SetAnimation(EnemyController.Idle, false);
|
||||||
_enemyController = null;
|
_enemyController = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
public class EnemyStateTrace : IEnemyState
|
public class EnemyStateTrace : IEnemyState
|
||||||
{
|
{
|
||||||
private static readonly int MoveSpeed = Animator.StringToHash("MoveSpeed");
|
|
||||||
private static readonly int Trace = Animator.StringToHash("Trace");
|
|
||||||
|
|
||||||
private EnemyController _enemyController;
|
private EnemyController _enemyController;
|
||||||
private Transform _detectPlayerTransform;
|
private Transform _detectPlayerTransform;
|
||||||
|
|
||||||
@ -14,7 +11,7 @@ public class EnemyStateTrace : IEnemyState
|
|||||||
public void Enter(EnemyController enemyController)
|
public void Enter(EnemyController enemyController)
|
||||||
{
|
{
|
||||||
_enemyController = enemyController;
|
_enemyController = enemyController;
|
||||||
|
Debug.Log("## Trace 상태 진입");
|
||||||
_detectPlayerTransform = _enemyController.TraceTargetTransform;
|
_detectPlayerTransform = _enemyController.TraceTargetTransform;
|
||||||
if (!_detectPlayerTransform)
|
if (!_detectPlayerTransform)
|
||||||
{
|
{
|
||||||
@ -28,25 +25,31 @@ public class EnemyStateTrace : IEnemyState
|
|||||||
_enemyController.Agent.SetDestination(_detectPlayerTransform.position);
|
_enemyController.Agent.SetDestination(_detectPlayerTransform.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
_enemyController.EnemyAnimator.SetBool(Trace, true);
|
_enemyController.SetAnimation(EnemyController.Trace, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
|
if(_enemyController.IsMeleeCombat) return;
|
||||||
if (_enemyController.Agent.enabled != true) return;
|
if (_enemyController.Agent.enabled != true) return;
|
||||||
|
|
||||||
// 일정 주기로 찾은 플레이어의 위치를 갱신해서 갱신된 위치로 이동
|
|
||||||
FindTargetPosition();
|
|
||||||
|
|
||||||
PlayerTracking();
|
PlayerTracking();
|
||||||
|
|
||||||
if (_enemyController.Agent.remainingDistance <= _enemyController.Agent.stoppingDistance)
|
if (_enemyController.Agent.remainingDistance <= _enemyController.Agent.stoppingDistance)
|
||||||
{
|
{
|
||||||
// TODO: 타겟에 도착함 -> 공격 준비
|
// TODO: 타겟에 도착함 -> 공격 준비
|
||||||
_enemyController.SetState(EnemyState.Attack);
|
// _enemyController.SetState(EnemyState.Attack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Exit()
|
||||||
|
{
|
||||||
|
_detectPlayerTransform = null;
|
||||||
|
_enemyController.SetAnimation(EnemyController.Trace, false);
|
||||||
|
_enemyController = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 일정 주기로 찾은 플레이어의 위치를 갱신해서 갱신된 위치로 이동
|
||||||
private void FindTargetPosition()
|
private void FindTargetPosition()
|
||||||
{
|
{
|
||||||
if (_detectPlayerInCircleWaitTime > MaxDetectPlayerInCircleWaitTime)
|
if (_detectPlayerInCircleWaitTime > MaxDetectPlayerInCircleWaitTime)
|
||||||
@ -68,6 +71,8 @@ public class EnemyStateTrace : IEnemyState
|
|||||||
// 플레이어를 추적하는 속도를 제어하는 함수
|
// 플레이어를 추적하는 속도를 제어하는 함수
|
||||||
private void PlayerTracking()
|
private void PlayerTracking()
|
||||||
{
|
{
|
||||||
|
FindTargetPosition();
|
||||||
|
|
||||||
float distance = (_detectPlayerTransform.position - _enemyController.transform.position).magnitude;
|
float distance = (_detectPlayerTransform.position - _enemyController.transform.position).magnitude;
|
||||||
|
|
||||||
if (distance > 2f)
|
if (distance > 2f)
|
||||||
@ -97,17 +102,6 @@ public class EnemyStateTrace : IEnemyState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 실제 속도 기반으로 애니메이션 제어
|
|
||||||
float currentSpeed = _enemyController.Agent.velocity.magnitude;
|
|
||||||
_enemyController.EnemyAnimator.SetFloat(MoveSpeed, currentSpeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Exit()
|
|
||||||
{
|
|
||||||
_detectPlayerTransform = null;
|
|
||||||
_enemyController.EnemyAnimator.SetBool(Trace, false);
|
|
||||||
_enemyController = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,30 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Unity.VisualScripting;
|
using Unity.VisualScripting;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
using Random = UnityEngine.Random;
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
public class PldDogController : EnemyController
|
public class PldDogController : EnemyController
|
||||||
{
|
{
|
||||||
private static readonly int WindUp = Animator.StringToHash("WindUp");
|
private static readonly int WindUp = Animator.StringToHash("WindUp");
|
||||||
private static readonly int VertiSlash = Animator.StringToHash("VertiSlash");
|
private static readonly int Slash = Animator.StringToHash("Slash");
|
||||||
|
private static readonly int BoomShot = Animator.StringToHash("BoomShot");
|
||||||
|
|
||||||
[Header("공격 패턴 관련")]
|
[Header("공격 패턴 관련")]
|
||||||
[SerializeField] private float patternInterval = 3f;
|
[SerializeField] private float patternInterval = 3f;
|
||||||
|
[SerializeField] private float meleeRange = 2f;
|
||||||
|
[SerializeField] private float bombTriggerDelay = 1.5f;
|
||||||
|
|
||||||
private float _patternTimer = 0f;
|
[Header("폭탄 패턴 설정")]
|
||||||
private int _currentPatternIndex = 0;
|
[SerializeField] private int bombCount = 1;
|
||||||
private bool _isPatternRunning = false;
|
[SerializeField] private Vector3 bombScale = new Vector3(5f, 5f, 5f);
|
||||||
|
|
||||||
[Header("각종 데미지 이펙트 세트")]
|
[Header("각종 데미지 이펙트 세트")]
|
||||||
[SerializeField] private GameObject chariotSlashWarning;
|
[SerializeField] private GameObject chariotSlashWarning;
|
||||||
[SerializeField] private GameObject chariotSlash;
|
[SerializeField] private GameObject chariotSlash;
|
||||||
|
[SerializeField] private GameObject boomExplosion;
|
||||||
|
|
||||||
[Space(10)]
|
[Space(10)]
|
||||||
[SerializeField] private GameObject verticalWarning;
|
[SerializeField] private GameObject verticalWarning;
|
||||||
@ -28,127 +34,109 @@ public class PldDogController : EnemyController
|
|||||||
[SerializeField] private GameObject horizontalWarning;
|
[SerializeField] private GameObject horizontalWarning;
|
||||||
[SerializeField] private GameObject horizontalSlash;
|
[SerializeField] private GameObject horizontalSlash;
|
||||||
|
|
||||||
private bool _isInTrace;
|
private float _patternTimer = 0f;
|
||||||
private bool _isInAttack;
|
private int _currentPatternIndex = 0;
|
||||||
|
private bool _isPatternRunning = false;
|
||||||
private bool _isFirstAttack = true;
|
private bool _isFirstAttack = true;
|
||||||
|
|
||||||
private void Update()
|
private List<Action> _patternActions;
|
||||||
|
|
||||||
|
protected override void Awake()
|
||||||
|
{
|
||||||
|
base.Awake();
|
||||||
|
|
||||||
|
_patternActions = new List<Action>
|
||||||
|
{
|
||||||
|
ChariotSlashPattern,
|
||||||
|
VerticalSlashPattern,
|
||||||
|
HorizontalSlashPattern
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
CheckIsInBattle();
|
if (CurrentState != EnemyState.Trace || _isPatternRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_isInAttack)
|
float distanceToPlayer = Vector3.Distance(transform.position, TraceTargetTransform.position);
|
||||||
|
|
||||||
|
if (distanceToPlayer <= meleeRange) // 근접 범위
|
||||||
{
|
{
|
||||||
|
if (!Agent.isStopped) Agent.isStopped = true;
|
||||||
_patternTimer += Time.deltaTime;
|
_patternTimer += Time.deltaTime;
|
||||||
|
|
||||||
if (!_isPatternRunning && (_isFirstAttack || _patternTimer >= patternInterval))
|
if (!_isPatternRunning && (_isFirstAttack || _patternTimer >= patternInterval))
|
||||||
{
|
{
|
||||||
Agent.enabled = false;
|
|
||||||
|
|
||||||
// TODO: 순서대로 패턴 실행
|
|
||||||
ExecutePattern(_currentPatternIndex);
|
ExecutePattern(_currentPatternIndex);
|
||||||
|
|
||||||
// _currentPatternIndex = (_currentPatternIndex + 1) % 3; // 패턴 순환
|
|
||||||
|
|
||||||
_isFirstAttack = false;
|
_isFirstAttack = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (_isInTrace)
|
|
||||||
{
|
{
|
||||||
|
if (Agent.isStopped) Agent.isStopped = false;
|
||||||
|
Agent.SetDestination(TraceTargetTransform.position);
|
||||||
_patternTimer += Time.deltaTime;
|
_patternTimer += Time.deltaTime;
|
||||||
|
|
||||||
if (!_isPatternRunning && _patternTimer >= patternInterval)
|
if (!_isPatternRunning && _patternTimer >= patternInterval)
|
||||||
{
|
{
|
||||||
_isPatternRunning = true;
|
BombThrowPattern();
|
||||||
|
|
||||||
float distanceToPlayer = Vector3.Distance(transform.position, TraceTargetTransform.position);
|
|
||||||
|
|
||||||
if (distanceToPlayer > 3f)
|
|
||||||
{
|
|
||||||
BombThrowPattern();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckIsInBattle()
|
|
||||||
{
|
|
||||||
switch (CurrentState)
|
|
||||||
{
|
|
||||||
case EnemyState.Attack:
|
|
||||||
_isInAttack = true;
|
|
||||||
_isInTrace = false;
|
|
||||||
break;
|
|
||||||
case EnemyState.Trace:
|
|
||||||
_isInTrace = true;
|
|
||||||
_isInAttack = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExecutePattern(int patternIndex)
|
private void ExecutePattern(int patternIndex)
|
||||||
{
|
{
|
||||||
_isPatternRunning = true;
|
_isPatternRunning = true;
|
||||||
|
Agent.isStopped = true;
|
||||||
|
IsMeleeCombat = true;
|
||||||
|
|
||||||
switch (patternIndex)
|
_patternActions[_currentPatternIndex]?.Invoke();
|
||||||
{
|
|
||||||
case 0:
|
_currentPatternIndex = (_currentPatternIndex + 1) % _patternActions.Count; // 패턴 순환
|
||||||
{
|
|
||||||
ChariotSlashPattern();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 순환 패턴과 별개로 동작하는 특수 패턴
|
||||||
private void BombThrowPattern()
|
private void BombThrowPattern()
|
||||||
{
|
{
|
||||||
Debug.Log("BombThrowPattern: 보스가 폭탄을 던집니다.");
|
Debug.Log("BombThrowPattern: 보스가 폭탄을 던집니다.");
|
||||||
|
SetAnimation(BoomShot);
|
||||||
int bombCount = 1; // 한 번에 몇 개 던질지
|
_isPatternRunning = true;
|
||||||
float radius = 2f; // 무작위로 던질 경우 범위
|
Agent.isStopped = true;
|
||||||
|
|
||||||
for (int i = 0; i < bombCount; i++)
|
for (int i = 0; i < bombCount; i++)
|
||||||
{
|
{
|
||||||
// Vector3 randomPos = TraceTargetTransform.position + (Random.insideUnitSphere * radius);
|
|
||||||
Vector3 targetPos = TraceTargetTransform.position;
|
Vector3 targetPos = TraceTargetTransform.position;
|
||||||
targetPos.y = 0.1f; // 지면에 맞추기
|
targetPos.y = 0.1f; // 지면에 맞춤
|
||||||
|
|
||||||
var boomObj = Instantiate(chariotSlashWarning, targetPos, Quaternion.identity);
|
var warning = Instantiate(chariotSlashWarning, targetPos, Quaternion.identity);
|
||||||
boomObj.transform.localScale = new Vector3(5f, 5f, 5f); // TODO : 하드 코딩됨 | 개선... 해야겠지??
|
warning.transform.localScale = bombScale;
|
||||||
var boom = boomObj.GetComponent<ChariotAoeController>();
|
var aoe = warning.GetComponent<BoomAoeController>();
|
||||||
|
|
||||||
DamageEffectData effectData = new DamageEffectData()
|
var effectData = new DamageEffectData
|
||||||
{
|
{
|
||||||
damage = (int)attackPower,
|
damage = (int)attackPower,
|
||||||
radius = 5f,
|
radius = bombScale.x,
|
||||||
delay = 1.5f,
|
delay = bombTriggerDelay,
|
||||||
targetLayer = TargetLayerMask,
|
targetLayer = TargetLayerMask,
|
||||||
explosionEffectPrefab = chariotSlash
|
explosionEffectPrefab = boomExplosion
|
||||||
};
|
};
|
||||||
|
|
||||||
boom.SetEffect(effectData, ()=>{ }, PatternClear);
|
aoe.SetEffect(effectData, null, PatternClear);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChariotSlashPattern()
|
private void ChariotSlashPattern()
|
||||||
{
|
{
|
||||||
Debug.Log("ChariotSlashPattern: 보스가 차지 슬래시를 사용합니다.");
|
Debug.Log("ChariotSlashPattern: 보스가 차지 슬래시를 사용합니다.");
|
||||||
WindUpAnimationStart();
|
WindUpAnimation();
|
||||||
|
|
||||||
var slash = Instantiate(chariotSlashWarning, transform.position, Quaternion.identity)
|
var warning = Instantiate(chariotSlashWarning, transform.position, Quaternion.identity)
|
||||||
.GetComponent<ChariotAoeController>();
|
.GetComponent<ChariotAoeController>();
|
||||||
|
|
||||||
DamageEffectData effectData = new DamageEffectData()
|
var effectData = new DamageEffectData
|
||||||
{
|
{
|
||||||
damage = (int)attackPower,
|
damage = (int)attackPower,
|
||||||
radius = 7.5f,
|
radius = 7.5f,
|
||||||
@ -157,35 +145,64 @@ public class PldDogController : EnemyController
|
|||||||
explosionEffectPrefab = chariotSlash
|
explosionEffectPrefab = chariotSlash
|
||||||
};
|
};
|
||||||
|
|
||||||
slash.SetEffect(effectData, SlashAnimationPlay,
|
warning.SetEffect(effectData, SlashAnimationPlay, PatternClear);
|
||||||
() =>
|
|
||||||
{
|
|
||||||
PatternClear();
|
|
||||||
WindUpAnimationEnd();
|
|
||||||
SetState(EnemyState.Trace);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindUpAnimationStart()
|
private void VerticalSlashPattern()
|
||||||
{
|
{
|
||||||
EnemyAnimator.SetBool(WindUp, true);
|
Debug.Log("VerticalSlashPattern: 보스가 수직 슬래시를 사용합니다.");
|
||||||
|
WindUpAnimation();
|
||||||
|
|
||||||
|
var warning = Instantiate(verticalWarning, transform.position, transform.rotation)
|
||||||
|
.GetComponent<VerticalAoeController>();
|
||||||
|
|
||||||
|
var effectData = new DamageEffectData
|
||||||
|
{
|
||||||
|
damage = (int)attackPower,
|
||||||
|
radius = 5f,
|
||||||
|
delay = 2f,
|
||||||
|
targetLayer = TargetLayerMask,
|
||||||
|
explosionEffectPrefab = verticalSlash
|
||||||
|
};
|
||||||
|
|
||||||
|
warning.SetEffect(effectData, SlashAnimationPlay, PatternClear);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindUpAnimationEnd()
|
private void HorizontalSlashPattern()
|
||||||
{
|
{
|
||||||
EnemyAnimator.SetBool(WindUp, false);
|
Debug.Log("HorizontalSlashPattern: 보스가 횡적 슬래시를 사용합니다.");
|
||||||
|
WindUpAnimation();
|
||||||
|
|
||||||
|
var warning = Instantiate(horizontalWarning, transform.position, transform.rotation)
|
||||||
|
.GetComponent<HorizontalAoeController>();
|
||||||
|
|
||||||
|
var effectData = new DamageEffectData
|
||||||
|
{
|
||||||
|
damage = (int)attackPower,
|
||||||
|
radius = 15f,
|
||||||
|
delay = 2f,
|
||||||
|
targetLayer = TargetLayerMask,
|
||||||
|
explosionEffectPrefab = horizontalSlash
|
||||||
|
};
|
||||||
|
|
||||||
|
warning.SetEffect(effectData, SlashAnimationPlay, PatternClear);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindUpAnimation()
|
||||||
|
{
|
||||||
|
SetAnimation(WindUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SlashAnimationPlay()
|
private void SlashAnimationPlay()
|
||||||
{
|
{
|
||||||
EnemyAnimator.SetTrigger(VertiSlash);
|
SetAnimation(Slash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PatternClear()
|
private void PatternClear()
|
||||||
{
|
{
|
||||||
_isPatternRunning = false;
|
_isPatternRunning = false;
|
||||||
|
IsMeleeCombat = false;
|
||||||
_patternTimer = 0f;
|
_patternTimer = 0f;
|
||||||
Agent.enabled = true;
|
Agent.isStopped = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user