/// <summary> /// Attempts to generate a bouncy richochet path. Not guaranteed to leave make path successful /// </summary> /// <param name="mode"></param> /// <param name="path"></param> /// <param name="angleBundle"></param> void attemptBonucyRicochetPath(ricochetMode mode, RicochetPath path, Vector3 angleBundle) { Vector3 launchVector = generateLaunchVector(angleBundle); //Calculating launch direction Vector3 objectPositionWhenContactMade = generateStartingContactPoint(mode) + launchVector * _ricochetObjectRadius; //Calculating the starting point //Calculating the ricochet points... path.ricochetPositions.Add(objectPositionWhenContactMade); RaycastHit hitResults = new RaycastHit(); for (int i = 0; i < maxNumberofBounces; i++) { Physics.SphereCast(objectPositionWhenContactMade, _ricochetObjectRadius, launchVector, out hitResults, maxPathSegmentLength, interactingLayers, QueryTriggerInteraction.Ignore); if (hitResults.collider == null) //Nothing was hit... { path.ricochetPositions.Add(objectPositionWhenContactMade + launchVector * maxPathSegmentLength); break; } else if (hitResults.collider.gameObject.layer == LayerMask.NameToLayer(destinationLayer)) { //Found where it was supposed to go! End here objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector; path.ricochetPositions.Add(objectPositionWhenContactMade); path.isSuccessful = true; break; } else //Just hit a bouncing surface { objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector; path.bounces++; path.ricochetPositions.Add(objectPositionWhenContactMade); launchVector = Vector3.Reflect(launchVector, hitResults.normal); } } }
public void initialize(RicochetPath path) { rotationVector = UnityEngine.Random.onUnitSphere * rotationSpeed; speed = difficultyCurveHolder.getCurrentValue(difficultyCurveHolder.Instance.richochetCubeSpeed); setPath(path); GetComponent <timedSelfDestruct>().startTimer(); }
void launchRichochetCube(RicochetTracer.ricochetMode mode) { RicochetPath path = GetComponentInChildren <RicochetTracer>().GenerateSuccessfulPath(mode); if (!path.isSuccessful) { return; } GameObject cube = objectPooler.Instance.requestObject("ricochetCube"); cube.transform.position = transform.parent.position; cube.GetComponent <ricochetCube>().initialize(path); }
/// <summary> /// Generates a straight path to the corruption sphere. /// If the scene is set up properly, this code should never leave path unsuccessful. /// </summary> /// <param name="mode"></param> /// <param name="path"></param> void generateGuaranteedPath(ricochetMode mode, RicochetPath path) { Vector3 launchVector = Vector3.forward; Vector3 objectPositionWhenContactMade = generateStartingContactPoint(mode) + launchVector * _ricochetObjectRadius; //Calculating the starting point //Calculating the ricochet points... path.ricochetPositions.Add(objectPositionWhenContactMade); RaycastHit hitResults = new RaycastHit(); Physics.SphereCast(objectPositionWhenContactMade, _ricochetObjectRadius, launchVector, out hitResults, maxPathSegmentLength, destinationLayerMask, QueryTriggerInteraction.Ignore); if (hitResults.collider == null) //Nothing was hit... { return; //Worse case scenario } else { objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector; path.ricochetPositions.Add(objectPositionWhenContactMade); path.isSuccessful = true; } }
/// <summary> /// Draws a path on the editor /// </summary> /// <param name="path"> Supplying no path will just render the editor's debug path</param> public void drawRichochetPath(RicochetPath path = null) { if (path == null) { if (editorRicochetPath == null) { setEditorPath(); } path = editorRicochetPath; } for (int i = 0; i < path.ricochetPositions.Count - 1; i++) { //I'm drawing based off the objrct positond, but since the object has a raduis I have to extend the drawing to account for its volume. Vector3 segmentVector = (-path.ricochetPositions[i] + path.ricochetPositions[i + 1]).normalized; DebugExtension.DrawCapsule(path.ricochetPositions[i] + -segmentVector * ricochetObjectRadius, path.ricochetPositions[i + 1] + segmentVector * ricochetObjectRadius, getDrawingColor(path.mode), _ricochetObjectRadius); } foreach (Vector3 point in path.ricochetPositions) { DebugExtension.DrawPoint(point, Color.blue, 1); } }
/// <summary> /// Genertates a richochet path. If the scene is set up properly, this is guaranteeded to return a successful path. Check just in case, though. /// </summary> /// <param name="mode"></param> /// <returns></returns> public RicochetPath GenerateSuccessfulPath(ricochetMode mode) { RicochetPath path = new RicochetPath(); path.mode = mode; Vector3 angleBundle = getAngleBundle(mode); for (int attempt = 0; attempt < 100; attempt++) { attemptBonucyRicochetPath(mode, path, angleBundle); if (path.isSuccessful) { break; } path.reset(); } if (!path.isSuccessful) { generateGuaranteedPath(mode, path); } return(path); }
void setPath(RicochetPath path) { this.path = path; destinationPointIndex = path.ricochetPositions.Count - 1; positionForFollowing(); }
public void setEditorPath() { editorRicochetPath = GenerateSuccessfulPath(editorRicochetMode); }