summaryrefslogtreecommitdiff
path: root/marching/Assets/Scripts/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'marching/Assets/Scripts/Physics')
-rw-r--r--marching/Assets/Scripts/Physics/FastBoxCollider.cs14
-rw-r--r--marching/Assets/Scripts/Physics/FastCircleCollider.cs13
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager.cs35
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs71
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs.meta11
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs80
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs.meta11
7 files changed, 232 insertions, 3 deletions
diff --git a/marching/Assets/Scripts/Physics/FastBoxCollider.cs b/marching/Assets/Scripts/Physics/FastBoxCollider.cs
index 7b52caf..03fbb24 100644
--- a/marching/Assets/Scripts/Physics/FastBoxCollider.cs
+++ b/marching/Assets/Scripts/Physics/FastBoxCollider.cs
@@ -36,6 +36,20 @@ public class FastBoxCollider : MonoBehaviour, IQuadTreeObject
}
}
+ public Vector4 box
+ {
+ get
+ {
+ Vector2 c = center;
+ Vector4 b = new Vector4();
+ b.x = c.x;
+ b.y = c.y;
+ b.z = size.x;
+ b.w = size.y;
+ return b;
+ }
+ }
+
public void Awake()
{
if (m_Type == ColliderType.Collider)
diff --git a/marching/Assets/Scripts/Physics/FastCircleCollider.cs b/marching/Assets/Scripts/Physics/FastCircleCollider.cs
index 5884a69..dde49f9 100644
--- a/marching/Assets/Scripts/Physics/FastCircleCollider.cs
+++ b/marching/Assets/Scripts/Physics/FastCircleCollider.cs
@@ -35,6 +35,19 @@ public class FastCircleCollider : MonoBehaviour, IQuadTreeObject
}
}
+ public Vector3 circle
+ {
+ get
+ {
+ Vector3 c = new Vector3();
+ Vector2 ct = center;
+ c.x = ct.x;
+ c.y = ct.y;
+ c.z = radius;
+ return c;
+ }
+ }
+
public Vector2 offset => m_Offset;
public void Awake()
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager.cs b/marching/Assets/Scripts/Physics/PhysicsManager.cs
index 6daf610..c4e6017 100644
--- a/marching/Assets/Scripts/Physics/PhysicsManager.cs
+++ b/marching/Assets/Scripts/Physics/PhysicsManager.cs
@@ -11,8 +11,12 @@ public enum ColliderType
Hitbox,
}
-public class PhysicsManager : Singleton<PhysicsManager>
+/// <summary>
+/// 四叉树空间划分,优化碰撞检测
+/// </summary>
+public partial class PhysicsManager : Singleton<PhysicsManager>
{
+ #region Quadtrees
public Vector4 quadtreeCollisionRange { set { m_QuadtreeCollisionRange = value; } }
private Vector4 m_QuadtreeCollisionRange;
private Quadtree m_QuadtreeCollision;
@@ -22,6 +26,9 @@ public class PhysicsManager : Singleton<PhysicsManager>
private Vector4 m_QuadtreeHurtboxRange;
private Quadtree m_QuadtreeHurtboxes;
private List<IQuadTreeObject> m_QuadtreeObjHurtboxes = new List<IQuadTreeObject>();
+ #endregion
+ public List<IQuadTreeObject> sharedRetriveResults => m_SharedRetriveResults;
+ private List<IQuadTreeObject> m_SharedRetriveResults = new List<IQuadTreeObject>();
public PhysicsManager()
{
@@ -99,9 +106,31 @@ public class PhysicsManager : Singleton<PhysicsManager>
return m_QuadtreeCollision.Retrieve(ref returnObjs, bound);
}
- public static bool CircleVsCircle(Vector2 pos1, float r1, Vector2 pos2, float r2)
+ public bool RetriveHurtboxes(ref List<IQuadTreeObject> returnObjs, Vector4 bound)
{
- return (pos1 - pos2).magnitude <= r1+r2;
+ return m_QuadtreeHurtboxes.Retrieve(ref returnObjs, bound);
+ }
+
+ public bool RetriveColliders(Vector4 bound)
+ {
+ m_SharedRetriveResults.Clear();
+ return m_QuadtreeCollision.Retrieve(ref m_SharedRetriveResults, bound);
+ }
+
+ public bool RetriveHurtboxes(Vector4 bound)
+ {
+ m_SharedRetriveResults.Clear();
+ return m_QuadtreeHurtboxes.Retrieve(ref m_SharedRetriveResults, bound);
+ }
+
+ public System.Func<Vector4, bool> GetRetriverByType(ColliderType type)
+ {
+ if (type == ColliderType.Collider)
+ return RetriveColliders;
+ else if (type == ColliderType.Hurtbox)
+ return RetriveHurtboxes;
+ else
+ return null;
}
} \ No newline at end of file
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs
new file mode 100644
index 0000000..48af516
--- /dev/null
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs
@@ -0,0 +1,71 @@
+using mh;
+using System.Collections;
+using System.Collections.Generic;
+using Unity.VisualScripting.Antlr3.Runtime.Tree;
+using UnityEngine;
+
+public partial class PhysicsManager : Singleton<PhysicsManager>
+{
+ private List<IQuadTreeObject> m_SharedCollideResults = new List<IQuadTreeObject>();
+
+ public Vector4 GetCircleBound(Vector3 circle)
+ {
+ float size = circle.z * 2;
+ return new Vector4(circle.x, circle.y, size, size);
+ }
+
+ public Vector4 GetBoxBound(Vector4 box)
+ {
+ return box;
+ }
+
+ public ref readonly List<IQuadTreeObject> CircleCast(ColliderType target, Vector3 circle)
+ {
+ m_SharedCollideResults.Clear();
+ var retriver = GetRetriverByType(target);
+ if(retriver != null)
+ {
+ if (retriver(GetCircleBound(circle)))
+ {
+ for(int i = 0; i < m_SharedRetriveResults.Count; ++i)
+ {
+ var collider = m_SharedRetriveResults[i];
+ if(collider != null)
+ {
+ if(collider is FastCircleCollider)
+ {
+ if(CircleVsCircle((collider as FastCircleCollider).circle, circle))
+ {
+ m_SharedCollideResults.Add(collider);
+ }
+ }
+ else if(collider is FastBoxCollider)
+ {
+ if (BoxVsCircle((collider as FastBoxCollider).box, circle))
+ {
+ m_SharedCollideResults.Add(collider);
+ }
+ }
+ }
+ }
+ }
+ }
+ return ref m_SharedCollideResults;
+ }
+
+ public ref readonly List<IQuadTreeObject> BoxCast(ColliderType target, Vector4 box)
+ {
+ return ref m_SharedCollideResults;
+ }
+
+ public ref readonly List<IQuadTreeObject> LineCast(ColliderType target, Vector4 line)
+ {
+ return ref m_SharedCollideResults;
+ }
+
+ public ref readonly List<IQuadTreeObject> PointCast(ColliderType target, Vector2 point)
+ {
+ return ref m_SharedCollideResults;
+ }
+
+} \ No newline at end of file
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs.meta b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs.meta
new file mode 100644
index 0000000..d5f9202
--- /dev/null
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2d0c6870f58c8c6469810ba2ca63cbc7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs
new file mode 100644
index 0000000..81625ac
--- /dev/null
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs
@@ -0,0 +1,80 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public partial class PhysicsManager : Singleton<PhysicsManager>
+{
+
+ /// <summary>
+ /// circle x,y,radius
+ /// </summary>
+ /// <param name="pos1"></param>
+ /// <param name="r1"></param>
+ /// <param name="pos2"></param>
+ /// <param name="r2"></param>
+ /// <returns></returns>
+ public static bool CircleVsCircle(Vector2 pos1, float r1, Vector2 pos2, float r2)
+ {
+ return (pos1 - pos2).magnitude <= r1 + r2;
+ }
+
+ public static bool CircleVsCircle(Vector3 c1, Vector3 c2)
+ {
+ return (c1.xy() - c2.xy()).magnitude <= c1.z + c2.z;
+ }
+
+ /// <summary>
+ /// intersection是r2对于r1
+ /// </summary>
+ /// <param name="b1"></param>
+ /// <param name="b2"></param>
+ /// <param name="intersection"></param>
+ /// <returns></returns>
+ public static bool BoxVsBox(Vector4 b1, Vector4 b2, out Vector2 intersection)
+ {
+ float b1w = b1.z / 2f, b1h = b1.w / 2f, b2w = b2.z / 2f, b2h = b2.w / 2f;
+ float distX = b2.x - b1.x;
+ float distY = b2.y - b1.y;
+ if(Mathf.Abs(distX) < b1w + b2w && Mathf.Abs(distY) < b1h +b2h)
+ {
+ intersection = new Vector2();
+ intersection.x = Mathf.Sign(distX) * (b1w + b2w - Mathf.Abs(distX));
+ intersection.y = Mathf.Sign(distY) * (b1h + b2h - Mathf.Abs(distY));
+ return true;
+ }
+ intersection = Vector2.zero;
+ return false;
+ }
+
+ public static bool BoxVsCircle(Vector4 box, Vector2 pos, float radius)
+ {
+ Vector4 boxScaled = box;
+ boxScaled.z = box.z + radius * 2;
+ boxScaled.w = box.w + radius * 2;
+ if (!IsPointInsideBox(boxScaled, pos))
+ return false;
+ Vector2 v = MathUtils.Abs(pos - box.xy());
+ Vector2 u = MathUtils.Max(v - box.zw(), 0);
+ return Vector2.Dot(u, u) < radius * radius;
+ }
+
+ /// <summary>
+ /// box x,y,w,h circle x,y,raduis
+ /// </summary>
+ /// <param name="box"></param>
+ /// <param name="circle"></param>
+ /// <returns></returns>
+ public static bool BoxVsCircle(Vector4 box, Vector3 circle)
+ {
+ return BoxVsCircle(box, circle.xy(), circle.z);
+ }
+
+ public static bool IsPointInsideBox(Vector4 box, Vector2 point)
+ {
+ return point.x >= box.x - box.z / 2f
+ && point.x <= box.x + box.z / 2f
+ && point.y >= box.y - box.w / 2f
+ && point.y <= box.y + box.w / 2f;
+ }
+
+}
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs.meta b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs.meta
new file mode 100644
index 0000000..7be9116
--- /dev/null
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2577861427359c9459ea0fa471de4040
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: