summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Physics/PhysicsWorld.cs
blob: 3514934cf97b9a0b790fa32a2edefe6e786a54fe (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
 using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// primitive分类
/// </summary>
public enum PhysicsGroup
{
    Character, // 角色
    Prop,      // 物体
    Ground,    // 地面
    Wall,      // 墙面

	GroupCount,
}

/// <summary>
/// primitive标记
/// </summary>
public enum PhysicsTag
{
	Player = 1,      // 从属于玩家
	Oponent = 1 << 1, // 从属于对手
}

public class PhysicsWorld : Singleton<PhysicsWorld>
{
    private int m_UpdateRate = 60;
    // 重力加速度
    private readonly Vector3 m_Gravity = new Vector3(0, -9.8f, 0);
    // 当前管理的碰撞体
    private List<PhysicsPrimitive> m_Primitives;
    private float m_TimeCount;

	private readonly int[] m_CollisionTable = {
		   // wall    ground    prop    character
/*character*/   1,       1,       1,       1,
/*prop     */   1,       1,       0,       0,
/*ground   */   0,       0,       0,       0,
/*wall     */   0,       0,       0,       0, 
	};

    public void Init()
    {
        m_Primitives = new List<PhysicsPrimitive>();
        m_TimeCount = Time.time;
    }

    public void AddPrimitive(PhysicsPrimitive prim)
    {
        if (prim == null)
            return;
        if(m_Primitives.Contains(prim))
        {
            Debug.LogError("PhysicsWorld已经存在此碰撞体,ID=" + prim.ID + ", 类型=" + prim.Tag);
            return;
        }
        m_Primitives.Add(prim);
    }

    public void RemovePrimitive(PhysicsPrimitive prim)
    {
        if (prim == null)
            return;
        m_Primitives.Remove(prim);
    }

    /// <summary>
    /// 物理系统已稳定的逻辑帧率执行
    /// </summary>
    public void Update()
    {
        float preTime = m_TimeCount;
        m_TimeCount = Time.time;
        float dt = m_TimeCount - preTime;
        while (dt > 1f / m_UpdateRate)
        {
            Tick();
            dt -= 1f / m_UpdateRate;
        }
        m_TimeCount -= dt;
    }

    private void Tick()
    {
		float deltaTime = 1f / m_UpdateRate;
		int groupCount = (int)PhysicsGroup.GroupCount;
		for (int i = 0; i < m_Primitives.Count; ++i)
		{
			PhysicsPrimitive prim1 = m_Primitives[i];
			for(int j = i + 1; j < m_Primitives.Count; ++j)
			{
				PhysicsPrimitive prim2 = m_Primitives[j];

				// check collision by group
				int minType = Mathf.Min((int)prim1.Type, (int)prim2.Type);
				int maxType = Mathf.Max((int)prim1.Type, (int)prim2.Type);
				if (m_CollisionTable[minType * groupCount + groupCount - maxType - 1] == 0)
					continue;

				// check collision by label
				if (prim1.Label == prim2.Label)
					continue;

				PhysicsCollisionInfo info;
				if(PhysicsHelper.PrimvsPrim(prim1, prim2, out info))
				{
					//没有physics body的primitive将不会被移动,只有那些绑定了physics body的会被施加物理效果,比如角色身体、物品

				}
			}
		}
    }

}