fix: 플레이어 접촉 이동과 타깃 표면 추적 보정

- TargetSurfaceUtility를 추가해 플레이어와 적의 실제 충돌 표면 기준으로 거리, 방향, 목적지를 계산

- 플레이어 이동과 적 루트모션, 추적 로직에서 접촉 시 수평 이동을 제한해 겹침과 밀어내기 문제를 완화

- 드로그 AI 거리 판정 노드들이 표면 거리 기준을 사용하도록 맞춰 사거리 분기 오차를 줄임
This commit is contained in:
2026-04-09 23:22:28 +09:00
parent 0fa23d4389
commit abfc43ae76
20 changed files with 514 additions and 92 deletions

View File

@@ -6,6 +6,7 @@ using UnityEngine;
using Unity.Netcode;
using Colosseum.Abnormalities;
using Colosseum.Combat;
using Colosseum.Player;
#if UNITY_EDITOR
@@ -1266,20 +1267,26 @@ namespace Colosseum.Skills
if (IsSpawned && !IsServer)
return;
Vector3 direction = currentTargetOverride.transform.position - transform.position;
direction.y = 0f;
Vector3 direction = TargetSurfaceUtility.GetHorizontalDirectionToSurface(transform.position, currentTargetOverride);
if (direction.sqrMagnitude < 0.0001f)
return;
bool suppressRotationWhileContactingPlayer = currentSkill.UseRootMotion
&& currentSkill.CastTargetTrackingMode == SkillCastTargetTrackingMode.FaceTarget
&& enemyBase.IsTouchingPlayerContact;
if (currentSkill.CastTargetTrackingMode == SkillCastTargetTrackingMode.FaceTarget ||
currentSkill.CastTargetTrackingMode == SkillCastTargetTrackingMode.MoveTowardTarget)
{
Quaternion targetRotation = Quaternion.LookRotation(direction.normalized);
float rotationSpeed = Mathf.Max(0f, currentSkill.CastTargetRotationSpeed);
if (rotationSpeed <= 0f)
transform.rotation = targetRotation;
else
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * 360f * Time.deltaTime);
if (!suppressRotationWhileContactingPlayer)
{
Quaternion targetRotation = Quaternion.LookRotation(direction.normalized);
float rotationSpeed = Mathf.Max(0f, currentSkill.CastTargetRotationSpeed);
if (rotationSpeed <= 0f)
transform.rotation = targetRotation;
else
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * 360f * Time.deltaTime);
}
}
if (currentSkill.CastTargetTrackingMode != SkillCastTargetTrackingMode.MoveTowardTarget || currentSkill.UseRootMotion)
@@ -1290,7 +1297,8 @@ namespace Colosseum.Skills
return;
float stopDistance = Mathf.Max(0f, currentSkill.CastTargetStopDistance);
if (direction.magnitude <= stopDistance)
float surfaceDistance = TargetSurfaceUtility.GetHorizontalSurfaceDistance(transform.position, currentTargetOverride);
if (surfaceDistance <= stopDistance)
{
navMeshAgent.isStopped = true;
navMeshAgent.ResetPath();
@@ -1298,7 +1306,7 @@ namespace Colosseum.Skills
}
navMeshAgent.isStopped = false;
navMeshAgent.SetDestination(currentTargetOverride.transform.position);
navMeshAgent.SetDestination(TargetSurfaceUtility.GetClosestSurfacePoint(transform.position, currentTargetOverride));
}
/// <summary>