private void HandleCollision(float start, float end, bool hasHit, RaycastHit hit) { // Are we now shorter than a pre-existing hit? if (endPoint != null && end < hitDist) { // Delete old hit endPoint = null; hitDist = Mathf.Infinity; // The children will clean themselves up based on startTime children = null; } TileHandler tile = null; if (hasHit) { tile = hit .collider .gameObject .GetComponentInParent <TileHandler>(); } if (!hasHit || tile != endPoint) { // If we have a real hit that doesn't exist anymore (because the // source moved), stop powering the children. if (children != null) { foreach (var beam in children) { beam.SetPoweredUntil(game.SimTime()); } endPoint = null; hitDist = Mathf.Infinity; children = null; } } // If we don't have a hit theres nothing to do if (!hasHit) { return; } if (tile == endPoint) { // We've already handled this collision return; } // FIXME: float newStart = FindOtherSide(hit) + hit.distance; print(newStart + " + " + end); if (newStart <= end - 0.01) { // New ray! var dir = GetDir(); var beam = game.CreateBeam(transform.position + newStart * dir, dir); beam.startTime = (end - newStart) / SPEED; beam.poweredUntil = game.SimTime() + Mathf.Max(0, start - newStart) / SPEED; beam.endPoint = endPoint; beam.children = children; } children = null; endPoint = tile; hitDist = hit.distance; // If we've already passed the collision point don't spawn children if (start < hit.distance - EPS) { children = tile.OnBeamCollision(this, hit); } if (children == null) { children = new List <BeamHandler>(); } UpdateChildrenPowered(); }
private void HandleCollision(float dt, float start, float end, bool hasHit, RaycastHit hit) { TileHandler tile = null; if (hasHit) { tile = hit .collider .gameObject .GetComponentInParent <TileHandler>(); } bool hitMatches = hasHit && endPoint == tile && ApproxEqual(hit.point, hitPoint) && ApproxEqual(hit.normal, hitNormal); if (children != null && (!hasHit || !hitMatches)) { // If we have a real hit that doesn't exist anymore (because the // source moved), stop powering the children & stop any spray effects DepowerChildren(); sprayEffect.Stop(); endPoint = null; children = null; } if (!hasHit) { sprayEffect.Stop(); return; } if (hitMatches) { // We've already handled this collision return; } // If we didn't hit this just in the new segment of the ray if (hit.distance < end - start) { float newStart = start + hit.distance + FindOtherSide(hit); if (newStart <= end - 0.01) { // New ray! var dir = GetDir(); var beam = game.CreateBeam(transform.position + newStart * dir, dir, this); beam.end = end - newStart; beam.powered = false; beam.endPoint = endPoint; beam.children = children; beam.SetEndpoints(); } } children = null; endPoint = tile; hitPoint = hit.point; hitNormal = hit.normal; children = tile.OnBeamCollision(this, hit); if (children == null) { children = new List <BeamHandler>(); } if (tile.TriggersSprayEffect()) { // Render a spray effect to highlight that the beam hit a solid, nonreflective surface sprayEffect.Play(hit.point, Vector3.Reflect(GetDir(), hit.normal)); } }