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 }