/// <summary> /// Calculate the trajectory of a rigidbody /// </summary> /// <param name="rb">The rigidbody of which to get the trajectory</param> /// <param name="timeStep">The interval between two nodes in the calculated trajectory</param> /// <returns>An array of trajectorynodes which make up the trajectory</returns> private TrajectoryNode[] GetRigidbodyTrajectory(Rigidbody rb, float timeStep) { TrajectoryNode[] trajectory = new TrajectoryNode[100]; for (int i = 0; ; i++) { trajectory[i] = new TrajectoryNode { Index = i, Position = PlotTrajectoryAtTime(rb.position, rb.velocity, i * timeStep), Timestep = i * timeStep }; if (i > 0 && Physics.Linecast(trajectory[i - 1].Position, trajectory[i].Position, 1 << LayerMask.NameToLayer("Default"))) { Array.Copy(trajectory, trajectory = new TrajectoryNode[i], i); return(trajectory); } } }
/// <summary> /// Checks if aim assist should activate. /// </summary> /// <param name="trajectory"></param> /// <param name="target"></param> /// <param name="closestNode">The closest descending node to the <paramref name="target"/></param> /// <returns></returns> private bool ShouldAssistThrow(TrajectoryNode[] trajectory, ThrowTarget target, out TrajectoryNode closestNode) { //Get all nodes in range of the target, where the node is descending compared to the previous node. Ascending nodes are ignored because they don't indicate a good trajectory. var possibleNodes = trajectory .Where(n => n.Index > 0 && trajectory[n.Index - 1].Position.y > trajectory[n.Index].Position.y && Vector3.Distance(n.Position, target.TargetCollider.ClosestPoint(n.Position)) < target.MaxAssistDistance).ToArray(); //No potential nodes found if (possibleNodes.Length == 0) { closestNode = trajectory[0]; return(false); } //Get closest potential node closestNode = possibleNodes .OrderBy(n => Vector3.Distance(n.Position, target.TargetCollider.ClosestPoint(n.Position))) .FirstOrDefault(); return(true); }