优化 WeaponLance 的攻击逻辑

This commit is contained in:
2026-03-20 09:55:52 +08:00
parent 8d21d53c4d
commit 0d7df18324
16 changed files with 321 additions and 89 deletions
@@ -58,7 +58,8 @@ namespace Simulation
AreaCollisionRequestData request = _areaCollisionRequests[i];
AddAreaCollisionQuery(queryId, request.SourceEntityId, request.SourceOwnerEntityId,
request.SourceWasActiveAtQueryTime, in request.Center, request.Radius, request.MaxTargets,
request.ShapeType, in request.Direction, request.HalfAngleDeg);
request.ShapeType, in request.Direction, request.HalfAngleDeg, request.HalfWidth,
request.HalfLength);
queryId++;
builtAreaQueryCount++;
if (request.Radius > maxQueryRadius)
@@ -12,18 +12,29 @@ namespace Simulation
float radius, int maxTargets = 16)
{
return TryRequestAreaCollisionInternal(sourceEntityId, sourceOwnerEntityId, in center, radius,
maxTargets, CollisionShapeCircle, Vector3.forward, 180f);
maxTargets, CollisionShapeCircle, Vector3.forward, 180f, 0f, 0f);
}
public bool TryRequestSectorCollision(int sourceEntityId, int sourceOwnerEntityId, in Vector3 center,
float radius, in Vector3 direction, float halfAngleDeg, int maxTargets = 16)
{
return TryRequestAreaCollisionInternal(sourceEntityId, sourceOwnerEntityId, in center, radius,
maxTargets, CollisionShapeSector, direction, halfAngleDeg);
maxTargets, CollisionShapeSector, direction, halfAngleDeg, 0f, 0f);
}
public bool TryRequestRectangleCollision(int sourceEntityId, int sourceOwnerEntityId, in Vector3 center,
float halfWidth, float halfLength, in Vector3 direction, int maxTargets = 16)
{
float safeHalfWidth = Mathf.Max(0.01f, halfWidth);
float safeHalfLength = Mathf.Max(0.01f, halfLength);
float boundingRadius = Mathf.Sqrt(safeHalfWidth * safeHalfWidth + safeHalfLength * safeHalfLength);
return TryRequestAreaCollisionInternal(sourceEntityId, sourceOwnerEntityId, in center, boundingRadius,
maxTargets, CollisionShapeRectangle, direction, 0f, safeHalfWidth, safeHalfLength);
}
private bool TryRequestAreaCollisionInternal(int sourceEntityId, int sourceOwnerEntityId,
in Vector3 center, float radius, int maxTargets, int shapeType, in Vector3 direction, float halfAngleDeg)
in Vector3 center, float radius, int maxTargets, int shapeType, in Vector3 direction, float halfAngleDeg,
float halfWidth, float halfLength)
{
if (!_useSimulationMovement)
{
@@ -58,7 +69,9 @@ namespace Simulation
MaxTargets = Mathf.Max(1, maxTargets),
ShapeType = shapeType,
Direction = normalizedDirection,
HalfAngleDeg = Mathf.Clamp(halfAngleDeg, 0f, 180f)
HalfAngleDeg = Mathf.Clamp(halfAngleDeg, 0f, 180f),
HalfWidth = Mathf.Max(0f, halfWidth),
HalfLength = Mathf.Max(0f, halfLength)
});
return true;
@@ -1,3 +1,4 @@
using Components;
using CustomDebugger;
using CustomUtility;
using Definition.DataStruct;
@@ -188,7 +189,8 @@ namespace Simulation
continue;
}
if (!IsAreaTargetInsidePreciseShape(in query, target))
float targetRadius = ResolveAreaTargetRadius(target);
if (!IsAreaTargetInsidePreciseShape(in query, target, targetRadius))
{
continue;
}
@@ -230,7 +232,24 @@ namespace Simulation
return false;
}
private static bool IsAreaTargetInsidePreciseShape(in CollisionQueryData query, TargetableObject target)
private float ResolveAreaTargetRadius(TargetableObject target)
{
if (target == null)
{
return 0f;
}
if (target is EnemyBase && TryGetEnemyData(target.Id, out EnemySimData enemyData))
{
return Mathf.Max(0f, enemyData.EnemyBodyRadius);
}
MovementComponent movementComponent = target.GetComponent<MovementComponent>();
return movementComponent != null ? Mathf.Max(0f, movementComponent.EnemyBodyRadius) : 0f;
}
private static bool IsAreaTargetInsidePreciseShape(in CollisionQueryData query, TargetableObject target,
float targetRadius)
{
if (target == null || target.CachedTransform == null)
{
@@ -241,7 +260,7 @@ namespace Simulation
Vector3 toTarget = target.CachedTransform.position - center;
toTarget.y = 0f;
float radius = Mathf.Max(0.01f, query.Radius);
float radius = Mathf.Max(0.01f, query.Radius + Mathf.Max(0f, targetRadius));
float radiusSqr = radius * radius;
float sqrDistance = toTarget.sqrMagnitude;
if (sqrDistance > radiusSqr)
@@ -249,6 +268,27 @@ namespace Simulation
return false;
}
if (query.ShapeType == CollisionShapeRectangle)
{
Vector3 forwardRect = new Vector3(query.Direction.x, query.Direction.y, query.Direction.z);
forwardRect.y = 0f;
if (forwardRect.sqrMagnitude <= Mathf.Epsilon)
{
forwardRect = Vector3.forward;
}
else
{
forwardRect.Normalize();
}
Vector3 rightRect = Vector3.Cross(Vector3.up, forwardRect);
float halfWidth = Mathf.Max(0.01f, query.HalfWidth + Mathf.Max(0f, targetRadius));
float halfLength = Mathf.Max(0.01f, query.HalfLength + Mathf.Max(0f, targetRadius));
float forwardDistance = Vector3.Dot(toTarget, forwardRect);
float lateralDistance = Vector3.Dot(toTarget, rightRect);
return Mathf.Abs(forwardDistance) <= halfLength && Mathf.Abs(lateralDistance) <= halfWidth;
}
if (query.ShapeType != CollisionShapeSector)
{
return true;