Example #1
0
        public TransformPoseSave(GameObject gameObject)
        {
            rootObject    = gameObject;
            startPosition = gameObject.transform.position;
            startRotation = gameObject.transform.rotation;
            startScale    = gameObject.transform.lossyScale;
            #region originalTransforms
            {
                originalTransforms = new Dictionary <Transform, SaveData>();
                Action <Transform, Transform> SaveTransform = null;
                SaveTransform = (t, root) =>
                {
                    if (!originalTransforms.ContainsKey(t))
                    {
                        var saveTransform = new SaveData(t);
                        originalTransforms.Add(t, saveTransform);
                    }
                    for (int i = 0; i < t.childCount; i++)
                    {
                        SaveTransform(t.GetChild(i), root);
                    }
                };
                SaveTransform(gameObject.transform, gameObject.transform);
            }
            #endregion
            #region saveTransforms
            {
                var bindPathTransforms    = new Dictionary <string, SaveData>();
                var prefabPathTransforms  = new Dictionary <string, SaveData>();
                var defaultPathTransforms = new Dictionary <string, SaveData>();
                {
                    var uAvatarSetupTool = new UAvatarSetupTool();
                    Action <Dictionary <string, SaveData>, Transform, Transform, bool> SaveTransform = null;
                    SaveTransform = (transforms, t, root, scaleOverwrite) =>
                    {
                        var path = AnimationUtility.CalculateTransformPath(t, root);
                        if (!transforms.ContainsKey(path))
                        {
                            var saveTransform = new SaveData(t);
                            transforms.Add(path, saveTransform);
                        }
                        else if (scaleOverwrite)
                        {
                            transforms[path].localScale = t.localScale;
                            transforms[path].scale      = t.lossyScale;
                        }
                        for (int i = 0; i < t.childCount; i++)
                        {
                            SaveTransform(transforms, t.GetChild(i), root, scaleOverwrite);
                        }
                    };
                    {
                        List <GameObject>   goList  = new List <GameObject>();
                        Action <GameObject> AddList = null;
                        AddList = (obj) =>
                        {
                            goList.Add(obj);
                            for (int i = 0; i < obj.transform.childCount; i++)
                            {
                                AddList(obj.transform.GetChild(i).gameObject);
                            }
                        };
                        Action <GameObject> GetBindPose = (go) =>
                        {
                            var goTmp = GameObject.Instantiate <GameObject>(go);
                            goTmp.hideFlags |= HideFlags.HideAndDontSave;
                            AddList(goTmp);
                            if (uAvatarSetupTool.SampleBindPose(goTmp))
                            {
                                var rootT = goTmp.transform;
                                #region Root
                                rootT.localPosition = gameObject.transform.localPosition;
                                rootT.localRotation = gameObject.transform.localRotation;
                                rootT.localScale    = gameObject.transform.localScale;
                                #endregion
                                SaveTransform(defaultPathTransforms, rootT, rootT, false);
                                SaveTransform(bindPathTransforms, rootT, rootT, false);
                            }
                            GameObject.DestroyImmediate(goTmp);
                        };
#if UNITY_2018_2_OR_NEWER
                        var prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject) as GameObject;
#else
                        var prefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
#endif
                        if (prefab != null)
                        {
                            var go = GameObject.Instantiate <GameObject>(prefab);
                            AnimatorUtility.DeoptimizeTransformHierarchy(go);
                            go.hideFlags |= HideFlags.HideAndDontSave;
                            AddList(go);
                            #region BindPose
                            if (go.GetComponentInChildren <SkinnedMeshRenderer>() != null)
                            {
                                GetBindPose(go);
                            }
                            #endregion
                            #region PrefabPose
                            {  //Root
                                go.transform.localPosition = gameObject.transform.localPosition;
                                go.transform.localRotation = gameObject.transform.localRotation;
                                go.transform.localScale    = gameObject.transform.localScale;
                            }
                            SaveTransform(defaultPathTransforms, go.transform, go.transform, true);
                            SaveTransform(prefabPathTransforms, go.transform, go.transform, false);
                            #endregion
                            GameObject.DestroyImmediate(go);
                        }
                        else
                        {
                            #region BindPose
                            if (gameObject.GetComponentInChildren <SkinnedMeshRenderer>() != null)
                            {
                                GetBindPose(gameObject);
                            }
                            #endregion
                        }
                        foreach (var go in goList)
                        {
                            if (go != null)
                            {
                                GameObject.DestroyImmediate(go);
                            }
                        }
                    }
                    //GameObjectPose
                    SaveTransform(defaultPathTransforms, gameObject.transform, gameObject.transform, false);
                }
                bindTransforms   = Paths2Transforms(bindPathTransforms, gameObject.transform);
                prefabTransforms = Paths2Transforms(prefabPathTransforms, gameObject.transform);
            }
            #endregion
        }
        public void CreateExtraTransforms()
        {
            #region saveTransforms
            {
                var bindPathTransforms             = new Dictionary <string, SaveData>();
                var tposePathTransforms            = new Dictionary <string, SaveData>();
                var prefabPathTransforms           = new Dictionary <string, SaveData>();
                var humanDescriptionPathTransforms = new Dictionary <string, SaveData>();
                var defaultPathTransforms          = new Dictionary <string, SaveData>();
                {
#if UNITY_2018_2_OR_NEWER
                    var uAvatarSetupTool = new UAvatarSetupTool_2018_2();
#else
                    var uAvatarSetupTool = new UAvatarSetupTool();
#endif
                    Action <Dictionary <string, SaveData>, Transform, Transform, bool> SaveTransform = null;
                    SaveTransform = (transforms, t, root, scaleOverwrite) =>
                    {
                        var path = AnimationUtility.CalculateTransformPath(t, root);
                        if (!transforms.ContainsKey(path))
                        {
                            var saveTransform = new SaveData(t);
                            transforms.Add(path, saveTransform);
                        }
                        else if (scaleOverwrite)
                        {
                            transforms[path].localScale = t.localScale;
                            transforms[path].scale      = t.lossyScale;
                        }
                        for (int i = 0; i < t.childCount; i++)
                        {
                            SaveTransform(transforms, t.GetChild(i), root, scaleOverwrite);
                        }
                    };
                    {
                        List <GameObject>   goList  = new List <GameObject>();
                        Action <GameObject> AddList = null;
                        AddList = (obj) =>
                        {
                            goList.Add(obj);
                            for (int i = 0; i < obj.transform.childCount; i++)
                            {
                                AddList(obj.transform.GetChild(i).gameObject);
                            }
                        };
                        Action <GameObject> GetBindPose = (go) =>
                        {
                            if (go.GetComponentInChildren <SkinnedMeshRenderer>() == null)
                            {
                                return;
                            }

                            var goTmp = GameObject.Instantiate <GameObject>(go);
                            goTmp.hideFlags |= HideFlags.HideAndDontSave;
                            goTmp.transform.SetParent(null);
                            goTmp.transform.localPosition = Vector3.zero;
                            goTmp.transform.localRotation = Quaternion.identity;
                            goTmp.transform.localScale    = Vector3.one;
                            AddList(goTmp);
                            if (uAvatarSetupTool.SampleBindPose(goTmp))
                            {
                                var rootT = goTmp.transform;
                                #region Root
                                rootT.localPosition = rootObject.transform.localPosition;
                                rootT.localRotation = rootObject.transform.localRotation;
                                rootT.localScale    = rootObject.transform.localScale;
                                #endregion
                                SaveTransform(defaultPathTransforms, rootT, rootT, false);
                                SaveTransform(bindPathTransforms, rootT, rootT, false);
                            }
                            GameObject.DestroyImmediate(goTmp);
                        };
                        Action <GameObject> GetTPoseHumanDescriptionPose = (go) =>
                        {
                            var animator = go.GetComponent <Animator>();
                            if (animator == null || !animator.isHuman || animator.avatar == null)
                            {
                                return;
                            }

                            var goTmp = GameObject.Instantiate <GameObject>(go);
                            goTmp.hideFlags |= HideFlags.HideAndDontSave;
                            goTmp.transform.SetParent(null);
                            goTmp.transform.localPosition = Vector3.zero;
                            goTmp.transform.localRotation = Quaternion.identity;
                            goTmp.transform.localScale    = Vector3.one;
                            AddList(goTmp);
                            if (uAvatarSetupTool.SampleBindPose(goTmp) &&   //Reset
                                uAvatarSetupTool.SampleTPose(goTmp))
                            {
                                var rootT = goTmp.transform;
                                #region Root
                                rootT.localPosition = rootObject.transform.localPosition;
                                rootT.localRotation = rootObject.transform.localRotation;
                                rootT.localScale    = rootObject.transform.localScale;
                                #endregion
                                SaveTransform(defaultPathTransforms, rootT, rootT, false);
                                SaveTransform(tposePathTransforms, rootT, rootT, false);
                            }
                            if (uAvatarSetupTool.SampleBindPose(goTmp))   //Reset
                            {
                                HumanDescription?humanDescription = null;
#if UNITY_2019_1_OR_NEWER
                                humanDescription = animator.avatar.humanDescription;
#endif
                                if (!humanDescription.HasValue)
                                {
                                    var modelImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(animator.avatar)) as ModelImporter;
                                    if (modelImporter != null)
                                    {
                                        humanDescription = modelImporter.humanDescription;
                                    }
                                }
                                if (humanDescription.HasValue)
                                {
                                    var hd         = humanDescription.Value;
                                    var transforms = goTmp.GetComponentsInChildren <Transform>(true);
                                    for (int i = 0; i < hd.skeleton.Length; i++)
                                    {
                                        var t = Array.Find(transforms, x => x.name == hd.skeleton[i].name);
                                        if (t == null)
                                        {
                                            continue;
                                        }
                                        t.localPosition = hd.skeleton[i].position;
                                        t.localRotation = hd.skeleton[i].rotation;
                                        t.localScale    = hd.skeleton[i].scale;
                                    }
                                    var rootT = goTmp.transform;
                                    #region Root
                                    rootT.localPosition = rootObject.transform.localPosition;
                                    rootT.localRotation = rootObject.transform.localRotation;
                                    rootT.localScale    = rootObject.transform.localScale;
                                    #endregion
                                    SaveTransform(defaultPathTransforms, rootT, rootT, false);
                                    SaveTransform(humanDescriptionPathTransforms, rootT, rootT, false);
                                }
                            }
                            GameObject.DestroyImmediate(goTmp);
                        };
#if UNITY_2018_2_OR_NEWER
                        var prefab = PrefabUtility.GetCorrespondingObjectFromSource(rootObject) as GameObject;
#else
                        var prefab = PrefabUtility.GetPrefabParent(rootObject) as GameObject;
#endif
                        if (prefab != null)
                        {
                            var go = GameObject.Instantiate <GameObject>(prefab);
                            AnimatorUtility.DeoptimizeTransformHierarchy(go);
                            go.hideFlags |= HideFlags.HideAndDontSave;
                            AddList(go);
                            #region BindPose
                            GetBindPose(go);
                            #endregion
                            #region TPose
                            GetTPoseHumanDescriptionPose(go);
                            #endregion
                            #region PrefabPose
                            {  //Root
                                go.transform.localPosition = rootObject.transform.localPosition;
                                go.transform.localRotation = rootObject.transform.localRotation;
                                go.transform.localScale    = rootObject.transform.localScale;
                            }
                            SaveTransform(defaultPathTransforms, go.transform, go.transform, true);
                            SaveTransform(prefabPathTransforms, go.transform, go.transform, false);
                            #endregion
                            GameObject.DestroyImmediate(go);
                        }
                        else
                        {
                            #region BindPose
                            GetBindPose(rootObject);
                            #endregion
                            #region TPose
                            GetTPoseHumanDescriptionPose(rootObject);
                            #endregion
                        }
                        foreach (var go in goList)
                        {
                            if (go != null)
                            {
                                GameObject.DestroyImmediate(go);
                            }
                        }
                    }
                    //GameObjectPose
                    SaveTransform(defaultPathTransforms, rootObject.transform, rootObject.transform, false);
                }
                bindTransforms             = Paths2Transforms(bindPathTransforms, rootObject.transform);
                tposeTransforms            = Paths2Transforms(tposePathTransforms, rootObject.transform);
                prefabTransforms           = Paths2Transforms(prefabPathTransforms, rootObject.transform);
                humanDescriptionTransforms = Paths2Transforms(humanDescriptionPathTransforms, rootObject.transform);
            }
            #endregion
        }