Example #1
0
    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();
    }
Example #2
0
    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));
        }
    }