/// <summary> /// Test to see if a beam hit anything, object or terrain. /// </summary> /// <param name="shooter"></param> /// <param name="beams"></param> /// <param name="particle"></param> /// <returns></returns> private bool HitSomething(GameActor shooter, Beam beam) { Vector3 start = beam.Position; Vector3 end = start + beam.Velocity * Time.GameTimeFrameSeconds; Vector3 terrainHit = end; bool hitTerrain = beam.Life - beam.TTL >= beam.TTTerraHit; if (hitTerrain) { /// terrain hit is current position /// - what we've travelled already (vel * (life - ttl)) /// + time from beginning to terrain hit (vel * ttTerraHit) /// We use end as current position because we've already updated TTL /// but haven't yet advanced .Position. When we do advance .Position, /// it will be to "end". terrainHit = end + beam.Velocity * (beam.TTTerraHit - (beam.Life - beam.TTL)); } Vector3 hitPoint = terrainHit; GameActor hitThing = beam.TargetActor; if (hitThing != null) { // never hit terrain if we have a valid target actor hitTerrain = false; hitPoint = beam.TargetActor.WorldCollisionCenter; } // used the actor to determine if we've hit the target Vector3 beamVector = end - hitPoint; float beamLength = beamVector.LengthSquared(); bool hitTarget = beamLength < 0.25f; if (hitTerrain && hitTarget) { float beamToTerrain = Vector3.DistanceSquared(start, terrainHit); float beamToHit = Vector3.DistanceSquared(start, hitPoint); if ((beamToHit - beamToTerrain) > 0.25f) { hitThing = null; hitPoint = terrainHit; } } if (hitTarget) { OnHit(shooter, hitThing, hitPoint, beam); } else if (hitTerrain) { OnHit(shooter, null, terrainHit, beam); ExplosionManager.CreateSpark(terrainHit, 3, 0.4f, 1.0f); } return(hitTerrain || hitTarget); }
/// <summary> /// Test to see if a bleep hit anything, object or terrain. /// </summary> /// <param name="shooter"></param> /// <param name="bleeps"></param> /// <param name="particle"></param> /// <returns></returns> private bool HitSomething(GameActor shooter, Bleep bleep) { Vector3 start = bleep.Position; Vector3 end = start + bleep.Velocity * Time.GameTimeFrameSeconds; Vector3 terrainHit = end; bool hitTerrain = bleep.Life - bleep.TTL >= bleep.TTTerraHit; if (hitTerrain) { /// terrain hit is current position /// - what we've travelled already (vel * (life - ttl)) /// + time from beginning to terrain hit (vel * ttTerraHit) /// We use end as current position because we've already updated TTL /// but haven't yet advanced .Position. When we do advance .Position, /// it will be to "end". terrainHit = end + bleep.Velocity * (bleep.TTTerraHit - (bleep.Life - bleep.TTL)); } const float kBleepRadius = 0.25f; GameActor hitThing = null; Vector3 hitPoint = terrainHit; if (CollSys.TestAll( start, end, kBleepRadius, _scratchHitInfo)) { for (int i = 0; i < _scratchHitInfo.Count; ++i) { GameActor other = _scratchHitInfo[i].Other; if (!ExcludedHitThing(shooter, other)) { hitThing = other; hitPoint = _scratchHitInfo[i].Contact; break; } } _scratchHitInfo.Clear(); } if (hitTerrain && (hitThing != null)) { if (Vector3.DistanceSquared(start, terrainHit) < Vector3.DistanceSquared(start, hitPoint)) { hitThing = null; hitPoint = terrainHit; } } if (hitThing != null) { OnHit(shooter, hitThing, hitPoint, bleep); } else if (hitTerrain) { OnHit(shooter, null, hitPoint, bleep); ExplosionManager.CreateSpark(hitPoint, 3, 0.4f, 1.0f); } return(hitTerrain || (hitThing != null));; }