/// <summary> /// /// </summary> /// <returns></returns> private bool CanStopWalking() { bool allPointsInRange = true; for (int i = 0; i < _legList.Count; i++) { if (_gaitGenerator.IsStriding(i)) { allPointsInRange = false; break; } else { LegData leg = _legList[i]; Vector3 flattened = Util.FlattenY(leg.finalPoint.position); float distanceSq = (flattened - leg.point.Position).sqrMagnitude; //Is this leg still outside its stop area? if (distanceSq >= leg.region.StopRadius * leg.region.StopRadius) { allPointsInRange = false; break; } if (Mathf.Abs(leg.finalPoint.angle - leg.point.Angle) > 0.1f) { allPointsInRange = false; break; } } } return(allPointsInRange); }
/// <summary> /// /// </summary> /// <param name="legMotions"></param> /// <param name="heightDiff"></param> private void ApplyInverseMotionToStancedLegs(Motion[] legMotions, float heightDiff) { for (int i = 0; i < _legList.Count; i++) { if (legMotions[i].HasRotation()) { float rotationAmount = legMotions[i].AngularVelocity; Vector3 localRotOrigin = legMotions[i].RotationOrigin; if (!_gaitGenerator.IsStriding(i)) { LegData leg = _legList[i]; leg.finalPoint.position = Util.Rotate(leg.finalPoint.position - localRotOrigin, -rotationAmount) + localRotOrigin; leg.finalPoint.position.y += heightDiff; leg.finalPoint.angle -= rotationAmount; } } else if (legMotions[i].HasTranslation()) { if (!_gaitGenerator.IsStriding(i)) { LegData leg = _legList[i]; leg.finalPoint.position -= legMotions[i].LinearVelocity; leg.finalPoint.position.y += heightDiff; } } } }
/// <summary> /// /// </summary> /// <returns></returns> private bool ShouldStartWalking() { bool anyPointsOutOfRange = false; for (int i = 0; i < _legList.Count; i++) { if (_gaitGenerator.IsStriding(i)) { anyPointsOutOfRange = true; break; } else { LegData leg = _legList[i]; Vector3 flattened = Util.FlattenY(leg.finalPoint.position); float distanceSq = (flattened - leg.point.Position).sqrMagnitude; //Is this leg now outside of its start area? if (distanceSq > leg.region.StartRadius * leg.region.StartRadius) { anyPointsOutOfRange = true; break; } if (Mathf.Abs(leg.finalPoint.angle - leg.point.Angle) > 45.0f) { anyPointsOutOfRange = true; break; } } } return(anyPointsOutOfRange); }
/// <summary> /// /// </summary> /// <param name="parent"></param> /// <param name="legList"></param> private void FindChildFeet(Transform parent, List <LegData> legList) { foreach (Transform child in parent) { FootMotionRegion region = child.GetComponent <FootMotionRegion>(); if (region != null) { MotionPoint initialPoint = MotionPoint.FromTransform(_bodyTransform, region.transform, _rootPoint); LegData stuff = new LegData { region = region, point = initialPoint, debugLastPosition = region.transform.position + new Vector3(0.0f, 0.0f, 0.0f),// stuff.channel.Height, stuff.channel.Offset); gaitPoint = new Point(initialPoint.Position, initialPoint.Angle), gaitError = new Point(Vector3.zero, 0.0f), finalPoint = new Point(initialPoint.Position, initialPoint.Angle), }; legList.Add(stuff); } else { //The child isn't anything so look at its children FindChildFeet(child, legList); } } }
void BuildLeg(Transform bodyParent, Transform hipParent, LegData legData, float hipWidth, string prefix) { GameObject hipPivot = new GameObject(prefix + "hipPivot"); GameObject hip = new GameObject(prefix + "hip"); GameObject thigh = new GameObject("thigh"); GameObject calf = new GameObject("calf"); GameObject foot = new GameObject("foot"); GameObject toe = new GameObject("toe"); GameObject thighMesh = NewBodySegment(legData.thighData, "thighMesh"); GameObject calfMesh = NewBodySegment(legData.calfData, "calfMesh"); GameObject footMesh = NewBodySegment(legData.footData, "footMesh"); GameObject toeMesh = NewBodySegment(legData.toeData, "toeMesh"); // Set up object heirarchy here hipPivot.transform.parent = hipParent.transform; hip.transform.parent = bodyParent; thigh.transform.parent = hip.transform; calf.transform.parent = thigh.transform; foot.transform.parent = calf.transform; toe.transform.parent = foot.transform; thighMesh.transform.parent = thigh.transform; calfMesh.transform.parent = calf.transform; footMesh.transform.parent = foot.transform; toeMesh.transform.parent = toe.transform; // Set up joint position offsets hipPivot.transform.localPosition = new Vector3(0.0f, 0.0f, hipWidth); // This one is not actually necessary as it is animated to always snap to hipPivot hip.transform.localPosition = hipPivot.transform.position; calf.transform.localPosition = new Vector3(0.0f, legData.thighData.length, 0.0f); foot.transform.localPosition = new Vector3(0.0f, legData.calfData.length, 0.0f); toe.transform.localPosition = new Vector3(0.0f, legData.footData.length, 0.0f); }
/// <summary> /// /// </summary> /// <param name="futureRoot"></param> /// <param name="motions"></param> /// <param name="pointSpeeds"></param> /// <param name="minPathTime"></param> /// <param name="maxPointSpeed"></param> private void AllLegPathFactors(MotionPoint futureRoot, out Motion[] motions, out float[] pointSpeeds, out float minPathTime, out float maxPointSpeed) { motions = new Motion[_legList.Count]; pointSpeeds = new float[_legList.Count]; minPathTime = float.PositiveInfinity; maxPointSpeed = 0.0f; //Compute the individual foot point motions as a result of applying the previous motion to the root for (int i = 0; i < _legList.Count; i++) { LegData leg = _legList[i]; //Compute the motion that would have resulted in the leg's point moving to the future point MotionPoint futurePoint = leg.point.RelativeTo(futureRoot); motions[i] = Motion.Between(leg.point, futurePoint); minPathTime = Mathf.Min(minPathTime, leg.region.BoundedPathFactors(leg.point, motions[i], _gaitGenerator.MaxStanceRatio(i), out pointSpeeds[i], _bodyTransform)); maxPointSpeed = Mathf.Max(maxPointSpeed, pointSpeeds[i]); } }
public void CreateNewSpecies() { // First we must generate all random variables // First, define leg dimensions // Note, radii should always be less than length for stability, and ideally much less float frontHipRadius = 0.5f; float frontThighLength = 0.7f; float frontThighRoundness = 0.6f; float frontKneeRadius = 0.4f; float frontCalfLength = 0.7f; float frontCalfRoundness = 0.3f; float frontAnkleRadius = 0.3f; float frontFootLength = 0.6f; float frontFootRoundness = 0.6f; float frontFootRadius = 0.4f; float frontToeLength = 0.5f; float frontToeRoundness = 0.5f; float frontToeRadius = 0.3f; float backHipRadius = 0.7f; float backThighLength = 1.3f; float backThighRoundness = 0.3f; float backKneeRadius = 0.4f; float backCalfLength = 1.2f; float backCalfRoundness = 0.6f; float backAnkleRadius = 0.3f; float backFootLength = 0.6f; float backFootRoundness = 0.7f; float backFootRadius = 0.2f; float backToeLength = 0.3f; float backToeRoundness = 0.9f; float backToeRadius = 0.1f; // Data containers must be created for each segment BodySegmentMeshData fr_thighData = new BodySegmentMeshData(frontThighLength, frontHipRadius, frontKneeRadius, frontThighRoundness, 12); BodySegmentMeshData fr_calfData = new BodySegmentMeshData(frontCalfLength, frontKneeRadius, frontAnkleRadius, frontCalfRoundness, 12); BodySegmentMeshData fr_footData = new BodySegmentMeshData(frontFootLength, frontAnkleRadius, frontFootRadius, frontFootRoundness, 12); BodySegmentMeshData fr_toeData = new BodySegmentMeshData(frontToeLength, frontFootRadius, frontToeRadius, frontToeRoundness, 12); BodySegmentMeshData bk_thighData = new BodySegmentMeshData(backThighLength, backHipRadius, backKneeRadius, backThighRoundness, 12); BodySegmentMeshData bk_calfData = new BodySegmentMeshData(backCalfLength, backKneeRadius, backAnkleRadius, backCalfRoundness, 12); BodySegmentMeshData bk_footData = new BodySegmentMeshData(backFootLength, backAnkleRadius, backFootRadius, backFootRoundness, 12); BodySegmentMeshData bk_toeData = new BodySegmentMeshData(backToeLength, backFootRadius, backToeRadius, backToeRoundness, 12); // LegData objects can now be created by passing in segment data // Front and back legs have separate leg data m_frontLegData = new LegData(fr_thighData, fr_calfData, fr_footData, fr_toeData); m_frontLegData.reverseKnee = true; // Front legs bend the opposite way m_backLegData = new LegData(bk_thighData, bk_calfData, bk_footData, bk_toeData); // Creating the leg data has also defined the height at which each leg stands // Use this to set the default heights for the spine float shoulderHeight = m_frontLegData.legLength; float pelvisHeight = m_backLegData.legLength; // Define other random variables for the spine float shoulderRadius = 0.8f; float torsoLength = 1.2f; float torsoRoundness = 0.8f; float chestRadius = 1.0f; float waistLength = 1.5f; float waistRoundness = 0.2f; float waistRadius = 0.8f; float pelvisLength = 1.2f; float pelvisRoundness = 0.4f; float hipRadius = 0.6f; BodySegmentMeshData torsoData = new BodySegmentMeshData(torsoLength, chestRadius, shoulderRadius, torsoRoundness, 20); BodySegmentMeshData waistData = new BodySegmentMeshData(waistLength, waistRadius, chestRadius, waistRoundness, 20); BodySegmentMeshData pelvisData = new BodySegmentMeshData(pelvisLength, hipRadius, waistRadius, pelvisRoundness, 20); m_spineData = new SpineData(torsoData, waistData, pelvisData, 0.0f, 0.0f); Debug.Log("Checking, spine length is " + m_spineData.spineLength); m_legSeparation = Mathf.Sqrt(m_spineData.spineLength * m_spineData.spineLength - (shoulderHeight - pelvisHeight) * (shoulderHeight - pelvisHeight)); m_spineElevation = Mathf.Rad2Deg * Mathf.Asin((shoulderHeight - pelvisHeight) / m_spineData.spineLength); Debug.Log("Leg separation: " + m_legSeparation + ", Spine elevation: " + m_spineElevation); // Define tail dimensions m_tailLength = 5.0f; m_tailTaper = 0.8f; m_tailSegments = 6; // Create animations // Animations are based only on species variables defined above //AnimationGenerator animGenerator = new AnimationGenerator(this); //m_clips = animGenerator.GenerateAnimation(); m_clips = new ClipContainer(this); m_clips.EnableAnimationGroup(ClipContainer.AnimType.IDLE); //ClipContainer clips = new ClipContainer(species); //clips.EnableAnimationGroup(ClipContainer.AnimType.IDLE); Debug.Log("m_clips = " + m_clips); }
public static SimpleLeg spawnLeg(GameObject body, Object legPrefab, Object footPrefab, LegData legData, float footXOffset, string nameDecorator) { Vector3 spawnPoint = body.transform.position; Quaternion rotation = body.transform.rotation; SimpleLeg newLeg; spawnPoint.y = spawnPoint.y - 0.5f; newLeg = ((GameObject)Object.Instantiate(legPrefab, spawnPoint, rotation)).GetComponent<SimpleLeg>(); newLeg.name = legPrefab.name + " " + nameDecorator + " -- (" + body.name + ")"; newLeg.legData = legData; newLeg.thigh = newLeg.GetComponent<SliderJoint2D>(); newLeg.thigh.connectedBody = body.rigidbody2D; spawnPoint.x = spawnPoint.x + footXOffset; spawnPoint.y = spawnPoint.y - .25f; newLeg.foot = ((GameObject)Object.Instantiate(footPrefab, spawnPoint, rotation)).GetComponent<SliderJoint2D>(); newLeg.foot.connectedBody = newLeg.thigh.rigidbody2D; newLeg.foot.name = footPrefab.name + " " + nameDecorator + " -- (" + body.name + ")"; return newLeg; }
/// <summary> /// /// </summary> /// <param name="futureRoot"></param> /// <param name="bodyMotion"></param> /// <param name="heightCorrectionCalc"></param> public void Update(MotionPoint futureRoot, Motion bodyMotion, out float heightCorrectionCalc, out float speedMultiplier, out float cyclesPerSecond) { heightCorrectionCalc = 0.0f; speedMultiplier = 1.0f; //Update the position of the leg points based on any animations that may have happened UpdateLegPoints(); //Now check if if (ShouldStartWalking()) { if (!_isWalking) { _balanceTransformStable = false; } _isWalking = true; } //TODO need to update below (as some point post conference) to account for chaining (centipede) causing rear segments to have completely different motions than the root //All the compute position stuff seems to be geared up for it, in that each leg is handled with its own motion, but we currently don't use chained motion points //May want to have a way in unity scene to define the hierachy, then MotionPoint baking "should" take care of the rest. //Calculate what the motion for each leg is as well as their speeds and other path factors, based on if they had been moved to the future root Motion[] motions; float[] pointSpeeds; float minPathTime, maxPointSpeed; AllLegPathFactors(futureRoot, out motions, out pointSpeeds, out minPathTime, out maxPointSpeed); //-------------------------------------------------- cyclesPerSecond = 0.0f; Point[] updatedGaitPoints = new Point[_legList.Count]; if (_isWalking) { if (_balanceTransformStable) { _gaitGenerator.CheckForNewStrides(_legList); } if (!float.IsPositiveInfinity(minPathTime)) { cyclesPerSecond = _gaitGenerator.CalcCyclesPerSecond(minPathTime, _minCyclesPerSecond, _maxCyclesPerSecond, pointSpeeds, maxPointSpeed); //Clamp the cycles per second, adjusting other values accordingly if (cyclesPerSecond > _maxCyclesPerSecond) { //Scale down the body speed to keep the maximum cycles per second speedMultiplier *= _maxCyclesPerSecond / cyclesPerSecond; cyclesPerSecond = _maxCyclesPerSecond; } else if (cyclesPerSecond < _minCyclesPerSecond) { //Scale down the path to keep the minimum cycles per second minPathTime *= cyclesPerSecond / _minCyclesPerSecond; cyclesPerSecond = _minCyclesPerSecond; } } else { cyclesPerSecond = _minCyclesPerSecond; } Debug.Log("CPS = " + cyclesPerSecond.ToString() + ", Slowdown = " + speedMultiplier.ToString()); _gaitGenerator.ComputePreUpdatePositions(_legList, motions, minPathTime, pointSpeeds, _bodyTransform, cyclesPerSecond * Time.deltaTime, updatedGaitPoints); _gaitGenerator.Update(cyclesPerSecond * Time.deltaTime); //-------------------------------------------------- heightCorrectionCalc = _gaitGenerator.MeanStancedHeight() * -_heightCorrection; float displacementCorrection = 0.0f; if (minPathTime > 0.0f) { displacementCorrection = (-Time.deltaTime * speedMultiplier) / minPathTime; } _gaitGenerator.ApplyOffset(heightCorrectionCalc, displacementCorrection); for (int i = 0; i < _legList.Count; i++) { motions[i] = motions[i].Scaled(speedMultiplier); } } else { for (int i = 0; i < _legList.Count; i++) { LegData leg = _legList[i]; updatedGaitPoints[i] = new Point(leg.gaitPoint); } } //Apply the inverse of the body motion to the legs in contact with the ground ApplyInverseMotionToStancedLegs(motions, heightCorrectionCalc); //Compute the final points of all the legs _gaitGenerator.ComputePositions(_legList, motions, minPathTime, pointSpeeds, _bodyTransform, cyclesPerSecond * Time.deltaTime, updatedGaitPoints); //Apply the final leg points to the targets so that IK can align to them UpdateLegTargets(); }
/// <summary> /// Creates or updates a leg. /// </summary> /// <param name="legData">The detailed leg object.</param> /// <returns> /// The leg object returned from the service (including ID). /// </returns> public Leg CreateOrUpdate(LegData legData) { return(PostObject <Leg, LegData>(legData, "/api/v1/legs")); }
void BuildLegPair(Transform bodyParent, Transform hipParent, LegData legData, float hipWidth, string prefix) { BuildLeg(bodyParent, hipParent, legData, hipWidth, prefix + "L_"); BuildLeg(bodyParent, hipParent, legData, -hipWidth, prefix + "R_"); }
// This function must be called first to set up variables public void InitialiseLeg(Vector3 offset, LegData data) { thData = data.thighData; cData = data.calfData; fData = data.footData; toData = data.toeData; // Get variables from creature species // // // // MeshFilter filter; MeshRenderer renderer; BodySegmentMesh meshScript; Material mat = new Material(Shader.Find("Diffuse")); thighLength = thData.length; calfLength = cData.length; footLength = fData.length; toeLength = toData.length; legPivot = new GameObject("legPivot"); //legPivot.transform.position = new Vector3(0.0f,data.standHeight,0.0f); legPivot.transform.parent = transform; legPivot.transform.localPosition = Vector3.zero; // Create leg segments thighJoint = new GameObject("thighJoint"); filter = thighJoint.AddComponent <MeshFilter>(); renderer = thighJoint.AddComponent <MeshRenderer>(); meshScript = thighJoint.AddComponent <BodySegmentMesh>(); filter.sharedMesh = meshScript.BuildMesh(thData); renderer.material = mat; thighJoint.transform.parent = legPivot.transform; calfJoint = new GameObject("calfJoint"); calfJoint.transform.parent = thighJoint.transform; filter = calfJoint.AddComponent <MeshFilter>(); renderer = calfJoint.AddComponent <MeshRenderer>(); meshScript = calfJoint.AddComponent <BodySegmentMesh>(); filter.sharedMesh = meshScript.BuildMesh(cData); renderer.material = mat; footJoint = new GameObject("footJoint"); footJoint.transform.parent = calfJoint.transform; filter = footJoint.AddComponent <MeshFilter>(); renderer = footJoint.AddComponent <MeshRenderer>(); meshScript = footJoint.AddComponent <BodySegmentMesh>(); filter.sharedMesh = meshScript.BuildMesh(fData); renderer.material = mat; toeJoint = new GameObject("toeJoint"); toeJoint.transform.parent = footJoint.transform; filter = toeJoint.AddComponent <MeshFilter>(); renderer = toeJoint.AddComponent <MeshRenderer>(); meshScript = toeJoint.AddComponent <BodySegmentMesh>(); filter.sharedMesh = meshScript.BuildMesh(toData); renderer.material = mat; // Set up initial positions thighJoint.transform.localPosition = new Vector3(0.0f, 0.0f, 0.0f); thighJoint.transform.Rotate(0.0f, 0.0f, 180.0f); calfJoint.transform.Translate(0.0f, thighLength, 0.0f); footJoint.transform.Translate(0.0f, calfLength, 0.0f); toeJoint.transform.Translate(0.0f, footLength, 0.0f); toeJoint.transform.Rotate(0.0f, 0.0f, 90.0f); }
void WalkAnim(Transform rootPivot, Transform[] legPivots, LegData legData, float stepHeight, float stepLength) { float thighLength = legData.thighData.length; float calfLength = legData.calfData.length; float footLength = legData.footData.length; float toeLength = legData.toeData.length; float elevationAngle = legData.elevationAngle; float standHeight = legData.standHeight; bool reverseKnee = legData.reverseKnee; float animTime = 1.0f; // Generate rotation values int arrayLength = (int)(animTime / Time.deltaTime) + 1; Quaternion[] rootPivotQuats = new Quaternion[arrayLength]; rootPivotQuats[0] = rootPivot.localRotation; Quaternion[] pivotsQuats = new Quaternion[arrayLength]; Quaternion[] thighQuats = new Quaternion[arrayLength]; Quaternion[] calfQuats = new Quaternion[arrayLength]; Quaternion[] footQuats = new Quaternion[arrayLength]; float[] times = new float[arrayLength]; Vector4 angles; int counter = 0; for (float t = 0.0f; t < animTime; t += Time.deltaTime) { // Define transformOffset, target position Vector3 footPosition = WalkAnimPositionFunction(t, animTime, stepLength, stepHeight); if (counter > 0) { rootPivotQuats[counter] = rootPivotQuats[counter - 1] * Quaternion.Euler(0.0f, 0.0f, Mathf.Sin(2 * Mathf.PI * (t / animTime))); } //float hipOffsetX = -0.8f*Mathf.Sin((2*Mathf.PI)/animTime*(t)); //float hipOffsetY = 0.8f*Mathf.Cos((2*Mathf.PI)/animTime*(t+0.5f)); float hipOffsetX = 0.0f; float hipOffsetY = 0.0f; Vector3 transformOffset = new Vector3(0.0f, legPivots[0].position.y, 0.0f); angles = JointRotationSolver(transformOffset + new Vector3(hipOffsetX, hipOffsetY, 0.0f), new Vector2(footPosition.x, footPosition.y), thighLength, calfLength, footLength, elevationAngle, reverseKnee); pivotsQuats[counter] = Quaternion.Euler(0.0f, 0.0f, angles.w); thighQuats[counter] = Quaternion.Euler(0.0f, 0.0f, angles.x); calfQuats[counter] = Quaternion.Euler(0.0f, 0.0f, angles.y); footQuats[counter] = Quaternion.Euler(0.0f, 0.0f, angles.z); times[counter] = t; counter++; } /* * AnimationClip rootPivotClip = CreateLocalRotationClip(rootPivotQuats,times); * * AnimationClip hipPivotClip = CreateLocalRotationClip(pivotsQuats,times); * AnimationClip thighClip = CreateLocalRotationClip(thighQuats,times); * AnimationClip calfClip = CreateLocalRotationClip(calfQuats,times); * AnimationClip footClip = CreateLocalRotationClip(footQuats,times); * * AnimationClip[] clips = {hipPivotClip,thighClip,calfClip,footClip}; */ // Attach clips //rootPivot.animation.AddClip(rootPivotClip,"walk"); // Attach clips to leg for (int i = 0; i < 2 /*legPivots[i] != null*/; i++) { //Transform child = legPivots[i]; for (int j = 0; j < 4 /* Number of clips */; j++) { //child.GetComponent<Animation>().AddClip(clips[j],"walk"); //child = child.GetChild(0); } } }
void WalkAnimOld(Transform[] legPivots, LegData legData, /* float animTime, */ float stepHeight, float stepLength) { float thighLength = legData.thighData.length; float calfLength = legData.calfData.length; float footLength = legData.footData.length; float toeLength = legData.toeData.length; float elevationAngle = legData.elevationAngle; float standHeight = legData.standHeight; float animTime = 1.0f; AnimationClip[] clips = new AnimationClip[4]; clips[0] = new AnimationClip(); clips[1] = new AnimationClip(); clips[2] = new AnimationClip(); clips[3] = new AnimationClip(); AnimationCurve pivotCurveW = new AnimationCurve(); AnimationCurve pivotCurveX = new AnimationCurve(); AnimationCurve pivotCurveY = new AnimationCurve(); AnimationCurve pivotCurveZ = new AnimationCurve(); AnimationCurve pivotCurveOffX = new AnimationCurve(); AnimationCurve pivotCurveOffY = new AnimationCurve(); AnimationCurve thighCurveW = new AnimationCurve(); AnimationCurve thighCurveX = new AnimationCurve(); AnimationCurve thighCurveY = new AnimationCurve(); AnimationCurve thighCurveZ = new AnimationCurve(); AnimationCurve calfCurveW = new AnimationCurve(); AnimationCurve calfCurveX = new AnimationCurve(); AnimationCurve calfCurveY = new AnimationCurve(); AnimationCurve calfCurveZ = new AnimationCurve(); AnimationCurve footCurveW = new AnimationCurve(); AnimationCurve footCurveX = new AnimationCurve(); AnimationCurve footCurveY = new AnimationCurve(); AnimationCurve footCurveZ = new AnimationCurve(); //float animTime = 2.0f;//stepLength/walkSpeed; //float stepDistance = 3.0f; //float stepHeight = 1.0f; Vector4 angles; Vector4[] pivotAngles = new Vector4[(int)(animTime / Time.deltaTime)]; for (float t = 0.0f; t < animTime; t += Time.deltaTime) { // Calculate position offset based on t float xOffset = 0.0f; float yOffset = 0.0f; if (t < /*animTime*/ 1.0f / 2.0f) { yOffset = 0.0f; xOffset = stepLength * ((4.0f * t) / animTime - 1.0f); } else { yOffset = stepHeight * Mathf.Sin((2.0f * Mathf.PI) / (animTime) * t - Mathf.PI); xOffset = stepLength * Mathf.Cos((2.0f * Mathf.PI) / (animTime) * t - Mathf.PI); } //float hipOffsetX = -0.8f*Mathf.Sin((2*Mathf.PI)/animTime*(t)); //float hipOffsetY = 0.8f*Mathf.Cos((2*Mathf.PI)/animTime*(t+0.5f)); float hipOffsetX = 0.0f; float hipOffsetY = 0.0f; Vector3 transformOffset = new Vector3(0.0f, legPivots[0].position.y, 0.0f); angles = JointRotationSolver(transformOffset + new Vector3(hipOffsetX, hipOffsetY, 0.0f), new Vector2(xOffset, yOffset), thighLength, calfLength, footLength, elevationAngle, false); pivotCurveW.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.w).w); pivotCurveX.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.w).x); pivotCurveY.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.w).y); pivotCurveZ.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.w).z); pivotCurveOffX.AddKey(t, hipOffsetX); pivotCurveOffY.AddKey(t, hipOffsetY + standHeight); thighCurveW.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.x).w); thighCurveX.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.x).x); thighCurveY.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.x).y); thighCurveZ.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.x).z); calfCurveW.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.y).w); calfCurveX.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.y).x); calfCurveY.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.y).y); calfCurveZ.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.y).z); footCurveW.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.z).w); footCurveX.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.z).x); footCurveY.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.z).y); footCurveZ.AddKey(t, Quaternion.Euler(0.0f, 0.0f, angles.z).z); } clips[0].SetCurve("", typeof(Transform), "localRotation.w", pivotCurveW); clips[0].SetCurve("", typeof(Transform), "localRotation.x", pivotCurveX); clips[0].SetCurve("", typeof(Transform), "localRotation.y", pivotCurveY); clips[0].SetCurve("", typeof(Transform), "localRotation.z", pivotCurveZ); clips[0].SetCurve("", typeof(Transform), "localPosition.x", pivotCurveOffX); clips[0].SetCurve("", typeof(Transform), "localPosition.y", pivotCurveOffY); clips[1].SetCurve("", typeof(Transform), "localRotation.w", thighCurveW); clips[1].SetCurve("", typeof(Transform), "localRotation.x", thighCurveX); clips[1].SetCurve("", typeof(Transform), "localRotation.y", thighCurveY); clips[1].SetCurve("", typeof(Transform), "localRotation.z", thighCurveZ); clips[2].SetCurve("", typeof(Transform), "localRotation.w", calfCurveW); clips[2].SetCurve("", typeof(Transform), "localRotation.x", calfCurveX); clips[2].SetCurve("", typeof(Transform), "localRotation.y", calfCurveY); clips[2].SetCurve("", typeof(Transform), "localRotation.z", calfCurveZ); clips[3].SetCurve("", typeof(Transform), "localRotation.w", footCurveW); clips[3].SetCurve("", typeof(Transform), "localRotation.x", footCurveX); clips[3].SetCurve("", typeof(Transform), "localRotation.y", footCurveY); clips[3].SetCurve("", typeof(Transform), "localRotation.z", footCurveZ); // Attach clips to leg for (int i = 0; i < 2 /*legPivots[i] != null*/; i++) { Transform child = legPivots[i]; for (int j = 0; j < 4 /* Number of clips */; j++) { child.GetComponent <Animation>().AddClip(clips[j], "walk"); child = child.GetChild(0); } } /* * legPivotAnim.AddClip(clips[0],"walk"); * thighJointAnim.AddClip(clips[1],"walk"); * calfJointAnim.AddClip(clips[2],"walk"); * footJointAnim.AddClip(clips[3],"walk"); */ }