untangle-puzzlegame/Library/PackageCache/com.unity.2d.animation@494a3b4e73a9/Runtime/SpriteSkinHelpers.cs
2025-04-17 17:33:08 -04:00

144 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
namespace UnityEngine.U2D.Animation
{
internal static class SpriteSkinHelpers
{
public static void CacheChildren(Transform current, Dictionary<int, List<SpriteSkin.TransformData>> cache)
{
var nameHash = current.name.GetHashCode();
var entry = new SpriteSkin.TransformData()
{
fullName = string.Empty,
transform = current
};
if (cache.TryGetValue(nameHash, out var value))
value.Add(entry);
else
cache.Add(nameHash, new List<SpriteSkin.TransformData>(1) { entry });
for (var i = 0; i < current.childCount; ++i)
CacheChildren(current.GetChild(i), cache);
}
public static string GenerateTransformPath(Transform rootBone, Transform child)
{
var path = child.name;
if (child == rootBone)
return path;
var parent = child.parent;
do
{
path = parent.name + "/" + path;
parent = parent.parent;
} while (parent != rootBone && parent != null);
return path;
}
public static bool GetSpriteBonesTransforms(SpriteSkin spriteSkin, out Transform[] outTransform)
{
var rootBone = spriteSkin.rootBone;
var spriteBones = spriteSkin.sprite.GetBones();
if (rootBone == null)
throw new ArgumentException("rootBone parameter cannot be null");
if (spriteBones == null)
throw new ArgumentException("spriteBones parameter cannot be null");
outTransform = new Transform[spriteBones.Length];
var boneObjects = rootBone.GetComponentsInChildren<Bone>();
if (boneObjects != null && boneObjects.Length >= spriteBones.Length)
{
using (SpriteSkin.Profiling.getSpriteBonesTransformFromGuid.Auto())
{
var i = 0;
for (; i < spriteBones.Length; ++i)
{
var boneHash = spriteBones[i].guid;
var boneTransform = Array.Find(boneObjects, x => (x.guid == boneHash));
if (boneTransform == null)
break;
outTransform[i] = boneTransform.transform;
}
if (i >= spriteBones.Length)
return true;
}
}
var hierarchyCache = spriteSkin.hierarchyCache;
if (hierarchyCache.Count == 0)
spriteSkin.CacheHierarchy();
// If unable to successfully map via guid, fall back to path
return GetSpriteBonesTransformFromPath(spriteBones, hierarchyCache, outTransform);
}
static bool GetSpriteBonesTransformFromPath(SpriteBone[] spriteBones, Dictionary<int, List<SpriteSkin.TransformData>> hierarchyCache, Transform[] outNewBoneTransform)
{
using (SpriteSkin.Profiling.getSpriteBonesTransformFromPath.Auto())
{
string[] bonePath = null;
var foundBones = true;
for (var i = 0; i < spriteBones.Length; ++i)
{
var nameHash = spriteBones[i].name.GetHashCode();
if (!hierarchyCache.TryGetValue(nameHash, out var children))
{
outNewBoneTransform[i] = null;
foundBones = false;
continue;
}
if (children.Count == 1)
outNewBoneTransform[i] = children[0].transform;
else
{
if (bonePath == null)
bonePath = new string[spriteBones.Length];
if (bonePath[i] == null)
CalculateBoneTransformsPath(i, spriteBones, bonePath);
var m = 0;
for (; m < children.Count; ++m)
{
if (children[m].fullName.Contains(bonePath[i]))
{
outNewBoneTransform[i] = children[m].transform;
break;
}
}
if (m >= children.Count)
{
outNewBoneTransform[i] = null;
foundBones = false;
}
}
}
return foundBones;
}
}
static void CalculateBoneTransformsPath(int index, SpriteBone[] spriteBones, string[] paths)
{
var spriteBone = spriteBones[index];
var parentId = spriteBone.parentId;
var bonePath = spriteBone.name;
if (parentId != -1)
{
if (paths[parentId] == null)
CalculateBoneTransformsPath(spriteBone.parentId, spriteBones, paths);
paths[index] = $"{paths[parentId]}/{bonePath}";
}
else
paths[index] = bonePath;
}
}
}