Unity-WebSocket/Assets/FishNet/Runtime/Plugins/GameKit/Dependencies/Utilities/Colliders.cs
2025-06-28 11:28:54 +03:30

162 lines
5.4 KiB
C#

using System;
using UnityEngine;
namespace GameKit.Dependencies.Utilities
{
public static class ColliderExtensions
{
public static void GetBoxOverlapParams(this BoxCollider boxCollider, out Vector3 center, out Vector3 halfExtents)
{
Transform cachedTransform = boxCollider.transform;
// DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM
center = cachedTransform.TransformPoint(boxCollider.center);
Vector3 lossyScale = cachedTransform.lossyScale;
Vector3 size = boxCollider.size;
float x = size.x * 0.5f * lossyScale.x;
float y = size.y * 0.5f * lossyScale.y;
float z = size.z * 0.5f * lossyScale.z;
halfExtents = new(x, y, z);
}
public static void GetCapsuleCastParams(this CapsuleCollider capsuleCollider, out Vector3 point1, out Vector3 point2, out float radius)
{
Transform cachedTransform = capsuleCollider.transform;
Vector3 lossyScale = cachedTransform.lossyScale;
// Use System.Math instead of UnityEngine.Mathf because it's much faster.
float absX = Math.Abs(lossyScale.x);
float absY = Math.Abs(lossyScale.y);
float absZ = Math.Abs(lossyScale.z);
float height;
Vector3 direction;
switch (capsuleCollider.direction)
{
case 1:
{
radius = capsuleCollider.radius * Math.Max(absX, absZ);
height = capsuleCollider.height * absY;
direction = Vector3.up;
break;
}
case 2:
{
radius = capsuleCollider.radius * Math.Max(absX, absY);
height = capsuleCollider.height * absZ;
direction = Vector3.forward;
break;
}
default:
{
// Falling back to X is Unity's default behaviour.
radius = capsuleCollider.radius * Math.Max(absY, absZ);
height = capsuleCollider.height * absX;
direction = Vector3.right;
break;
}
}
Vector3 center = cachedTransform.TransformPoint(capsuleCollider.center);
Vector3 offset = height < radius * 2.0f ? Vector3.zero : cachedTransform.TransformDirection(direction * (height * 0.5f - radius));
// DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM
float x1 = center.x + offset.x;
float y1 = center.y + offset.y;
float z1 = center.z + offset.z;
float x2 = center.x - offset.x;
float y2 = center.y - offset.y;
float z2 = center.z - offset.z;
point1 = new(x1, y1, z1);
point2 = new(x2, y2, z2);
}
public static void GetSphereOverlapParams(this SphereCollider sphereCollider, out Vector3 center, out float radius)
{
Transform cachedTransform = sphereCollider.transform;
center = cachedTransform.TransformPoint(sphereCollider.center);
Vector3 lossyScale = cachedTransform.lossyScale;
// Use System.Math instead of UnityEngine.Mathf because it's much faster.
float x = Math.Abs(lossyScale.x);
float y = Math.Abs(lossyScale.y);
float z = Math.Abs(lossyScale.z);
// Two calls of Math.Max are faster than a single Mathf.Max call because Math.Max doesn't allocate memory and doesn't use loops.
radius = sphereCollider.radius * Math.Max(Math.Max(x, y), z);
}
}
public static class Collider2DExtensions
{
public static void GetBox2DOverlapParams(this BoxCollider2D boxCollider, out Vector3 center, out Vector3 halfExtents)
{
Transform cachedTransform = boxCollider.transform;
// DO NOT USE UNITY'S VECTOR OPERATIONS IN HOT PATHS, UNITY DOESN'T OPTIMISE THEM
center = cachedTransform.TransformPoint(boxCollider.offset);
Vector3 lossyScale = cachedTransform.lossyScale;
Vector3 size = boxCollider.size;
float x = size.x * 0.5f * lossyScale.x;
float y = size.y * 0.5f * lossyScale.y;
float z = size.z * 0.5f * lossyScale.z;
halfExtents = new(x, y, z);
}
public static void GetCircleOverlapParams(this CircleCollider2D circleCollider, out Vector3 center, out float radius)
{
Transform cachedTransform = circleCollider.transform;
Vector3 offset = new(circleCollider.offset.x, circleCollider.offset.y, circleCollider.transform.position.z);
center = cachedTransform.TransformPoint(offset);
Vector3 lossyScale = cachedTransform.lossyScale;
// Use System.Math instead of UnityEngine.Mathf because it's much faster.
float x = Math.Abs(lossyScale.x);
float y = Math.Abs(lossyScale.y);
float z = Math.Abs(lossyScale.z);
// Two calls of Math.Max are faster than a single Mathf.Max call because Math.Max doesn't allocate memory and doesn't use loops.
radius = circleCollider.radius * Math.Max(Math.Max(x, y), z);
}
}
}