public void OnCollision(RelativeRigidbody body) { if (_lockPosition) { return; } nextVelocity = _velocity - .5F * Vector3.Project(_velocity - body._velocity, transform.position - body.transform.position); }
void Start() { parent = GetComponentInParent <NodeBuilder>(); body = GetComponent <RelativeRigidbody>(); halo = (Behaviour)GetComponent("Halo"); circle = GetComponent <DrawCircle>(); collision = GetComponent <AudioSource>(); body.listeners.Add(UpdateForces); }
public bool FindCollision(IEnumerable <RelativeRigidbody> bodies, out RelativeRigidbody collidedBody, out float collisionTime) { collidedBody = null; collisionTime = 1F; foreach (RelativeRigidbody body in bodies) { Vector3 dp = transform.position - body.transform.position; Vector3 dv = scaledVelocity - body.scaledVelocity; float dpv = Vector3.Dot(dp, dv); if (dp.sqrMagnitude <= 1F && dpv < 1F) { Vector3 adjustment = .5F * (1F - dp.magnitude) * dp.normalized; antiClipping += adjustment; body.antiClipping -= adjustment; clipping.Add(body); body.clipping.Add(this); continue; } if (dv == Vector3.zero || clipping.Contains(body)) { continue; } double discriminant = dpv * dpv - 4D * dv.sqrMagnitude * (dp.sqrMagnitude - 1D); if (discriminant >= 0D) { discriminant = Math.Sqrt(discriminant); float collision1 = (float)(-dpv + discriminant) / 2F / dv.magnitude; float collision2 = (float)(-dpv - discriminant) / 2F / dv.magnitude; if (collision1 >= 0F && collision1 <= collisionTime) { collidedBody = body; collisionTime = collision1; } if (collision2 >= 0F && collision2 <= collisionTime) { collidedBody = body; collisionTime = collision2; } } } return(collidedBody != null); }
protected virtual void FixedUpdate() { RelativeRigidbody[] bodies = GetComponentsInChildren <RelativeRigidbody>(); foreach (RelativeRigidbody body in bodies) { foreach (Action listener in body.listeners) { listener.Invoke(); } } bodies = bodies.Where(b => b.timeScale != 0).ToArray(); RelativeRigidbody[] withCollisions = bodies.Where(b => b.hasCollision).ToArray(); float timeRemaining = 1F; bool collisionFound; int iterations = 0; do { foreach (RelativeRigidbody body in bodies) { body.CalculateVelocity(Time.fixedDeltaTime * timeRemaining); } collisionFound = false; float collisionTime = 1F; RelativeRigidbody collided1 = null, collided2 = null; UnityEngine.Profiling.Profiler.BeginSample("FindCollisions"); foreach (RelativeRigidbody body in withCollisions) { RelativeRigidbody foundCollided; float foundTime; if (body.FindCollision(withCollisions.Where(b => b != body), out foundCollided, out foundTime)) { if (foundTime < collisionTime) { collisionFound = true; collisionTime = foundTime; collided1 = body; collided2 = foundCollided; } } } UnityEngine.Profiling.Profiler.EndSample(); if (collisionTime > 0F) { foreach (RelativeRigidbody body in bodies) { body.ApplyVelocity(collisionTime); } timeRemaining -= collisionTime; } if (collisionFound) { collided1.OnCollision(collided2); collided2.OnCollision(collided1); } } while (iterations++ < 1000 && collisionFound && timeRemaining > 0F); if (iterations > 1000) { Debug.Log("Reached maximum number of iterations"); } }
public void LockSelected() { if (_selected == null) return; RelativeRigidbody body = _selected.GetComponent<RelativeRigidbody>(); _lockButton.GetComponentInChildren<Text>().text = (body.lockPosition = !body.lockPosition) ? "Unlock" : "Lock"; }