A game about forced loneliness, made by TACStudios
at master 143 lines 5.4 kB view raw
1using System; 2using System.Collections.Generic; 3 4namespace UnityEngine.U2D.Animation 5{ 6 internal static class SpriteSkinHelpers 7 { 8 public static void CacheChildren(Transform current, Dictionary<int, List<SpriteSkin.TransformData>> cache) 9 { 10 var nameHash = current.name.GetHashCode(); 11 var entry = new SpriteSkin.TransformData() 12 { 13 fullName = string.Empty, 14 transform = current 15 }; 16 if (cache.TryGetValue(nameHash, out var value)) 17 value.Add(entry); 18 else 19 cache.Add(nameHash, new List<SpriteSkin.TransformData>(1) { entry }); 20 21 for (var i = 0; i < current.childCount; ++i) 22 CacheChildren(current.GetChild(i), cache); 23 } 24 25 public static string GenerateTransformPath(Transform rootBone, Transform child) 26 { 27 var path = child.name; 28 if (child == rootBone) 29 return path; 30 var parent = child.parent; 31 do 32 { 33 path = parent.name + "/" + path; 34 parent = parent.parent; 35 } while (parent != rootBone && parent != null); 36 37 return path; 38 } 39 40 public static bool GetSpriteBonesTransforms(SpriteSkin spriteSkin, out Transform[] outTransform) 41 { 42 var rootBone = spriteSkin.rootBone; 43 var spriteBones = spriteSkin.sprite.GetBones(); 44 45 if (rootBone == null) 46 throw new ArgumentException("rootBone parameter cannot be null"); 47 if (spriteBones == null) 48 throw new ArgumentException("spriteBones parameter cannot be null"); 49 50 outTransform = new Transform[spriteBones.Length]; 51 52 var boneObjects = rootBone.GetComponentsInChildren<Bone>(); 53 if (boneObjects != null && boneObjects.Length >= spriteBones.Length) 54 { 55 using (SpriteSkin.Profiling.getSpriteBonesTransformFromGuid.Auto()) 56 { 57 var i = 0; 58 for (; i < spriteBones.Length; ++i) 59 { 60 var boneHash = spriteBones[i].guid; 61 var boneTransform = Array.Find(boneObjects, x => (x.guid == boneHash)); 62 if (boneTransform == null) 63 break; 64 65 outTransform[i] = boneTransform.transform; 66 } 67 68 if (i >= spriteBones.Length) 69 return true; 70 } 71 } 72 73 var hierarchyCache = spriteSkin.hierarchyCache; 74 if (hierarchyCache.Count == 0) 75 spriteSkin.CacheHierarchy(); 76 77 // If unable to successfully map via guid, fall back to path 78 return GetSpriteBonesTransformFromPath(spriteBones, hierarchyCache, outTransform); 79 } 80 81 static bool GetSpriteBonesTransformFromPath(SpriteBone[] spriteBones, Dictionary<int, List<SpriteSkin.TransformData>> hierarchyCache, Transform[] outNewBoneTransform) 82 { 83 using (SpriteSkin.Profiling.getSpriteBonesTransformFromPath.Auto()) 84 { 85 string[] bonePath = null; 86 var foundBones = true; 87 for (var i = 0; i < spriteBones.Length; ++i) 88 { 89 var nameHash = spriteBones[i].name.GetHashCode(); 90 if (!hierarchyCache.TryGetValue(nameHash, out var children)) 91 { 92 outNewBoneTransform[i] = null; 93 foundBones = false; 94 continue; 95 } 96 97 if (children.Count == 1) 98 outNewBoneTransform[i] = children[0].transform; 99 else 100 { 101 if (bonePath == null) 102 bonePath = new string[spriteBones.Length]; 103 if (bonePath[i] == null) 104 CalculateBoneTransformsPath(i, spriteBones, bonePath); 105 106 var m = 0; 107 for (; m < children.Count; ++m) 108 { 109 if (children[m].fullName.Contains(bonePath[i])) 110 { 111 outNewBoneTransform[i] = children[m].transform; 112 break; 113 } 114 } 115 116 if (m >= children.Count) 117 { 118 outNewBoneTransform[i] = null; 119 foundBones = false; 120 } 121 } 122 } 123 124 return foundBones; 125 } 126 } 127 128 static void CalculateBoneTransformsPath(int index, SpriteBone[] spriteBones, string[] paths) 129 { 130 var spriteBone = spriteBones[index]; 131 var parentId = spriteBone.parentId; 132 var bonePath = spriteBone.name; 133 if (parentId != -1) 134 { 135 if (paths[parentId] == null) 136 CalculateBoneTransformsPath(spriteBone.parentId, spriteBones, paths); 137 paths[index] = $"{paths[parentId]}/{bonePath}"; 138 } 139 else 140 paths[index] = bonePath; 141 } 142 } 143}