private static void IncrementalRaycast( Vector3 start, Vector3 end, ProcessIntersection onIntersect, ShouldContinueRayCast shouldContinue ) { RaycastHit hitInfo; Vector3 ray = end - start; Vector3 dx = ray.normalized; Vector3 remaining = end - start; dx.Scale(new Vector3(.01f, .01f, .01f)); while (Physics.Raycast(start, dx, out hitInfo, remaining.magnitude, instance.collisionMask)) { remaining -= (hitInfo.point - start); start = (hitInfo.point + dx); //hit object must have an obstacle script if (hitInfo.collider.transform.GetComponent <Obstacle>() != null) { IntersectionResult result = new IntersectionResult(hitInfo); onIntersect(result); if (!shouldContinue(result)) { break; } } } }
public ParallelIncrementalRaycastData( Vector3 start, Vector3 end, ProcessIntersection onIntersect, ShouldContinueRayCast continueCondition ) { this.start = start; this.end = end; this.onIntersect = onIntersect; this.continueCondition = continueCondition; ray = end - start; remaining = end - start; dx = ray.normalized; }
public static MapNode CreateMapNodeAt(Vector2 location) { float x = location.x; float z = location.y; float height = 0; bool heightSet = false; bool walkable = true; float speedModifier = 1; List <IntersectionResult> layers = new List <IntersectionResult>(); ProcessIntersection onIntersect = (result => { if (!heightSet && !result.GetObstacle().CanPhaseThrough()) { height = result.GetPosition().y; heightSet = true; } if (!result.GetObstacle().IsWalkable()) { walkable = false; } layers.Add(new IntersectionResult( result.GetPosition(), result.GetObstacle() )); speedModifier *= result.GetObstacle().GetSpeedModifier(); }); ShouldContinueRayCast continueCondition = (result => { return(true); }); IncrementalRaycast( new Vector3(x, instance.bottomLeftCorner.y + instance.maxDimensions.y, z), new Vector3(x, instance.bottomLeftCorner.y, z), onIntersect, continueCondition ); MapNode newMapNode = Pools.MapNode; newMapNode.Set( new Vector3(location.x, height, location.y), height, layers, walkable ); return(newMapNode); }
public static void SendProjectile(Projectile projectile, Vector3 start, Vector3 target) { /* * First extend the target point to the bounds */ Vector3 boundsDimensions = instance.mapbounds.GetDimensions(); float largestDimension = Mathf.Max( boundsDimensions.x, boundsDimensions.y, boundsDimensions.z ); Vector3 direction = target - start; Ray ray = new Ray(start, direction); // reverse the ray ray.origin = ray.GetPoint(largestDimension); ray.direction = -ray.direction; RaycastHit info; Physics.Raycast(ray, out info, instance.boundsMask); target = info.point; //Debug.DrawLine(start, target, color: Color.white, duration: .2f); Vector3 lastImpact = target; ProcessIntersection onIntersect = (result => { result.GetObstacle().HitBy(projectile); Vector3 location = result.GetPosition(); float power = projectile.GetStrength(); float suppressiveRadius = projectile.GetSuppressiveRadius(); lastImpact = location; EnvironmentInteractions.ProjectileInstantImpactEffect(location, suppressiveRadius, power); projectile.SlowedBy(result.GetObstacle()); }); ShouldContinueRayCast continueCondition = (result => { return(projectile.IsStillActive()); }); IncrementalRaycast(start, target, onIntersect, continueCondition); projectile.ResetStrength(); Debug.DrawLine(start, lastImpact, color: Color.white, duration: .2f); }
public static float FindHeightAt(float x, float z) { float height = 0; ProcessIntersection onIntersect = (result => { height = result.GetPosition().y; }); ShouldContinueRayCast continueCondition = (result => { return(result.GetObstacle().CanPhaseThrough()); }); IncrementalRaycast( new Vector3(x, instance.bottomLeftCorner.y + instance.maxDimensions.y, z), new Vector3(x, instance.bottomLeftCorner.y, z), onIntersect, continueCondition ); return(height); }
public static bool ProjectileCanPassThrough(Projectile projectile, Vector3 start, Vector3 target) { var data = new Tuple <Projectile, Vector3, Vector3>(projectile, start, target); if (instance.projectileCanPassThroughCache.ContainsKey(data)) { return(instance.projectileCanPassThroughCache[data]); } ProcessIntersection onIntersect = (result => { projectile.SlowedBy(result.GetObstacle()); }); ShouldContinueRayCast continueCondition = (result => { return(projectile.IsStillActive()); }); IncrementalRaycast(start, target, onIntersect, continueCondition); bool passedThrough = projectile.IsStillActive(); projectile.ResetStrength(); // ProcessIntersectionFast onIntersect = (result => { // for(int i = 0; i < result.Count; i++) { // var r = result[i]; // projectile.SlowedBy(r.GetObstacle()); // } //}); //ShouldContinueRayCastFast continueCondition = (result => { // return projectile.IsStillActive(); //}); //IncrementalRaycastFast (start, target, onIntersect,continueCondition); //bool passedThrough = projectile.IsStillActive (); //projectile.ResetStrength (); instance.projectileCanPassThroughCache[data] = passedThrough; if (instance.projectileCanPassThroughCache.Count > PROJECTILE_CAN_PASS_THROUGH_CACHE_MAX_SIZE) { instance.projectileCanPassThroughCache.PopFirst(); } return(passedThrough); }
public static Vector3 ScreenToEnvironmentPoint(GameplayCamera cam, Vector3 screenPoint) { Vector3 environmentPoint = new Vector3(); Camera camera = cam.GetCamera(); Ray rayFromMouse = camera.ScreenPointToRay(screenPoint); Vector3 origin = rayFromMouse.origin; Vector3 direction = rayFromMouse.direction; Vector3 end = origin + (direction * cam.GetMaxDistanceFromFocus() * 2); environmentPoint = origin; ProcessIntersection onIntersect = (result) => { environmentPoint = result.GetPosition(); }; ShouldContinueRayCast shouldContinue = (result) => { return(false); }; IncrementalRaycast(origin, end, onIntersect, shouldContinue); return(environmentPoint); }
public static bool LineOfSightToVantagePointExists(int visionSharpness, Vector3 start, Vector3 target) { //Profiler.BeginSample("Fast"); //bool uninterrupted = true; //int clarityLeft = visionSharpness; //ProcessIntersectionFast onIntersect = (result => { // for (int i = 0; i < result.Count; i++) { // IntersectionResult r = result[i]; // clarityLeft -= r.GetObstacle().GetTransparency(); // } // if (clarityLeft <= 0) { // uninterrupted = false; // } //}); //ShouldContinueRayCastFast continueCondition = (result => { // return clarityLeft > 0; //}); //IncrementalRaycastFast(start, target, onIntersect, continueCondition); //Profiler.EndSample(); Profiler.BeginSample("Regular"); bool uninterrupted2 = true; int clarityLeft2 = visionSharpness; ProcessIntersection onIntersect2 = (result => { clarityLeft2 -= result.GetObstacle().GetTransparency(); if (clarityLeft2 <= 0) { uninterrupted2 = false; } }); ShouldContinueRayCast continueCondition2 = (result => { return(clarityLeft2 > 0); }); IncrementalRaycast(start, target, onIntersect2, continueCondition2); Profiler.EndSample(); return(uninterrupted2); }
public static List <MapNode> CreateMapNodesAt(List <Vector2> locations) { List <Tuple <Vector2, ParallelIncrementalRaycastResult> > results = new List <Tuple <Vector2, ParallelIncrementalRaycastResult> >(); for (int i = 0; i < locations.Count; i++) { results.Add( new Tuple <Vector2, ParallelIncrementalRaycastResult>( locations[i], new ParallelIncrementalRaycastResult() ) ); } List <ParallelIncrementalRaycastData> raycastData = new List <ParallelIncrementalRaycastData>(); for (int i = 0; i < results.Count; i++) { var tuple = results[i]; ParallelIncrementalRaycastResult result = tuple.Item2; Vector2 location = tuple.Item1; float x = location.x; float z = location.y; result.walkable = true; result.heightSet = false; ProcessIntersection onIntersect = (r => { if (!result.heightSet && !r.GetObstacle().CanPhaseThrough()) { result.height = r.GetPosition().y; result.heightSet = true; } if (!r.GetObstacle().IsWalkable()) { result.walkable = false; } result.layers.Add( new IntersectionResult( r.GetPosition(), r.GetObstacle() ) ); result.speedModifier *= r.GetObstacle().GetSpeedModifier(); }); ShouldContinueRayCast continueCondition = (r => { return(true); }); raycastData.Add( new ParallelIncrementalRaycastData( new Vector3(x, instance.bottomLeftCorner.y + instance.maxDimensions.y, z), new Vector3(x, instance.bottomLeftCorner.y, z), onIntersect, continueCondition ) ); } ParallelIncrementalRaycast(raycastData); List <MapNode> mapNodes = new List <MapNode>(); for (int i = 0; i < results.Count; i++) { var tuple = results[i]; ParallelIncrementalRaycastResult result = tuple.Item2; Vector2 location = tuple.Item1; MapNode newMapNode = Pools.MapNode; newMapNode.Set( new Vector3(location.x, result.height, location.y), result.height, result.layers, result.walkable ); mapNodes.Add( newMapNode ); } return(mapNodes); }