/// <summary> /// /// </summary> /// <param name="legs"></param> /// <param name="motions"></param> /// <param name="minPathTime"></param> /// <param name="pointSpeeds"></param> /// <param name="transform"></param> /// <param name="cycleTimestep"></param> /// <param name="gaitPointsIn"></param> public void ComputePositions(List <WalkController.LegData> legs, Motion[] motions, float minPathTime, float[] pointSpeeds, Transform transform, float cycleTimestep, WalkController.Point[] gaitPointsIn) { for (int i = 0; i < legs.Count; i++) { WalkController.LegData leg = legs[i]; //Difference between the previous gait position and where it would be on the new motion but at the current timestep leg.gaitError.position += Util.FlattenY(leg.gaitPoint.position - gaitPointsIn[i].position); leg.gaitError.angle += leg.gaitPoint.angle - gaitPointsIn[i].angle; //The gait position on the new motion path updated by the current timestep leg.gaitPoint = ComputePointPosition(_channels[i], leg.point, motions[i], minPathTime, pointSpeeds[i], transform); if (_channels[i].IsStriding) { leg.finalPoint.position = leg.gaitPoint.position + leg.gaitError.position; leg.finalPoint.angle = leg.gaitPoint.angle + leg.gaitError.angle; Debug.DrawRay(transform.TransformPoint(leg.gaitPoint.position), transform.TransformDirection(leg.gaitError.position), new Color(0.75f, 0.75f, 0.75f)); float timeRemaining = _channels[i].StrideDurationRemaining(); if (timeRemaining > 0.0f) { float spd = Mathf.Min(leg.gaitError.position.magnitude * (cycleTimestep / timeRemaining), 0.005f); float spdA = Mathf.Min(Mathf.Abs(leg.gaitError.angle) * (cycleTimestep / timeRemaining), 0.5f); leg.gaitError.position = Vector3.MoveTowards(leg.gaitError.position, Vector3.zero, spd); leg.gaitError.angle = Mathf.MoveTowards(leg.gaitError.angle, 0.0f, spdA); } } } }
/// <summary> /// Checks all of the legs to see which have completed their strides. Uses raycasts against collision objects to perform these checks /// </summary> /// <param name="legs">The final positions of all legs</param> /// <param name="transform">The transform to use to convert the local leg positions in to world positions</param> public void CheckForStridesComplete(List <WalkController.LegData> legs, Transform transform) { _anyChannelsStriding = false; _fOverrun = 0.0f; for (int i = 0; i < legs.Count; i++) { WalkController.LegData leg = legs[i]; bool bEnded = false; _fOverrun = Mathf.Max(_channels[i].CheckForStrideComplete(transform.TransformPoint(leg.finalPoint.position), out bEnded), _fOverrun); if (bEnded) { leg.gaitError = new WalkController.Point(Vector3.zero, 0.0f); } else if (_channels[i].IsStriding) { _anyChannelsStriding = true; } } if (!_anyChannelsStriding) { ApplyQueuedGait(); } }
/// <summary> /// Checks all of the legs to see which should start their next strides /// </summary> /// <param name="legs">The final points and gait points of all legs (sets gaitError)</param> public void CheckForNewStrides(List <WalkController.LegData> legs) { //If there is a queued gait then we want the current gait to end completely first, //And we don't want new strides to start if any are overrunning if ((_queuedGait == null) && (_fOverrun == 0.0f)) { for (int i = 0; i < _channels.Length; i++) { WalkController.LegData leg = legs[i]; //Attempt to start the next stride if (_channels[i].AttemptNextStride(_cycleTime)) { leg.gaitError.position = Util.FlattenY(leg.finalPoint.position - leg.gaitPoint.position); leg.gaitError.angle = leg.finalPoint.angle - leg.gaitPoint.angle; } } } }