summaryrefslogtreecommitdiff
path: root/marching/Assets/Scripts/Physics/PhysicsManager.cs
blob: bfb1dfe26c0a3b2eb248cb4e09dc485e3d0037b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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<IQuadTreeObject> m_Objects = new List<IQuadTreeObject>();

    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<IQuadTreeObject> returnObjs, IQuadTreeObject obj)
    {
        return m_Quadtree.Retrieve(ref returnObjs, obj);
    }

    public bool Retrive(ref List<IQuadTreeObject> returnObjs, Vector4 bound)
    {
        return m_Quadtree.Retrieve(ref returnObjs, bound);
    }

}

/// <summary>
/// 四叉树空间划分,优化碰撞检测
/// </summary>
public partial class PhysicsManager : Singleton<PhysicsManager>
{
    #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<IQuadTreeObject> sharedRetriveResults => m_SharedRetriveResults;
    private List<IQuadTreeObject> m_SharedRetriveResults = new List<IQuadTreeObject>();

    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<IQuadTreeObject> returnObjs, IQuadTreeObject obj)
    {
        return m_CollisionQuadtree.Retrive(ref returnObjs, obj);       
    }

    public bool RetriveColliders(ref List<IQuadTreeObject> returnObjs, Vector4 bound)
    {
        return m_CollisionQuadtree.Retrive(ref returnObjs, bound);
    }

    public bool RetriveHurtboxes(ref List<IQuadTreeObject> 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<Vector4, bool> 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();
    }

}