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