TrueSync: Physics2DWorldManager.cs Source File

TrueSync

Physics2DWorldManager.cs
1 using UnityEngine;
2 using System.Collections.Generic;
3 using System;
4 using TrueSync.Physics2D;
5 
6 namespace TrueSync {
7 
11  public class Physics2DWorldManager : IPhysicsManager {
12 
17 
18  private Physics2D.World world;
19 
20  Dictionary<IBody, GameObject> gameObjectMap;
21 
22  Dictionary<Physics2D.Body, Dictionary<Physics2D.Body, TSCollision2D>> collisionInfo;
23 
27  public TSVector Gravity {
28  get;
29  set;
30  }
31 
35  public bool SpeculativeContacts {
36  get;
37  set;
38  }
39 
40  public FP LockedTimeStep {
41  get;
42  set;
43  }
44 
45  // Use this for initialization
46  public void Init() {
47  ChecksumExtractor.Init(this);
48 
49  Settings.ContinuousPhysics = SpeculativeContacts;
50 
51  world = new TrueSync.Physics2D.World(new TSVector2(Gravity.x, Gravity.y));
52  ContactManager.physicsManager = this;
53 
54  world.BodyRemoved += OnRemovedRigidBody;
55  world.ContactManager.BeginContact += CollisionEnter;
56  world.ContactManager.StayContact += CollisionStay;
57  world.ContactManager.EndContact += CollisionExit;
58 
59  gameObjectMap = new Dictionary<IBody, GameObject>();
60  collisionInfo = new Dictionary<Physics2D.Body, Dictionary<Physics2D.Body, TSCollision2D>>();
61 
62  instance = this;
63  AddRigidBodies();
64  }
65 
69  public void UpdateStep() {
70  world.Step(LockedTimeStep);
71  }
72 
73  public IWorld GetWorld() {
74  return world;
75  }
76 
77  void AddRigidBodies() {
78  TSCollider2D[] bodies = GameObject.FindObjectsOfType<TSCollider2D>();
79  List<TSCollider2D> sortedBodies = new List<TSCollider2D>(bodies);
80  sortedBodies.Sort(UnityUtils.body2DComparer);
81 
82  for (int i = 0; i < sortedBodies.Count; i++) {
83  AddBody(sortedBodies[i]);
84  }
85  }
86 
87  public void AddBody(ICollider iCollider) {
88  if (!(iCollider is TSCollider2D)) {
89  Debug.LogError("You have a 3D object but your Physics 3D is disabled.");
90  return;
91  }
92 
93  TSCollider2D tsCollider = (TSCollider2D) iCollider;
94 
95  if (tsCollider._body != null) {
96  //already added
97  return;
98  }
99 
100  tsCollider.Initialize(world);
101  gameObjectMap[tsCollider._body] = tsCollider.gameObject;
102 
103  if (tsCollider.gameObject.transform.parent != null && tsCollider.gameObject.transform.parent.GetComponentInParent<TSCollider2D>() != null) {
104  TSCollider2D parentCollider = tsCollider.gameObject.transform.parent.GetComponentInParent<TSCollider2D>();
105  Physics2D.Body childBody = tsCollider._body;
106 
107  childBody.bodyConstraints.Add(new ConstraintHierarchy2D(((Physics2D.Body)parentCollider.Body), tsCollider._body, (tsCollider.GetComponent<TSTransform2D>().position + tsCollider.ScaledCenter) - (parentCollider.GetComponent<TSTransform2D>().position + parentCollider.ScaledCenter)));
108  }
109 
110  world.ProcessAddedBodies();
111  }
112 
113  internal string GetChecksum(bool plain) {
114  return ChecksumExtractor.GetEncodedChecksum();
115  }
116 
117  public void RemoveBody(IBody iBody) {
118  world.RemoveBody((TrueSync.Physics2D.Body) iBody);
119  world.ProcessRemovedBodies();
120  }
121 
122  public void OnRemoveBody(Action<IBody> OnRemoveBody) {
123  world.BodyRemoved += delegate (TrueSync.Physics2D.Body body) {
124  OnRemoveBody(body);
125  };
126  }
127 
128  private void OnRemovedRigidBody(TrueSync.Physics2D.Body body) {
129  GameObject go = gameObjectMap[body];
130 
131  if (go != null) {
132  GameObject.Destroy(go);
133  }
134  }
135 
136  private bool CollisionEnter(TrueSync.Physics2D.Contact contact) {
137  if (contact.FixtureA.IsSensor || contact.FixtureB.IsSensor) {
138  TriggerEnter(contact);
139 
140  return true;
141  }
142 
143  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, contact, "OnSyncedCollisionEnter");
144  return true;
145  }
146 
147  private void CollisionStay(TrueSync.Physics2D.Contact contact) {
148  if (contact.FixtureA.IsSensor || contact.FixtureB.IsSensor) {
149  TriggerStay(contact);
150  return;
151  }
152 
153  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, contact, "OnSyncedCollisionStay");
154  }
155 
156  private void CollisionExit(TrueSync.Physics2D.Contact contact) {
157  if (contact.FixtureA.IsSensor || contact.FixtureB.IsSensor) {
158  TriggerExit(contact);
159  return;
160  }
161 
162  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, null, "OnSyncedCollisionExit");
163  }
164 
165  private void TriggerEnter(TrueSync.Physics2D.Contact contact) {
166  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, contact, "OnSyncedTriggerEnter");
167  }
168 
169  private void TriggerStay(TrueSync.Physics2D.Contact contact) {
170  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, contact, "OnSyncedTriggerStay");
171  }
172 
173  private void TriggerExit(TrueSync.Physics2D.Contact contact) {
174  CollisionDetected(contact.FixtureA.Body, contact.FixtureB.Body, null, "OnSyncedTriggerExit");
175  }
176 
177  private void CollisionDetected(Physics2D.Body body1, Physics2D.Body body2, TrueSync.Physics2D.Contact contact, string callbackName) {
178  if (!gameObjectMap.ContainsKey(body1) || !gameObjectMap.ContainsKey(body2)) {
179  return;
180  }
181 
182  GameObject b1 = gameObjectMap[body1];
183  GameObject b2 = gameObjectMap[body2];
184 
185  if (b1 == null || b2 == null) {
186  return;
187  }
188 
189  b1.SendMessage(callbackName, GetCollisionInfo(body1, body2, contact), SendMessageOptions.DontRequireReceiver);
190  b2.SendMessage(callbackName, GetCollisionInfo(body2, body1, contact), SendMessageOptions.DontRequireReceiver);
191 
193  }
194 
195  private TSCollision2D GetCollisionInfo(Physics2D.Body body1, Physics2D.Body body2, TrueSync.Physics2D.Contact c) {
196  if (!collisionInfo.ContainsKey(body1)) {
197  collisionInfo.Add(body1, new Dictionary<Physics2D.Body, TSCollision2D>());
198  }
199 
200  Dictionary<Physics2D.Body, TSCollision2D> collisionInfoBody1 = collisionInfo[body1];
201 
202  TSCollision2D result = null;
203 
204  if (collisionInfoBody1.ContainsKey(body2)) {
205  result = collisionInfoBody1[body2];
206  } else {
207  result = new TSCollision2D();
208  collisionInfoBody1.Add(body2, result);
209  }
210 
211  result.Update(gameObjectMap[body2], c);
212 
213  return result;
214  }
215 
216  public GameObject GetGameObject(IBody body) {
217  if (!gameObjectMap.ContainsKey(body)) {
218  return null;
219  }
220 
221  return gameObjectMap[body];
222  }
223 
224  public int GetBodyLayer(IBody body) {
225  GameObject go = GetGameObject(body);
226  if (go == null) {
227  return -1;
228  }
229 
230  return go.layer;
231  }
232 
233  public TSRaycastHit2D Raycast(TSVector2 origin, TSVector2 direction, FP distance) {
234  TSRaycastHit2D result = null;
235 
236  Func<TrueSync.Physics2D.Fixture, TSVector2, TSVector2, FP, FP> callback = delegate (TrueSync.Physics2D.Fixture fixture, TSVector2 point, TSVector2 normal, FP fraction) {
237  result = new TSRaycastHit2D(gameObjectMap[fixture.Body].GetComponent<TSCollider2D>());
238  return 0;
239  };
240 
241  world.RayCast(callback, origin, origin + direction * distance);
242 
243  return result;
244  }
245 
246  public TSRaycastHit2D[] RaycastAll(TSVector2 origin, TSVector2 direction, FP distance) {
247  List<TSRaycastHit2D> result = new List<TSRaycastHit2D>();
248 
249  Func<TrueSync.Physics2D.Fixture, TSVector2, TSVector2, FP, FP> callback = delegate (TrueSync.Physics2D.Fixture fixture, TSVector2 point, TSVector2 normal, FP fraction) {
250  result.Add(new TSRaycastHit2D(gameObjectMap[fixture.Body].GetComponent<TSCollider2D>()));
251  return -1;
252  };
253 
254  world.RayCast(callback, origin, origin + direction * distance);
255 
256  if (result.Count == 0) {
257  return null;
258  }
259 
260  return result.ToArray();
261  }
262 
263  public bool IsCollisionEnabled(IBody rigidBody1, IBody rigidBody2) {
264  if (gameObjectMap.ContainsKey(rigidBody1) && gameObjectMap.ContainsKey(rigidBody2)) {
265  return LayerCollisionMatrix.CollisionEnabled(gameObjectMap[rigidBody1], gameObjectMap[rigidBody2]);
266  }
267 
268  return true;
269  }
270 
271  public IWorldClone GetWorldClone() {
272  return new WorldClone2D();
273  }
274 
275  }
276 
277 }
Manages the collision matrix of physics simulation.
Manages creation of player prefabs and lockstep execution.
Represents information about a contact between two 2D bodies.
static Physics2DWorldManager instance
Public access to a manager instance.
static void UpdateCoroutines()
Update all coroutines created.
void Initialize(Physics2D.World world)
Initializes Shape and RigidBody and sets initial values to position and orientation based on Unity&#39;s ...
Provides a few utilities to be used on TrueSync exposed classes.
Definition: UnityUtils.cs:10
A deterministic version of Unity&#39;s Transform component for 2D physics.
Definition: TSTransform2D.cs:9
TSVector2 position
Property access to position.
TSVector Gravity
Property access to simulated gravity.
Information about a 2D cast hit.
static TSBody2DComparer body2DComparer
Instance of a TSBody2DComparer.
Definition: UnityUtils.cs:58
static bool CollisionEnabled(int layerA, int layerB)
Returns true if the given layers can collide.
Manages the 2D physics simulation.
bool SpeculativeContacts
Property access to speculative contacts.
TSVector2 ScaledCenter
Returns a version of collider&#39;s center scaled by parent&#39;s transform.
Definition: TSCollider2D.cs:95
Abstract collider for 2D shapes.
Definition: TSCollider2D.cs:12
IBody2D Body
Returns RigidBody associated to this TSRigidBody.
Definition: TSCollider2D.cs:70
void UpdateStep()
Goes one step further on the physics simulation.
Represents a common interface to 2D and 3D bodies.
Definition: IBody.cs:6
Generated by   doxygen 1.8.11