[Skills] 부채꼴 범위 판정 및 디버그 시각화 추가
- AreaShapeType enum 추가 (Sphere, Fan) - 부채꼴 설정: 원점 거리, 반지름, 좌우 각도 - 런타임 범위 시각화 (Scene 뷰) - 스킬 에셋 파일 구조 정리
This commit is contained in:
@@ -21,6 +21,10 @@ namespace Colosseum.Skills
|
|||||||
|
|
||||||
[Header("설정")]
|
[Header("설정")]
|
||||||
[SerializeField] private bool debugMode = false;
|
[SerializeField] private bool debugMode = false;
|
||||||
|
[Tooltip("공격 범위 시각화 (Scene 뷰에서 확인)")]
|
||||||
|
[SerializeField] private bool showAreaDebug = true;
|
||||||
|
[Tooltip("범위 표시 지속 시간")]
|
||||||
|
[Min(0.1f)] [SerializeField] private float debugDrawDuration = 1f;
|
||||||
|
|
||||||
// 현재 실행 중인 스킬
|
// 현재 실행 중인 스킬
|
||||||
private SkillData currentSkill;
|
private SkillData currentSkill;
|
||||||
@@ -207,6 +211,12 @@ namespace Colosseum.Skills
|
|||||||
var effect = effects[index];
|
var effect = effects[index];
|
||||||
if (debugMode) Debug.Log($"[Effect] {effect.name} (index {index})");
|
if (debugMode) Debug.Log($"[Effect] {effect.name} (index {index})");
|
||||||
|
|
||||||
|
// 공격 범위 시각화
|
||||||
|
if (showAreaDebug)
|
||||||
|
{
|
||||||
|
effect.DrawDebugRange(gameObject, debugDrawDuration);
|
||||||
|
}
|
||||||
|
|
||||||
effect.ExecuteOnCast(gameObject);
|
effect.ExecuteOnCast(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,28 @@ namespace Colosseum.Skills
|
|||||||
[Tooltip("범위 내에서 공격할 대상 필터")]
|
[Tooltip("범위 내에서 공격할 대상 필터")]
|
||||||
[SerializeField] protected TargetTeam targetTeam = TargetTeam.Enemy;
|
[SerializeField] protected TargetTeam targetTeam = TargetTeam.Enemy;
|
||||||
[SerializeField] protected AreaCenterType areaCenter = AreaCenterType.Caster;
|
[SerializeField] protected AreaCenterType areaCenter = AreaCenterType.Caster;
|
||||||
[Min(0.1f)] [SerializeField] protected float areaRadius = 3f;
|
[SerializeField] protected AreaShapeType areaShape = AreaShapeType.Sphere;
|
||||||
[SerializeField] protected LayerMask targetLayers;
|
[SerializeField] protected LayerMask targetLayers;
|
||||||
|
|
||||||
|
[Header("Sphere Settings")]
|
||||||
|
[Min(0.1f)] [SerializeField] protected float areaRadius = 3f;
|
||||||
|
|
||||||
|
[Header("Fan Settings")]
|
||||||
|
[Tooltip("부채꼴 원점이 캐릭터로부터 떨어진 거리")]
|
||||||
|
[Min(0f)] [SerializeField] protected float fanOriginDistance = 1f;
|
||||||
|
[Tooltip("부채꼴 반지름")]
|
||||||
|
[Min(0.1f)] [SerializeField] protected float fanRadius = 3f;
|
||||||
|
[Tooltip("부채꼴 좌우 각도 (각 방향으로 이 각도만큼 벌어짐, 총 각도 = 2배)")]
|
||||||
|
[Range(0f, 180f)] [SerializeField] protected float fanHalfAngle = 45f;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
public TargetType TargetType => targetType;
|
public TargetType TargetType => targetType;
|
||||||
public TargetTeam TargetTeam => targetTeam;
|
public TargetTeam TargetTeam => targetTeam;
|
||||||
|
public AreaShapeType AreaShape => areaShape;
|
||||||
|
public float AreaRadius => areaRadius;
|
||||||
|
public float FanOriginDistance => fanOriginDistance;
|
||||||
|
public float FanRadius => fanRadius;
|
||||||
|
public float FanHalfAngle => fanHalfAngle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 스킬 시전 시 호출
|
/// 스킬 시전 시 호출
|
||||||
@@ -89,17 +105,51 @@ namespace Colosseum.Skills
|
|||||||
private void ExecuteArea(GameObject caster)
|
private void ExecuteArea(GameObject caster)
|
||||||
{
|
{
|
||||||
Vector3 center = GetAreaCenter(caster);
|
Vector3 center = GetAreaCenter(caster);
|
||||||
Collider[] hits = Physics.OverlapSphere(center, areaRadius, targetLayers);
|
Collider[] hits = Physics.OverlapSphere(center, Mathf.Max(areaRadius, fanRadius), targetLayers);
|
||||||
|
|
||||||
foreach (var hit in hits)
|
foreach (var hit in hits)
|
||||||
{
|
{
|
||||||
if (hit.gameObject == caster) continue;
|
if (hit.gameObject == caster) continue;
|
||||||
if (!IsCorrectTeam(caster, hit.gameObject)) continue;
|
if (!IsCorrectTeam(caster, hit.gameObject)) continue;
|
||||||
|
|
||||||
|
// 부채꼴 판정
|
||||||
|
if (areaShape == AreaShapeType.Fan)
|
||||||
|
{
|
||||||
|
if (!IsInFanShape(caster, hit.transform.position))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ApplyEffect(caster, hit.gameObject);
|
ApplyEffect(caster, hit.gameObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 타겟이 부채꼴 범위 내에 있는지 확인
|
||||||
|
/// </summary>
|
||||||
|
private bool IsInFanShape(GameObject caster, Vector3 targetPosition)
|
||||||
|
{
|
||||||
|
Vector3 casterPos = caster.transform.position;
|
||||||
|
Vector3 casterForward = caster.transform.forward;
|
||||||
|
|
||||||
|
// 부채꼴 원점 계산
|
||||||
|
Vector3 fanOrigin = casterPos + casterForward * fanOriginDistance;
|
||||||
|
|
||||||
|
// 원점에서 타겟까지의 방향과 거리
|
||||||
|
Vector3 toTarget = targetPosition - fanOrigin;
|
||||||
|
float distance = toTarget.magnitude;
|
||||||
|
|
||||||
|
// 거리 체크
|
||||||
|
if (distance > fanRadius)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 각도 체크 (Y축 무시)
|
||||||
|
Vector3 toTargetFlat = new Vector3(toTarget.x, 0f, toTarget.z).normalized;
|
||||||
|
Vector3 casterForwardFlat = new Vector3(casterForward.x, 0f, casterForward.z).normalized;
|
||||||
|
|
||||||
|
float angle = Vector3.Angle(casterForwardFlat, toTargetFlat);
|
||||||
|
return angle <= fanHalfAngle;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector3 GetAreaCenter(GameObject caster)
|
private Vector3 GetAreaCenter(GameObject caster)
|
||||||
{
|
{
|
||||||
if (caster == null) return Vector3.zero;
|
if (caster == null) return Vector3.zero;
|
||||||
@@ -111,6 +161,83 @@ namespace Colosseum.Skills
|
|||||||
_ => caster.transform.position
|
_ => caster.transform.position
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Debug Visualization
|
||||||
|
/// <summary>
|
||||||
|
/// 공격 범위 시각화 (런타임 디버그용)
|
||||||
|
/// </summary>
|
||||||
|
public void DrawDebugRange(GameObject caster, float duration = 1f)
|
||||||
|
{
|
||||||
|
if (targetType != TargetType.Area) return;
|
||||||
|
|
||||||
|
Vector3 casterPos = caster.transform.position;
|
||||||
|
Vector3 forward = caster.transform.forward;
|
||||||
|
|
||||||
|
if (areaShape == AreaShapeType.Sphere)
|
||||||
|
{
|
||||||
|
Vector3 center = GetAreaCenter(caster);
|
||||||
|
DebugDrawSphere(center, areaRadius, Color.red, duration);
|
||||||
|
}
|
||||||
|
else if (areaShape == AreaShapeType.Fan)
|
||||||
|
{
|
||||||
|
DebugDrawFan(casterPos, forward, fanOriginDistance, fanRadius, fanHalfAngle, Color.red, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DebugDrawSphere(Vector3 center, float radius, Color color, float duration)
|
||||||
|
{
|
||||||
|
int segments = 32;
|
||||||
|
float step = 360f / segments;
|
||||||
|
|
||||||
|
// XZ 평면 원
|
||||||
|
Vector3 prevPoint = center + new Vector3(radius, 0, 0);
|
||||||
|
for (int i = 1; i <= segments; i++)
|
||||||
|
{
|
||||||
|
float angle = i * step * Mathf.Deg2Rad;
|
||||||
|
Vector3 newPoint = center + new Vector3(Mathf.Cos(angle) * radius, 0, Mathf.Sin(angle) * radius);
|
||||||
|
Debug.DrawLine(prevPoint, newPoint, color, duration);
|
||||||
|
prevPoint = newPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 수직선 (높이 표시)
|
||||||
|
Debug.DrawLine(center + Vector3.up * 0.1f, center + Vector3.up * 2f, color, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DebugDrawFan(Vector3 casterPos, Vector3 forward, float originDistance, float radius, float halfAngle, Color color, float duration)
|
||||||
|
{
|
||||||
|
Vector3 fanOrigin = casterPos + forward * originDistance;
|
||||||
|
Vector3 forwardFlat = new Vector3(forward.x, 0f, forward.z).normalized;
|
||||||
|
|
||||||
|
// 부채꼴의 양끝 방향 계산
|
||||||
|
Quaternion leftRot = Quaternion.Euler(0, -halfAngle, 0);
|
||||||
|
Quaternion rightRot = Quaternion.Euler(0, halfAngle, 0);
|
||||||
|
Vector3 leftDir = leftRot * forwardFlat;
|
||||||
|
Vector3 rightDir = rightRot * forwardFlat;
|
||||||
|
|
||||||
|
// 부채꼴 호 그리기
|
||||||
|
int arcSegments = Mathf.Max(8, Mathf.CeilToInt(halfAngle * 2 / 5f)); // 5도당 1세그먼트
|
||||||
|
Vector3 prevPoint = fanOrigin + leftDir * radius;
|
||||||
|
|
||||||
|
for (int i = 1; i <= arcSegments; i++)
|
||||||
|
{
|
||||||
|
float t = (float)i / arcSegments;
|
||||||
|
float angle = -halfAngle + t * halfAngle * 2;
|
||||||
|
Quaternion rot = Quaternion.Euler(0, angle, 0);
|
||||||
|
Vector3 dir = rot * forwardFlat;
|
||||||
|
Vector3 newPoint = fanOrigin + dir * radius;
|
||||||
|
|
||||||
|
Debug.DrawLine(prevPoint, newPoint, color, duration);
|
||||||
|
prevPoint = newPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 부채꼴 경계선
|
||||||
|
Debug.DrawLine(fanOrigin, fanOrigin + leftDir * radius, color, duration);
|
||||||
|
Debug.DrawLine(fanOrigin, fanOrigin + rightDir * radius, color, duration);
|
||||||
|
|
||||||
|
// 원점 표시
|
||||||
|
Debug.DrawLine(fanOrigin + Vector3.up * 0.1f, fanOrigin + Vector3.up * 1.5f, color, duration);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TargetType
|
public enum TargetType
|
||||||
@@ -131,4 +258,10 @@ namespace Colosseum.Skills
|
|||||||
Caster,
|
Caster,
|
||||||
CasterForward
|
CasterForward
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum AreaShapeType
|
||||||
|
{
|
||||||
|
Sphere, // 원형 범위
|
||||||
|
Fan // 부채꼴 범위
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
Assets/Scripts/Stats.meta
Normal file
8
Assets/Scripts/Stats.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 16ccc0cabc79ab349804827c78c5f38a
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
2
Assets/Scripts/Stats/CharacterStat.cs.meta
Normal file
2
Assets/Scripts/Stats/CharacterStat.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6f06303e1f173c04b82ef0d6bb561bc1
|
||||||
2
Assets/Scripts/Stats/CharacterStats.cs.meta
Normal file
2
Assets/Scripts/Stats/CharacterStats.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fae0149926eea244dad932b67ee76f7b
|
||||||
2
Assets/Scripts/Stats/StatModifier.cs.meta
Normal file
2
Assets/Scripts/Stats/StatModifier.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f947563a48624434b8f7851592571324
|
||||||
2
Assets/Scripts/Stats/StatType.cs.meta
Normal file
2
Assets/Scripts/Stats/StatType.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d826b3dfc0d45042ae01c2def537568
|
||||||
@@ -10,7 +10,7 @@ MonoBehaviour:
|
|||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
|
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
|
||||||
m_Name: NewDamageEffect
|
m_Name: Melee_Slash_0
|
||||||
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
|
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
|
||||||
description:
|
description:
|
||||||
damageAmount: 10
|
damageAmount: 10
|
||||||
Reference in New Issue
Block a user