using mh; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; public enum ColliderType { Collider, Hurtbox, Hitbox, } class PhysicsQuadtree { public Vector4 quadtreeRange { set { m_QuadtreeRange = value; } } private Vector4 m_QuadtreeRange; private Quadtree m_Quadtree; private List m_Objects = new List(); public PhysicsQuadtree(Vector4 range) { m_QuadtreeRange = range; m_Quadtree = new Quadtree(0, range); } public void AddObject(IQuadTreeObject obj) { m_Objects.Add(obj); } public void RemoveObject(IQuadTreeObject obj) { m_Objects.Remove(obj); } public void UpdateQuadtree() { m_Quadtree.Clear(false); m_Quadtree.Rebound(m_QuadtreeRange); for (int i = 0; i < m_Objects.Count; i++) { IQuadTreeObject obj = m_Objects[i]; m_Quadtree.Insert(obj); } } public void Debug() { Color c = Gizmos.color; Gizmos.color = Color.red; m_Quadtree?.Iterate((t) => { Vector3 pos = new Vector3(t.x, t.y, 0); Vector3 size = new Vector3(t.w, t.h, 1); Gizmos.DrawWireCube(pos, size); }); Gizmos.color = c; } public bool Retrive(ref List returnObjs, IQuadTreeObject obj) { return m_Quadtree.Retrieve(ref returnObjs, obj); } public bool Retrive(ref List returnObjs, Vector4 bound) { return m_Quadtree.Retrieve(ref returnObjs, bound); } } /// /// 四叉树空间划分,优化碰撞检测 /// public partial class PhysicsManager : Singleton { #region Quadtrees private PhysicsQuadtree m_CollisionQuadtree; private PhysicsQuadtree m_HurtboxQuadtree; #endregion public Vector4 collisionQuadtreeRange { set { m_CollisionQuadtree.quadtreeRange = value; } } public Vector4 hurtboxQuadtreeRange { set { m_HurtboxQuadtree.quadtreeRange = value; } } public List sharedRetriveResults => m_SharedRetriveResults; private List m_SharedRetriveResults = new List(); public PhysicsManager() { m_CollisionQuadtree = new PhysicsQuadtree(new Vector4(0, 0, 30, 30)); m_HurtboxQuadtree = new PhysicsQuadtree(new Vector4(0, 0, 30, 30)); } public void AddCollider(IQuadTreeObject collider) { m_CollisionQuadtree.AddObject(collider); } public void RemoveCollider(IQuadTreeObject collider) { m_CollisionQuadtree.RemoveObject(collider); } public void AddHurtboxes(IQuadTreeObject hurtbox) { m_HurtboxQuadtree.AddObject(hurtbox); } public void RemoveHurtbox(IQuadTreeObject hurtbox) { m_HurtboxQuadtree.RemoveObject(hurtbox); } public void Update() { m_CollisionQuadtree.UpdateQuadtree(); m_HurtboxQuadtree.UpdateQuadtree(); } public bool RetriveColliders(ref List returnObjs, IQuadTreeObject obj) { return m_CollisionQuadtree.Retrive(ref returnObjs, obj); } public bool RetriveColliders(ref List returnObjs, Vector4 bound) { return m_CollisionQuadtree.Retrive(ref returnObjs, bound); } public bool RetriveHurtboxes(ref List returnObjs, Vector4 bound) { return m_HurtboxQuadtree.Retrive(ref returnObjs, bound); } public bool RetriveColliders(Vector4 bound) { m_SharedRetriveResults.Clear(); return m_CollisionQuadtree.Retrive(ref m_SharedRetriveResults, bound); } public bool RetriveHurtboxes(Vector4 bound) { m_SharedRetriveResults.Clear(); return m_HurtboxQuadtree.Retrive(ref m_SharedRetriveResults, bound); } public System.Func GetRetriverByType(ColliderType type) { if (type == ColliderType.Collider) return RetriveColliders; else if (type == ColliderType.Hurtbox) return RetriveHurtboxes; else return null; } public void Debug() { m_CollisionQuadtree.Debug(); } }