private void AppendSpriteBoneDataRecursively(List <SpriteBone> spriteBones, BoneCache bone, int parentIndex) { int currentParentIndex = spriteBones.Count; var spriteBone = new SpriteBone(); spriteBone.name = bone.name; spriteBone.parentId = parentIndex; if (parentIndex == -1 && bone.parentBone != null) { spriteBone.position = bone.position; spriteBone.rotation = bone.rotation; } else { spriteBone.position = bone.localPosition; spriteBone.rotation = bone.localRotation; } spriteBone.position = new Vector3(spriteBone.position.x, spriteBone.position.y, bone.depth); spriteBone.length = bone.localLength; spriteBones.Add(spriteBone); foreach (var child in bone) { var childBone = child as BoneCache; if (childBone != null) { AppendSpriteBoneDataRecursively(spriteBones, childBone, currentParentIndex); } } }
private static List <SpriteBone> Load(SerializedObject importer, SpriteImportMode mode, int index) { var sp = mode == SpriteImportMode.Multiple ? importer.FindProperty("m_SpriteSheet.m_Sprites").GetArrayElementAtIndex(index).FindPropertyRelative("m_Bones") : importer.FindProperty("m_SpriteSheet.m_Bones"); var spriteBone = new List <SpriteBone>(sp.arraySize); if (sp.arraySize > 0) { var boneSO = sp.GetArrayElementAtIndex(0); for (int i = 0; i < sp.arraySize; ++i, boneSO.Next(false)) { var sb = new SpriteBone(); sb.length = boneSO.FindPropertyRelative("length").floatValue; sb.position = boneSO.FindPropertyRelative("position").vector3Value; sb.rotation = boneSO.FindPropertyRelative("rotation").quaternionValue; sb.parentId = boneSO.FindPropertyRelative("parentId").intValue; sb.name = boneSO.FindPropertyRelative("name").stringValue; sb.guid = boneSO.FindPropertyRelative("guid").stringValue; sb.color = boneSO.FindPropertyRelative("color").colorValue; spriteBone.Add(sb); } } return(spriteBone); }
public UniqueSpriteBone(SpriteBone spriteBone) { this.length = spriteBone.length; this.name = spriteBone.name; this.parentId = spriteBone.parentId; this.position = spriteBone.position; this.rotation = spriteBone.rotation; this.id = new GUID(); }
public static void Apply(SerializedProperty rectSP, List <SpriteBone> spriteBone) { SerializedProperty serializedProperty = rectSP.FindPropertyRelative("m_Bones"); serializedProperty.arraySize = spriteBone.Count; for (int i = 0; i < serializedProperty.arraySize; i++) { SerializedProperty arrayElementAtIndex = serializedProperty.GetArrayElementAtIndex(i); SpriteBone spriteBone2 = spriteBone[i]; arrayElementAtIndex.FindPropertyRelative("length").floatValue = spriteBone2.length; arrayElementAtIndex.FindPropertyRelative("position").vector3Value = spriteBone2.position; arrayElementAtIndex.FindPropertyRelative("rotation").quaternionValue = spriteBone2.rotation; arrayElementAtIndex.FindPropertyRelative("parentId").intValue = spriteBone2.parentId; arrayElementAtIndex.FindPropertyRelative("name").stringValue = spriteBone2.name; } }
static void CalculateLocaltoWorldMatrix(int i, SpriteRect spriteRect, float definitionScale, float pixelsPerUnit, List <SpriteBone> spriteBone, ref SpriteBone?[] outpriteBone, ref NativeArray <Matrix4x4> bindPose) { if (outpriteBone[i] != null) { return; } SpriteBone sp = spriteBone[i]; var isRoot = sp.parentId == -1; var position = isRoot ? (spriteBone[i].position - Vector3.Scale(spriteRect.rect.size, spriteRect.pivot)) : spriteBone[i].position; position.z = 0f; sp.position = position * definitionScale / pixelsPerUnit; sp.length = spriteBone[i].length * definitionScale / pixelsPerUnit; outpriteBone[i] = sp; // Calculate bind poses var worldPosition = Vector3.zero; var worldRotation = Quaternion.identity; if (sp.parentId == -1) { worldPosition = sp.position; worldRotation = sp.rotation; } else { if (outpriteBone[sp.parentId] == null) { CalculateLocaltoWorldMatrix(sp.parentId, spriteRect, definitionScale, pixelsPerUnit, spriteBone, ref outpriteBone, ref bindPose); } var parentBindPose = bindPose[sp.parentId]; var invParentBindPose = Matrix4x4.Inverse(parentBindPose); worldPosition = invParentBindPose.MultiplyPoint(sp.position); worldRotation = sp.rotation * invParentBindPose.rotation; } // Practically Matrix4x4.SetTRInverse var rot = Quaternion.Inverse(worldRotation); Matrix4x4 mat = Matrix4x4.identity; mat = Matrix4x4.Rotate(rot); mat = mat * Matrix4x4.Translate(-worldPosition); bindPose[i] = mat; }
public override bool ApplyRevert(bool apply) { if (apply) { var meshDataProvider = spriteEditor.GetDataProvider <ISpriteMeshDataProvider>(); var boneDataProvider = spriteEditor.GetDataProvider <ISpriteBoneDataProvider>(); foreach (var spriteMeshData in m_SpriteMeshCache) { spriteMeshData.SortTrianglesByDepth(); List <Vertex2DMetaData> vmd = new List <Vertex2DMetaData>(spriteMeshData.vertices.Count); foreach (var v in spriteMeshData.vertices) { vmd.Add(new Vertex2DMetaData() { position = v.position - spriteMeshData.frame.position, boneWeight = v.editableBoneWeight.ToBoneWeight(true) }); } List <Vector2Int> emd = new List <Vector2Int>(spriteMeshData.edges.Count); foreach (var e in spriteMeshData.edges) { emd.Add(new Vector2Int(e.index1, e.index2)); } meshDataProvider.SetVertices(spriteMeshData.spriteID, vmd.ToArray()); meshDataProvider.SetIndices(spriteMeshData.spriteID, spriteMeshData.indices.ToArray()); meshDataProvider.SetEdges(spriteMeshData.spriteID, emd.ToArray()); List <SpriteBone> bones = boneDataProvider.GetBones(spriteMeshData.spriteID); for (int i = 0; i < bones.Count; ++i) { SpriteBone original = bones[i]; SpriteBoneData bone = spriteMeshData.bones[i]; Vector3 position = original.position; position.z = bone.depth; original.position = position; bones[i] = original; } boneDataProvider.SetBones(spriteMeshData.spriteID, bones); } } return(true); }
private List <SpriteBoneData> CreateBones() { SpriteBone[] spriteBones = new SpriteBone[] { new SpriteBone() { name = "root", length = 1f, parentId = -1, position = Vector2.zero, rotation = Quaternion.identity }, new SpriteBone() { name = "bone 0", length = 1f, parentId = 0, position = Vector2.right, rotation = Quaternion.identity } }; return(ModuleUtility.CreateSpriteBoneData(spriteBones, Matrix4x4.identity)); }
private List <SpriteBoneData> CreateSpriteBoneData() { var spriteBones = new SpriteBone[2] { new SpriteBone() { name = "root", parentId = -1, position = Vector2.one, rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f), length = 1.0f }, new SpriteBone() { name = "child1", parentId = 0, position = Vector3.up, rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f), length = 1.5f } }; return(MeshModuleUtility.CreateSpriteBoneData(spriteBones.ToList(), Matrix4x4.identity)); }
private static IEnumerable <TestCaseData> BoneMetadataCases() { var originalMetadata = new SpriteBone[5] { new SpriteBone() { name = "root", parentId = -1, position = Vector2.one, rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f), length = 1.0f }, new SpriteBone() { name = "child1", parentId = 0, position = Vector3.up, rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f), length = 1.5f }, new SpriteBone() { name = "child2", parentId = 1, position = Vector3.right, rotation = Quaternion.identity, length = 1.5f }, new SpriteBone() { name = "child3", parentId = 1, position = Vector3.left, rotation = Quaternion.Euler(0.0f, 0.0f, 120.0f), length = 2.5f }, new SpriteBone() { name = "child4", parentId = 3, position = Vector3.up, rotation = Quaternion.identity, length = 1.0f } }; var expectedPositions = new List <Vector2>(); expectedPositions.Add(new Vector2(1f, 1f)); expectedPositions.Add(new Vector2(0.5f, 1.8660f)); expectedPositions.Add(new Vector2(0.5f, 2.8660f)); expectedPositions.Add(new Vector2(0.5f, 0.8660f)); expectedPositions.Add(new Vector2(1f, 0f)); var expectedEndPositions = new List <Vector2>(); expectedEndPositions.Add(new Vector2(1.8660f, 1.5f)); expectedEndPositions.Add(new Vector2(0.5f, 3.3660f)); expectedEndPositions.Add(new Vector2(0.5f, 4.3660f)); expectedEndPositions.Add(new Vector2(-1.6650f, -0.383974f)); expectedEndPositions.Add(new Vector2(0.133974f, -0.5f)); var testcase = new TestCaseData(originalMetadata, expectedPositions, expectedEndPositions); testcase.SetName("Normal Hierarchical order"); yield return(testcase); originalMetadata = new SpriteBone[5] { new SpriteBone() { name = "child4", parentId = 1, position = Vector3.up, rotation = Quaternion.identity, length = 1.0f }, new SpriteBone() { name = "child3", parentId = 3, position = Vector3.left, rotation = Quaternion.Euler(0.0f, 0.0f, 120.0f), length = 2.5f }, new SpriteBone() { name = "child2", parentId = 3, position = Vector3.right, rotation = Quaternion.identity, length = 1.5f }, new SpriteBone() { name = "child1", parentId = 4, position = Vector3.up, rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f), length = 1.5f }, new SpriteBone() { name = "root", parentId = -1, position = Vector2.one, rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f), length = 1.0f } }; expectedPositions = new List <Vector2>(); expectedPositions.Add(new Vector2(1f, 0f)); expectedPositions.Add(new Vector2(0.5f, 0.8660f)); expectedPositions.Add(new Vector2(0.5f, 2.8660f)); expectedPositions.Add(new Vector2(0.5f, 1.8660f)); expectedPositions.Add(new Vector2(1f, 1f)); expectedEndPositions = new List <Vector2>(); expectedEndPositions.Add(new Vector2(0.133974f, -0.5f)); expectedEndPositions.Add(new Vector2(-1.6650f, -0.383974f)); expectedEndPositions.Add(new Vector2(0.5f, 4.3660f)); expectedEndPositions.Add(new Vector2(0.5f, 3.3660f)); expectedEndPositions.Add(new Vector2(1.8660f, 1.5f)); testcase = new TestCaseData(originalMetadata, expectedPositions, expectedEndPositions); testcase.SetName("Reversed Hierarchical order"); yield return(testcase); }
public void OnPasteActivated(bool bone, bool mesh, bool flipX, bool flipY) { var copyBuffer = m_CopyToolStringStore.stringStore; if (!SkinningCopyUtility.CanDeserializeStringToSkinningCopyData(copyBuffer)) { Debug.LogError(TextContent.copyError1); return; } var skinningCopyData = SkinningCopyUtility.DeserializeStringToSkinningCopyData(copyBuffer); if (skinningCopyData == null || skinningCopyData.copyData.Count == 0) { Debug.LogError(TextContent.copyError2); return; } var scale = 1f; if (skinningCopyData.pixelsPerUnit > 0f) { scale = pixelsPerUnit / skinningCopyData.pixelsPerUnit; } var sprites = skinningCache.GetSprites(); var copyMultiple = skinningCopyData.copyData.Count > 1; if (copyMultiple && skinningCopyData.copyData.Count != sprites.Length && mesh) { Debug.LogError(String.Format(TextContent.copyError3, sprites.Length, skinningCopyData.copyData.Count)); return; } using (skinningCache.UndoScope(TextContent.pasteData)) { NewBonesStore newBonesStore = null; if (bone && copyMultiple && skinningCache.hasCharacter) { newBonesStore = new NewBonesStore(); var skinningSpriteData = skinningCopyData.copyData[0]; newBonesStore.newBones = skinningCache.CreateBoneCacheFromSpriteBones(skinningSpriteData.spriteBones.Select(y => y.spriteBone).ToArray(), scale); if (flipX || flipY) { var characterRect = new Rect(Vector2.zero, skinningCache.character.dimension); var newPositions = new Vector3[newBonesStore.newBones.Length]; var newRotations = new Quaternion[newBonesStore.newBones.Length]; for (var i = 0; i < newBonesStore.newBones.Length; ++i) { newPositions[i] = GetFlippedBonePosition(newBonesStore.newBones[i], Vector2.zero, characterRect, flipX, flipY); newRotations[i] = GetFlippedBoneRotation(newBonesStore.newBones[i], flipX, flipY); } for (var i = 0; i < newBonesStore.newBones.Length; ++i) { newBonesStore.newBones[i].position = newPositions[i]; newBonesStore.newBones[i].rotation = newRotations[i]; } } newBonesStore.MapAllExistingBones(); var skeleton = skinningCache.character.skeleton; skeleton.SetBones(newBonesStore.newBones); skinningCache.events.skeletonTopologyChanged.Invoke(skeleton); } foreach (var skinningSpriteData in skinningCopyData.copyData) { SpriteCache sprite = null; if (!String.IsNullOrEmpty(skinningSpriteData.spriteName)) { sprite = sprites.FirstOrDefault(x => x.name == skinningSpriteData.spriteName); } if (sprite == null && (skinningCopyData.copyData.Count == 1 || String.IsNullOrEmpty(skinningSpriteData.spriteName))) { sprite = skinningCache.selectedSprite; } if (sprite == null) { continue; } if (bone && (!skinningCache.hasCharacter || !copyMultiple)) { var spriteBones = new SpriteBone[skinningSpriteData.spriteBones.Count]; for (int i = 0; i < skinningSpriteData.spriteBones.Count; ++i) { var order = skinningSpriteData.spriteBones[i].order; spriteBones[order] = skinningSpriteData.spriteBones[i].spriteBone; var parentId = spriteBones[order].parentId; if (parentId >= 0) { spriteBones[order].parentId = skinningSpriteData.spriteBones[parentId].order; } } newBonesStore = PasteSkeletonBones(sprite, spriteBones.ToList(), flipX, flipY, scale); } if (mesh && meshTool != null) { PasteMesh(sprite, skinningSpriteData, flipX, flipY, scale, newBonesStore); } } if (newBonesStore != null && newBonesStore.newBones != null) { skinningCache.skeletonSelection.elements = newBonesStore.newBones; skinningCache.events.boneSelectionChanged.Invoke(); } } skinningCache.events.paste.Invoke(bone, mesh, flipX, flipY); }
public static void ProcessCharacter() { // Get the file paths of the data string plist_path = EditorUtility.OpenFilePanel("Open character's config data:", "Assets", "plist"); string json_path = EditorUtility.OpenFilePanel("Open character's skeletal/animation data:", "Assets", "ExportJson"); Texture2D sprite; if (Selection.objects.Length != 1) { sprite = null; } else { sprite = Selection.activeObject as Texture2D; } if (sprite == null) { Debug.LogError("ERROR: Sprite sheet is not selected."); return; } if (plist_path == "" || json_path == "") { Debug.LogError("ERROR: Plist and/or JSON are null."); return; } // Read sprite data from the plist List <SpriteData> cutting_data = ReadPlist(plist_path); // Cut sprite data List <SpriteMetaData> sheet = CutSprite(sprite, cutting_data); // Prepare sprite atlas string atlas_source = AssetDatabase.GetAssetPath(sprite); atlas_source = atlas_source.Substring(atlas_source.LastIndexOf("/") + 1, (atlas_source.LastIndexOf(".") - atlas_source.LastIndexOf("/")) - 1); SpriteAtlas atlas = new SpriteAtlas(atlas_source); // Read data from Json file into Json string string json_content = File.ReadAllText(json_path); // Deserialize Json string into usable object data RootObject obj = JsonUtility.FromJson <RootObject>(json_content); // Create base object for armature GameObject root = new GameObject(obj.armature_data[0].name); root.tag = "Armature"; // Prepare the skeleton //List<GameObject> bones = new List<GameObject>(); List <SpriteBone> bones = new List <SpriteBone>(); // For each bone in the skeleton foreach (BoneData node in obj.armature_data[0].bone_data) { // Create a new game object, tag is set to bone GameObject g = new GameObject(node.name); g.tag = "Bone"; // If parent node is null, parent the object to the root if (node.parent == "") { g.transform.SetParent(root.transform); } else { // Get a reference to all child transforms Transform[] allChildren = root.GetComponentsInChildren <Transform>(); // For each transform foreach (Transform child in allChildren) { // Check if transform name matches parent. If so, parent the object to that transform if (child.gameObject.name == node.parent) { g.transform.SetParent(child); } } } // POSITION IS RELATIVE TO PARENT // Set the position and scale // Mathf.Rad2Deg g.transform.localPosition = new Vector2((float)node.x / scale_factor, (float)node.y / scale_factor); g.transform.localScale = new Vector3((float)node.cX, (float)node.cY, 1.0f); g.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(node.kY * Mathf.Rad2Deg)); int index = 0; int displayIndex = node.dI; /*if (displayIndex < 0) * displayIndex = 0;*/ // Initialize skeleton SpriteBone sb = new SpriteBone(); sb.bone = g; // Sprites need to be their own gameobjects foreach (DisplayData d in node.display_data) { // Create object GameObject s = new GameObject(d.name); s.transform.SetParent(g.transform); s.tag = "Display Data"; SkinData d_data = d.skin_data[0]; SpriteData sd = FindSpriteData(cutting_data, d.name); // Set sprite transforms if (sd != null) { s.transform.localPosition = new Vector3(((float)d_data.x) / scale_factor, ((float)d_data.y) / scale_factor); s.transform.localScale = new Vector3((float)d_data.cX, (float)d_data.cY, 1.0f); s.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(d_data.kY * Mathf.Rad2Deg)); // Set sprite offset GameObject o = new GameObject(index.ToString()); o.transform.SetParent(s.transform); o.tag = "Sprite"; // Set up sprite components o.AddComponent <SpriteRenderer>(); //o.GetComponent<SpriteRenderer>().sortingOrder = node.z; Sprite body_piece = atlas.getSprite(d.name); o.GetComponent <SpriteRenderer>().sprite = body_piece; // Apply sprite offset o.transform.localPosition = new Vector3(sd.offsetX / scale_factor, sd.offsetY / scale_factor, -node.z / scale_factor); o.transform.localEulerAngles = Vector3.zero; sb.displayData.Add(o); // Determine visibility if (displayIndex != index) { o.SetActive(false); } } index++; } // Add bone to the list bones.Add(sb); } // Add an animator to the root root.AddComponent <Animator>(); // Create an animator controller (ADDENDUM: MAY NOT BE NEEDED) // Loop through all animations in the JSON foreach (MovData md in obj.animation_data[0].mov_data) { // Create and name an animation clip AnimationClip anim = new AnimationClip(); anim.name = md.name; // Name and frame index of inverted bones // Change to dictionary <string, Dictionary<int, bool>> Dictionary <string, Dictionary <int, bool> > toInvert = new Dictionary <string, Dictionary <int, bool> >(); foreach (MovBoneData mbd in md.mov_bone_data) { Dictionary <int, bool> boneInv = new Dictionary <int, bool>(); int numAdded = 0; foreach (FrameData fd in mbd.frame_data) { if (fd.cX < 0 || fd.cY < 0) { boneInv.Add(fd.fi, true); numAdded++; } else { if (!boneInv.ContainsKey(fd.fi)) { boneInv.Add(fd.fi, false); } } } if (boneInv.Count > 0 && numAdded > 0) { toInvert.Add(mbd.name, boneInv); } } // Loop through all bone data foreach (MovBoneData mbd in md.mov_bone_data) { // Name of bone that needs its transform inverted //List<string> toInvert = new List<string>(); // Find the game object matching the bone SpriteBone bone = null; foreach (SpriteBone sb in bones) { if (sb.bone.name.Equals(mbd.name)) { bone = sb; } } // Prepare animation curves for animated properties AnimationCurve curve_x = new AnimationCurve(); AnimationCurve curve_y = new AnimationCurve(); AnimationCurve curve_cx = new AnimationCurve(); AnimationCurve curve_cy = new AnimationCurve(); AnimationCurve curve_ky = new AnimationCurve(); AnimationCurve[] curve_z = new AnimationCurve[bone.displayData.Count]; AnimationCurve[] curve_di = new AnimationCurve[bone.displayData.Count]; AnimationCurve[] curve_fx = new AnimationCurve[bone.displayData.Count]; AnimationCurve[] curve_fy = new AnimationCurve[bone.displayData.Count]; // Required to retain offsets AnimationCurve[] curve_zx = new AnimationCurve[bone.displayData.Count]; AnimationCurve[] curve_zy = new AnimationCurve[bone.displayData.Count]; for (int i = 0; i < bone.displayData.Count; i++) { curve_z[i] = new AnimationCurve(); curve_zx[i] = new AnimationCurve(); curve_zy[i] = new AnimationCurve(); curve_di[i] = new AnimationCurve(); curve_fx[i] = new AnimationCurve(); curve_fy[i] = new AnimationCurve(); } int previous_z = 0; // Loop through all keyframes for that bone foreach (FrameData fd in mbd.frame_data) { // Set keyframe values for position, rotation, and scale. Note that all of these are relative Keyframe px = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.x + ((float)fd.x / scale_factor))); px.tangentMode = 0; px.inTangent = 0.0f; px.outTangent = 0.0f; Keyframe py = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.y + ((float)fd.y / scale_factor))); py.tangentMode = 0; py.inTangent = 0.0f; py.outTangent = 0.0f; curve_x.AddKey(px); curve_y.AddKey(py); // Scale keyframes Keyframe kx = new Keyframe((fd.fi / sample_rate), ((float)fd.cX)); kx.tangentMode = 0; kx.inTangent = 0.0f; kx.outTangent = 0.0f; Keyframe ky = new Keyframe((fd.fi / sample_rate), ((float)fd.cY)); ky.tangentMode = 0; ky.inTangent = 0.0f; ky.outTangent = 0.0f; curve_cx.AddKey(kx); curve_cy.AddKey(ky); // This is the ONLY bug remaining. When something's supposed to be inverted, the inversion is never reset. // Inversion is also not 100%. For example, Suzy's right arm is not inverted in her idle animation // Correct inversion error Transform t = bone.bone.transform; float direction = 1.0f; while (t.transform.parent != null) { t = t.transform.parent; if (toInvert.ContainsKey(t.gameObject.name)) { // This needs to get the previous frame index if none exist if (InvertAtIndex(toInvert, fd.fi, t.gameObject.name)) { direction = -1.0f; Debug.Log("Success! - " + md.name + ": " + t.gameObject.name + " " + mbd.name); } } } // Invert rotation Keyframe ry = new Keyframe((fd.fi / sample_rate), direction * (bone.bone.transform.localEulerAngles.z + ((float)(fd.kY * Mathf.Rad2Deg)))); ry.tangentMode = 0; ry.inTangent = 0.0f; ry.outTangent = 0.0f; curve_ky.AddKey(ry); // Determine display index int displayIndex = fd.dI; for (int i = 0; i < bone.displayData.Count; i++) { // If the frame index is not one, a second keyframe will need to be set to disable "sliding" if (fd.fi > 1) { Keyframe p_zx = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.x); p_zx.tangentMode = 0; p_zx.inTangent = 0.0f; p_zx.outTangent = 0.0f; Keyframe p_zy = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.y); p_zy.tangentMode = 0; p_zy.inTangent = 0.0f; p_zy.outTangent = 0.0f; Keyframe p_zz = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.z + (-previous_z / scale_factor)); p_zz.tangentMode = 0; p_zz.inTangent = 0.0f; p_zz.outTangent = 0.0f; curve_z[i].AddKey(p_zz); curve_zx[i].AddKey(p_zx); curve_zy[i].AddKey(p_zy); } Keyframe zx = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.x); zx.tangentMode = 0; zx.inTangent = 0.0f; zx.outTangent = 0.0f; Keyframe zy = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.y); zy.tangentMode = 0; zy.inTangent = 0.0f; zy.outTangent = 0.0f; Keyframe zz = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.z + (-fd.z / scale_factor)); zz.tangentMode = 0; zz.inTangent = 0.0f; zz.outTangent = 0.0f; curve_z[i].AddKey(zz); previous_z = fd.z; curve_zx[i].AddKey(zx); curve_zy[i].AddKey(zy); // Check if the current index equals the display index if (bone.displayData[i].name.Equals(displayIndex.ToString())) { Keyframe k = new Keyframe((fd.fi / sample_rate), 1.0f); k.tangentMode = 103; k.inTangent = float.PositiveInfinity; k.outTangent = float.PositiveInfinity; curve_di[i].AddKey(k); } else { Keyframe k = new Keyframe((fd.fi / sample_rate), 0.0f); k.tangentMode = 103; k.inTangent = float.PositiveInfinity; k.outTangent = float.PositiveInfinity; curve_di[i].AddKey(k); } } } // Get full name of bone string bone_name = GetCompletePath(bone.bone.transform); // Apply transform keyframes to animation clip anim.SetCurve(bone_name, typeof(Transform), "localPosition.x", curve_x); anim.SetCurve(bone_name, typeof(Transform), "localPosition.y", curve_y); anim.SetCurve(bone_name, typeof(Transform), "localScale.x", curve_cx); anim.SetCurve(bone_name, typeof(Transform), "localScale.y", curve_cy); anim.SetCurve(bone_name, typeof(Transform), "localEulerAngles.z", curve_ky); // Get full name of sprites string[] sprite_names = new string[bone.displayData.Count]; for (int i = 0; i < sprite_names.Length; i++) { sprite_names[i] = GetCompletePath(bone.displayData[i].transform); // Apply sprite keyframes to animation clip anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.x", curve_zx[i]); anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.y", curve_zy[i]); anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.z", curve_z[i]); anim.SetCurve(sprite_names[i], typeof(GameObject), "m_IsActive", curve_di[i]); } } // Apply loop AnimationClipSettings animClipSett = new AnimationClipSettings(); animClipSett.loopTime = md.lp; AnimationUtility.SetAnimationClipSettings(anim, animClipSett); string filePath = "assets/animations/" + sprite.name + "/"; // Create the anim clip if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } AssetDatabase.CreateAsset(anim, filePath + anim.name + ".anim"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } }
public void Populate(bool character) { m_HasCharacter = character; m_SpriteRects = new SpriteRect[2]; m_SpriteRects[0] = new SpriteRect(); m_SpriteRects[0].rect = new Rect(0, 0, 100, 100); m_SpriteRects[0].alignment = SpriteAlignment.Center; m_SpriteRects[0].border = Vector4.zero; m_SpriteRects[0].name = "Sprite1"; m_SpriteRects[0].pivot = Vector2.zero; m_SpriteRects[0].spriteID = GUID.Generate(); m_SpriteRects[1] = new SpriteRect(); m_SpriteRects[1].rect = new Rect(100, 0, 100, 100); m_SpriteRects[1].alignment = SpriteAlignment.Center; m_SpriteRects[1].border = Vector4.zero; m_SpriteRects[1].name = "Sprite2"; m_SpriteRects[1].pivot = Vector2.zero; m_SpriteRects[1].spriteID = GUID.Generate(); pixelsPerUnit = 100f; m_SpriteData = new SpriteData[2]; m_SpriteData[0] = new SpriteData(); m_SpriteData[0].bones = new List <SpriteBone>(); var bone = new SpriteBone() { name = "Bone-1-1", length = 20f, position = Vector3.zero, rotation = Quaternion.identity, parentId = -1 }; m_SpriteData[0].bones.Add(bone); bone = new SpriteBone() { name = "Bone-1-2", length = 50f, position = new Vector3(20, 0, 0), rotation = Quaternion.Euler(0, 0, 270), parentId = 0 }; m_SpriteData[0].bones.Add(bone); m_SpriteData[0].vertices = new Vertex2DMetaData[4]; m_SpriteData[0].vertices[0] = new Vertex2DMetaData() { position = new Vector2(0, 0), boneWeight = new BoneWeight() }; m_SpriteData[0].vertices[1] = new Vertex2DMetaData() { position = new Vector2(0, 100), boneWeight = new BoneWeight() }; m_SpriteData[0].vertices[2] = new Vertex2DMetaData() { position = new Vector2(100, 100), boneWeight = new BoneWeight() }; m_SpriteData[0].vertices[3] = new Vertex2DMetaData() { position = new Vector2(100, 0), boneWeight = new BoneWeight() }; m_SpriteData[0].indices = new int[6] { 0, 1, 2, 0, 2, 3 }; m_SpriteData[0].edges = new Vector2Int[4] { new Vector2Int(0, 1), new Vector2Int(1, 2), new Vector2Int(2, 3), new Vector2Int(3, 0) }; m_SpriteData[1] = new SpriteData(); m_SpriteData[1].bones = new List <SpriteBone>(); bone = new SpriteBone() { name = "Bone-2-1", length = 20f, position = new Vector3(100, 0, 0), rotation = Quaternion.identity, parentId = -1 }; m_SpriteData[1].bones.Add(bone); bone = new SpriteBone() { name = "Bone-2-2", length = 50f, position = new Vector3(120, 0, 0), rotation = Quaternion.Euler(0, 0, 270), parentId = 0 }; m_SpriteData[1].bones.Add(bone); m_SpriteData[1].vertices = new Vertex2DMetaData[3]; m_SpriteData[1].vertices[0] = new Vertex2DMetaData() { position = new Vector2(100, 0), boneWeight = new BoneWeight() { boneIndex0 = 0, weight0 = 1.5f } }; m_SpriteData[1].vertices[1] = new Vertex2DMetaData() { position = new Vector2(100, 100), boneWeight = new BoneWeight() { boneIndex0 = 1, weight0 = 0.5f } }; m_SpriteData[1].vertices[2] = new Vertex2DMetaData() { position = new Vector2(190, 50), boneWeight = new BoneWeight() { boneIndex0 = 0, weight0 = 0.5f, boneIndex1 = 1, weight1 = 0.5f } }; m_SpriteData[1].indices = new int[3] { 0, 1, 2 }; m_SpriteData[1].edges = new Vector2Int[3] { new Vector2Int(0, 1), new Vector2Int(1, 2), new Vector2Int(2, 0) }; m_Character.bones = new SpriteBone[3]; m_Character.bones[0] = new SpriteBone(); m_Character.bones[0].name = "Bone 1"; m_Character.bones[0].length = 10f; m_Character.bones[0].position = new Vector3(55, 0, 0); m_Character.bones[0].rotation = Quaternion.identity; m_Character.bones[0].parentId = -1; m_Character.bones[1] = new SpriteBone(); m_Character.bones[1].name = "Bone 2"; m_Character.bones[1].length = 30f; m_Character.bones[1].position = Vector3.zero; m_Character.bones[1].rotation = Quaternion.Euler(0, 0, 315); m_Character.bones[1].parentId = 0; m_Character.bones[2] = new SpriteBone(); m_Character.bones[2].name = "Bone 3"; m_Character.bones[2].length = 20f; m_Character.bones[2].position = Vector3.zero; m_Character.bones[2].rotation = Quaternion.Euler(0, 0, 45); m_Character.bones[2].parentId = 1; m_Character.parts = new CharacterPart[2]; m_Character.parts[0] = new CharacterPart(); m_Character.parts[0].spritePosition = new RectInt(50, 0, 100, 100); m_Character.parts[0].spriteId = m_SpriteRects[0].spriteID.ToString(); m_Character.parts[0].bones = new int[0]; m_Character.parts[1] = new CharacterPart(); m_Character.parts[1].spritePosition = new RectInt(75, 0, 100, 100); m_Character.parts[1].spriteId = m_SpriteRects[1].spriteID.ToString(); m_Character.parts[1].bones = new int[0]; }
static bool PostProcessBoneData(ISpriteEditorDataProvider spriteDataProvider, Sprite[] sprites) { var boneDataProvider = spriteDataProvider.GetDataProvider <ISpriteBoneDataProvider>(); var textureDataProvider = spriteDataProvider.GetDataProvider <ITextureDataProvider>(); if (sprites == null || sprites.Length == 0 || boneDataProvider == null || textureDataProvider == null) { return(false); } bool dataChanged = false; float definitionScale = CalculateDefinitionScale(textureDataProvider); foreach (var sprite in sprites) { var guid = sprite.GetSpriteID(); { SpriteRect spriteRect = spriteDataProvider.GetSpriteRects().First(s => { return(s.spriteID == guid); }); var spriteBone = boneDataProvider.GetBones(guid); if (spriteBone == null) { continue; } var spriteBoneCount = spriteBone.Count; var pivotPointInPixels = sprite.pivot; var bindPose = new NativeArray <Matrix4x4>(spriteBoneCount, Allocator.Temp); var outputSpriteBones = new SpriteBone[spriteBoneCount];// NativeArray<SpriteBone>(spriteBone.Count, Allocator.Temp); for (int i = 0; i < spriteBoneCount; ++i) { // Convert position to world unit. SpriteBone sp = spriteBone[i]; var isRoot = sp.parentId == -1; var position = isRoot ? (spriteBone[i].position - Vector3.Scale(spriteRect.rect.size, spriteRect.pivot)) : spriteBone[i].position; position.z = 0f; sp.position = position * definitionScale / sprite.pixelsPerUnit; sp.length = spriteBone[i].length * definitionScale / sprite.pixelsPerUnit; outputSpriteBones[i] = sp; // Calculate bind poses var worldPosition = Vector3.zero; var worldRotation = Quaternion.identity; if (sp.parentId == -1) { worldPosition = sp.position; worldRotation = sp.rotation; } else { var parentBindPose = bindPose[sp.parentId]; var invParentBindPose = Matrix4x4.Inverse(parentBindPose); worldPosition = invParentBindPose.MultiplyPoint(sp.position); worldRotation = sp.rotation * invParentBindPose.rotation; } // Practically Matrix4x4.SetTRInverse var rot = Quaternion.Inverse(worldRotation); Matrix4x4 mat = Matrix4x4.identity; mat = Matrix4x4.Rotate(rot); mat = mat * Matrix4x4.Translate(-worldPosition); bindPose[i] = mat; } sprite.SetBindPoses(bindPose); sprite.SetBones(outputSpriteBones); bindPose.Dispose(); dataChanged = true; } } return(dataChanged); }