public RaycastHit2D IntersectionFollowingImpulse(Vector2 impulse, params Condition <RaycastHit2D>[] conditions) { //Debug.Log(GetType().Name + " (" + Time.realtimeSinceStartup + ") -> public RaycastHit2D IntersectionFollowingImpulse(Vector2 impulse, params Condition<RaycastHit2D>[] conditions)"); validHitConditions = conditions; Vector2[] curvePoints = MxArithmetic.CurvePoints(Physics2D.gravity, Velocity + impulse, Origin, MaxExtrapolationDeltaT, TrajectorySegments); for (int i = 0; i < TrajectorySegments - 1; i++) { RaycastHit2D hit = Physics2D.Linecast(curvePoints[i], curvePoints[i + 1]); if (visualizeTrajectory && i % 2 == 0) { Debug.DrawLine(curvePoints[i], curvePoints[i + 1]); } if (hit.collider != null && hit.collider.gameObject != gameObject) { foreach (Condition <RaycastHit2D> meetsCondition in conditions) { if (!meetsCondition(hit)) { continue; } } return(hit); } } return(LastKnownIntersection); }
/// <summary> /// <para>Uses the object's ballistic trajectory to (attempt to) predict its position at a given height.</para> /// <para>Returns 'null' when unable to make a prediction.</para> /// </summary> Vector2?PredictPositionAtHeight(float height) { Vector2?prevPoint = null; foreach (Vector2 point in MxArithmetic.CurvePoints(Physics2D.gravity, EstimatedVelocity, transform.position, 5f, 100)) { if (prevPoint != null && MxArithmetic.IsValueInRange(height, point.y, prevPoint.Value.y)) { return(.5f * (point + prevPoint)); } prevPoint = point; } return(null); }
public static void UnsignedFloatField(string labelText, ref float value) { FloatField(labelText, ref value); MxArithmetic.Unsigned(ref value); }
void FixedUpdate() { //float mockOutput; //if (rigidbody2D.velocity.y > 0f || !groundDetector.PerformRaycast(out mockOutput)) // return; Line[] foundSurfaces = IdentifySurfaces(); Plane[] surfacePlanes = Line.ToPlanes2D(foundSurfaces); Vector2?targetDeltaV = null; /* Continuously raycast along ballistic trajectories (starting from their peaks) * derived from randomized velocity changes (within the specified delta-V budget). */ for (int i = 0; i < maxTrajectoryEvaluations; i++) { Vector2 deltaV; switch (impulseMode) { case ImpulseMode.Incremental: deltaV = minVelocity + (maxVelocity - minVelocity) * i / maxTrajectoryEvaluations; break; case ImpulseMode.Random: deltaV = RandomValidDeltaV; break; default: throw new InvalidOperationException(); } Vector2?prevPoint = null; foreach (Vector2 point in MxArithmetic.CurvePoints(GetComponent <Rigidbody2D>().gravityScale *Physics2D.gravity, GetComponent <Rigidbody2D>().velocity + deltaV, GetComponent <Rigidbody2D>().position + feetPosition, 5f, 100)) { if (prevPoint != null && point.y < prevPoint.Value.y) { Debug.DrawLine(prevPoint.Value, point, Color.red); for (int j = 0; j < foundSurfaces.Length; j++) { Plane plane = surfacePlanes[j]; Vector2 delta = point - prevPoint.Value; Ray ray = new Ray(prevPoint.Value, delta); float intersectionDist; if (plane.Raycast(ray, out intersectionDist)) { Vector2 landingPoint = prevPoint.Value + intersectionDist * delta.normalized; if (MxArithmetic.IsValueInRange(landingPoint.x, foundSurfaces[j].start.x, foundSurfaces[j].end.x) && MxArithmetic.IsValueInRange(intersectionDist, 0f, delta.magnitude)) { targetDeltaV = deltaV; //if (showChosenLandingSites) // Debug.DrawLine(landingPoint, (Vector3)landingPoint + Vector3.up, Color.yellow, 1f); storedLandingSiteData.AddLast(new LandingSiteData(landingPoint, Vector2.up)); goto ApplyDeltaV; } } } } else if (prevPoint != null) { Debug.DrawLine(prevPoint.Value, point, Color.green); } prevPoint = point; } prevPoint = null; } return; ApplyDeltaV: //rigidbody2D.velocity += targetDeltaV.Value; GetComponent <Rigidbody2D>().velocity += jumpMultiplier * targetDeltaV.Value; //jumpMultiplier = 1f; onJump.Invoke(); }
protected Vector2[] TrajectoryCurvePoints() { return(MxArithmetic.CurvePoints(Physics2D.gravity, Velocity, Position + offset, maxExtrapolationDeltaT, trajectorySegments)); }