// Called when the structure is accessed public void Execute(int i) { // Pass through the animation data from the user CG_GameManager UserAnimationData = CG_GameManager.Instance; // The current texture animator data at the index provide AnimationData animData = texAnimData[i]; // if the animation id isnt the same as the new animation data if (animData.animationID != animData.newAnimationId) { // transition pre anim if (animData.animationID >= 0) { // set pre-transition data values animData.animationToSwitchID = animData.animationID; animData.animationToSwitchNormTime = animData.normalizedAnimationTime; animData.transitionPercent = 0f; // get the animation loops based on the user inputted varaibles if (animData.animationID == 1) { animData.animationToSwitchLooping = UserAnimationData.LoopAnimation2; } else { animData.animationToSwitchLooping = UserAnimationData.LoopAnimation1; } } else { animData.transitionPercent = -1f; } // set the animation id and resent the normalised time animData.animationID = animData.newAnimationId; animData.normalizedAnimationTime = 0f; } // Geth the baked clip data from the current animation index AnimationClipDataBaked bakedClip = animationClips[animData.animationID]; // Set the default normalised time of the animation float normalizedTime = animData.normalizedAnimationTime + deltaTime / (bakedClip.animationLength / UserAnimationData.Animation1Speed); // Change the speed dependant on the animation clip being played if (animData.animationID == 1) { normalizedTime = animData.normalizedAnimationTime + deltaTime / (bakedClip.animationLength / UserAnimationData.Animation2Speed); } // if the normalised time is equal to 1, the animation has if (normalizedTime > 1.0f) { // Get whether the animation should loop or not based on user variables bool animLoop = UserAnimationData.LoopAnimation1; if (animData.animationID == 1) { animLoop = UserAnimationData.LoopAnimation2; } // if the animation should loop, reset the normalised time // else hold this value at 1 if (animLoop) { normalizedTime = 0; } else { normalizedTime = 1f; } } // set the animation datas normalised time to this new normalised time animData.normalizedAnimationTime = normalizedTime; // if a transition is in progress if (animData.transitionPercent >= 0.0f) { float blendPercent = animData.transitionPercent + deltaTime / UserAnimationData.TransitionSpeed; // Transition ended if (blendPercent > 1f) { blendPercent = -1f; } else { // continue preanimation AnimationClipDataBaked preClip = animationClips[animData.animationToSwitchID]; float preNormalizedTime = animData.animationToSwitchNormTime + deltaTime / (preClip.animationLength); // if the animation should loop, reset the normalised time // else hold this value at 1 if (preNormalizedTime > 1.0f) { if (animData.animationToSwitchLooping) { preNormalizedTime = 0; } else { preNormalizedTime = 1f; } } animData.animationToSwitchNormTime = preNormalizedTime; } animData.transitionPercent = blendPercent; } texAnimData[i] = animData; }
// Main functioon, handles the baking of the animation public static AnimationData BakeAnimation(SkinnedMeshRenderer meshToSample) { // Create the default variables AnimationData bakedAnimData = new AnimationData(); List <Matrix4x4[, ]> boneMatrix = new List <Matrix4x4[, ]>(); int keyframes = 0; // Convert the skinned mesh to sample into a static mesh bakedAnimData.NewMesh = ConvertSkinnedMesh(meshToSample); // Get the animations from the user CG_GameManager UserAnimations = CG_GameManager.Instance; // Assign these animation clips. For this to work, the animations must be inserted into // the mesh renderers animator controller, however allows the hot swapping of animations AnimationClip[] animationClips = new AnimationClip[2]; // If the animations are found, add these to the clips if (UserAnimations.Animation1) { animationClips[0] = UserAnimations.Animation1; } if (UserAnimations.Animation2) { animationClips[1] = UserAnimations.Animation2; } // For both of the animation clips, sample their data for (int i = 0; i < animationClips.Length; i++) { Matrix4x4[,] sampledAim = SampleAnimation(animationClips[i], meshToSample); boneMatrix.Add(sampledAim); keyframes += sampledAim.GetLength(0); } // Initialise the texture data of the baked data bakedAnimData.textures = new Texture2D[3]; for (int i = 0; i < bakedAnimData.textures.Length; i++) { bakedAnimData.textures[i] = new Texture2D(keyframes, boneMatrix[0].GetLength(1), TextureFormat.RGBAFloat, false); } // Initialise the texture color data of the baked data int tCW = bakedAnimData.textures[0].width * bakedAnimData.textures[0].height; Color[] texture0Colour = new Color[tCW]; Color[] texture1Colour = new Color[tCW]; Color[] texture2Colour = new Color[tCW]; // loop through and assign this colour data int totalKeyframes = 0; for (int i = 0; i < boneMatrix.Count; i++) { for (int boneIdx = 0; boneIdx < boneMatrix[i].GetLength(1); boneIdx++) { for (int keyframeIdx = 0; keyframeIdx < boneMatrix[i].GetLength(0); keyframeIdx++) { int index = (boneIdx * bakedAnimData.textures[0].width + (totalKeyframes + keyframeIdx)); texture0Colour[index] = boneMatrix[i][keyframeIdx, boneIdx].GetRow(0); texture1Colour[index] = boneMatrix[i][keyframeIdx, boneIdx].GetRow(1); texture2Colour[index] = boneMatrix[i][keyframeIdx, boneIdx].GetRow(2); } } // set the color data bakedAnimData.textures[0].SetPixels(texture0Colour); // Apply this without setting minmaps and do not make them no longer readable bakedAnimData.textures[0].Apply(false, false); bakedAnimData.textures[1].SetPixels(texture1Colour); bakedAnimData.textures[1].Apply(false, false); bakedAnimData.textures[2].SetPixels(texture2Colour); bakedAnimData.textures[2].Apply(false, false); // Create the animation clip data AnimationClipData clipData = new AnimationClipData(); clipData.Clip = animationClips[i]; clipData.textureStart = totalKeyframes + 1; clipData.textureEnd = (totalKeyframes + boneMatrix[i].GetLength(0) - 1) - 1; // Add this animation to the animation clip data bakedAnimData.animationClipData.Add(clipData); // count the total running amount of keyframes totalKeyframes += boneMatrix[i].GetLength(0); } // Return the AnimatorData gathered return(bakedAnimData); }