Last active
March 25, 2021 13:47
-
-
Save MoePus/1497229d02c0d8a06bcef7de8a698c2b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if UNITY_EDITOR | |
using UnityEngine; | |
using UnityEditor; | |
using CustomAvatar; | |
using System; | |
using System.Linq; | |
using System.Reflection; | |
using System.Collections.Generic; | |
public class DBTransfer : MonoBehaviour | |
{ | |
static List<string> GetPathTil(GameObject Top, Transform child) | |
{ | |
var result = new List<string>(); | |
result.Add(child.gameObject.name); | |
while (child.parent != null) | |
{ | |
if (child.parent.gameObject == Top) | |
{ | |
result.Reverse(); | |
return result; | |
} | |
var gameobj = child.parent.gameObject; | |
child = gameobj.transform; | |
result.Add(gameobj.name); | |
} | |
return new List<string>(); | |
} | |
static Transform GetChildrenByPath(GameObject Top, List<string> path) | |
{ | |
var parent = Top.transform; | |
foreach (string name in path) | |
{ | |
parent = parent.Find(name); | |
if (!parent) | |
return null; | |
} | |
return parent; | |
} | |
static void CopyClassValues<T>(T srcComp, T destComp, GameObject srcTop, GameObject destTop) | |
{ | |
FieldInfo[] sourceFields = srcComp.GetType().GetFields( | |
BindingFlags.Public | | |
BindingFlags.NonPublic | | |
BindingFlags.Instance | |
); | |
for (int i = 0; i < sourceFields.Length; i++) | |
{ | |
var value = sourceFields[i].GetValue(srcComp); | |
if (value is Transform) | |
{ | |
if (value.ToString() == "null") | |
{ | |
sourceFields[i].SetValue(destComp, null); | |
} | |
else | |
{ | |
var path = GetPathTil(srcTop, (Transform)value); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
if (destTransform) | |
{ | |
sourceFields[i].SetValue(destComp, destTransform); | |
} | |
else | |
{ | |
sourceFields[i].SetValue(destComp, null); | |
} | |
} | |
} | |
else if (value is List<Transform>) | |
{ | |
List<Transform> _value = (List<Transform>)value; | |
List<Transform> _destVal = new List<Transform>(Enumerable.Repeat<Transform>(null, _value.Count)); | |
for (int index = 0; index < _value.Count; index++) | |
{ | |
if (_value[index].ToString() != "null") | |
{ | |
var path = GetPathTil(srcTop, _value[index]); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
if (destTransform) | |
{ | |
_destVal[index] = destTransform; | |
} | |
} | |
} | |
sourceFields[i].SetValue(destComp, _destVal); | |
} | |
else if (value is List<DynamicBoneColliderBase>) | |
{ | |
List<DynamicBoneColliderBase> _value = (List<DynamicBoneColliderBase>)value; | |
List<DynamicBoneColliderBase> _destVal = new List<DynamicBoneColliderBase>(Enumerable.Repeat<DynamicBoneColliderBase>(null, _value.Count)); | |
for (int index = 0; index < _value.Count; index++) | |
{ | |
var path = GetPathTil(srcTop, _value[index].transform); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
if (destTransform) | |
{ | |
_destVal[index] = destTransform.gameObject.GetComponent<DynamicBoneColliderBase>(); | |
} | |
} | |
sourceFields[i].SetValue(destComp, _destVal); | |
} | |
else if (value is SkinnedMeshRenderer meshRenderer) | |
{ | |
var path = GetPathTil(srcTop, meshRenderer.gameObject.transform); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
if (destTransform) | |
{ | |
sourceFields[i].SetValue(destComp, destTransform.gameObject.GetComponent<SkinnedMeshRenderer>()); | |
} | |
else | |
{ | |
sourceFields[i].SetValue(destComp, null); | |
} | |
} | |
else if (value is Animator animator) | |
{ | |
var path = GetPathTil(srcTop, animator.gameObject.transform); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
if (destTransform) | |
{ | |
sourceFields[i].SetValue(destComp, destTransform.gameObject.GetComponent<Animator>()); | |
} | |
else | |
{ | |
sourceFields[i].SetValue(destComp, null); | |
} | |
} | |
else if (value is GameObject[] objs) | |
{ | |
GameObject[] _destVal = new List<GameObject>(Enumerable.Repeat<GameObject>(null, objs.Length)).ToArray(); | |
for (int index = 0; index < objs.Length; index++) | |
{ | |
var path = GetPathTil(srcTop, objs[index].transform); | |
Transform destTransform = GetChildrenByPath(destTop, path); | |
_destVal[index] = destTransform?.gameObject; | |
} | |
sourceFields[i].SetValue(destComp, _destVal); | |
} | |
else | |
{ | |
sourceFields[i].SetValue(destComp, value); | |
} | |
} | |
} | |
static void TransferComponent<T>(GameObject source, GameObject dest, GameObject srcTop, GameObject destTop) where T : Component | |
{ | |
var srcComps = source.GetComponents<T>(); | |
if (srcComps.Length == 0) | |
return; | |
var destComps = dest.GetComponents<T>(); | |
foreach (T destComp in destComps) | |
{ | |
DestroyImmediate(destComp); | |
} | |
foreach (T srcComp in srcComps) | |
{ | |
var destComp = dest.AddComponent<T>(); | |
try | |
{ | |
CopyClassValues(srcComp, destComp, srcTop, destTop); | |
} | |
catch (Exception e) | |
{ | |
Debug.Log(e.StackTrace); | |
Debug.Log(e.Message); | |
} | |
} | |
} | |
static void DescendTransfer(GameObject source, GameObject dest, GameObject srcTop, GameObject destTop, int pass = 0) | |
{ | |
void Transfer(GameObject _srcObj, GameObject _destObj) | |
{ | |
if (pass < 1) | |
{ | |
_destObj.transform.localPosition = _srcObj.transform.localPosition; | |
_destObj.transform.localEulerAngles = _srcObj.transform.localEulerAngles; | |
_destObj.transform.localScale = _srcObj.transform.localScale; | |
TransferComponent<DynamicBoneCollider>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<DynamicBonePlaneCollider>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<FirstPersonExclusion>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<AvatarDescriptor>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<EyeTrackingManager>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<VRIKManager>(_srcObj, _destObj, srcTop, destTop); | |
TransferComponent<PoseManager>(_srcObj, _destObj, srcTop, destTop); | |
} | |
else | |
{ | |
TransferComponent<DynamicBone>(_srcObj, _destObj, srcTop, destTop); | |
} | |
} | |
if (source == srcTop) | |
{ | |
Transfer(source, dest); | |
} | |
foreach (Transform child in source.transform) | |
{ | |
var srcObj = child.gameObject; | |
if (srcObj.GetComponent<SkinnedMeshRenderer>()) | |
continue; | |
GameObject destObj = dest.transform.Find(srcObj.name)?.gameObject; | |
if (!destObj) | |
{ | |
destObj = new GameObject(srcObj.name); | |
destObj.transform.parent = dest.transform; | |
} | |
Transfer(srcObj, destObj); | |
DescendTransfer(srcObj, destObj, srcTop, destTop, pass); | |
} | |
} | |
[MenuItem("BeatSaber/Transfer Components")] | |
static void Transfer() | |
{ | |
var source = GameObject.Find("Source"); | |
var destTop = GameObject.Find("_CustomAvatar"); | |
var destAvatar = destTop.GetComponentInChildren<Animator>()?.gameObject; | |
if (!destAvatar) | |
{ | |
throw new NullReferenceException(); | |
} | |
DescendTransfer(source, destTop, source, destTop); | |
DescendTransfer(source, destTop, source, destTop, 1); | |
} | |
} | |
public class GenericGenerate : MonoBehaviour | |
{ | |
static bool isChildOf(Transform that, GameObject parent) | |
{ | |
while (that.parent != null) | |
{ | |
if (that.parent == parent.transform) | |
return true; | |
that = that.parent; | |
} | |
return false; | |
} | |
static GameObject FindGameObject(GameObject parent, string name) | |
{ | |
var objects = FindObjectsOfType<GameObject>(); | |
foreach (GameObject obj in objects) | |
{ | |
if (isChildOf(obj.transform, parent) && obj.name == name) | |
return obj; | |
} | |
return null; | |
} | |
static GameObject GenerateChild(GameObject parent, string name, Transform transform = null) | |
{ | |
var obj = parent.transform.Find(name)?.gameObject; | |
if (obj) | |
return obj; | |
obj = new GameObject(name); | |
obj.transform.parent = parent.transform; | |
if (transform) | |
{ | |
obj.transform.position = transform.position; | |
obj.transform.eulerAngles = transform.eulerAngles; | |
obj.transform.localScale = transform.localScale; | |
} | |
else | |
{ | |
obj.transform.localPosition = new Vector3(0, 0, 0); | |
obj.transform.localEulerAngles = new Vector3(0, 0, 0); | |
obj.transform.localScale = new Vector3(1, 1, 1); | |
} | |
return obj; | |
} | |
class TargetInfo | |
{ | |
public HumanBodyBones bone { get; set; } | |
public Transform targetTransform { get; set; } | |
} | |
[MenuItem("BeatSaber/Generate Common Objects")] | |
static void TopGenerate() | |
{ | |
var top = GameObject.Find("_CustomAvatar"); | |
var animator = top.GetComponentInChildren<Animator>(); | |
var avatar = animator?.gameObject; | |
var armature = avatar.transform.Find("Armature"); | |
GenerateChild(top, "Body"); | |
if (armature) | |
{ | |
var targets = new Dictionary<string, TargetInfo>() | |
{ | |
{ "Head", new TargetInfo{ bone = HumanBodyBones.Head , targetTransform = null} }, | |
{ "Pelvis", new TargetInfo{ bone = HumanBodyBones.Hips , targetTransform = null} }, | |
{ "LeftHand", new TargetInfo{ bone = HumanBodyBones.LeftHand , targetTransform = null} }, | |
{ "RightHand", new TargetInfo{ bone = HumanBodyBones.RightHand , targetTransform = null} }, | |
{ "LeftLeg", new TargetInfo{ bone = HumanBodyBones.LeftToes , targetTransform = null} }, | |
{ "RightLeg", new TargetInfo{ bone = HumanBodyBones.RightToes , targetTransform = null} }, | |
}; | |
foreach (var target in targets) | |
{ | |
var armTransform = animator.GetBoneTransform(target.Value.bone); | |
var targetObj = GenerateChild(top, target.Key, armTransform); | |
GenerateChild(targetObj, target.Key + "Target"); | |
} | |
} | |
var ikMgr = avatar.GetComponent<CustomAvatar.VRIKManager>(); | |
if (!ikMgr) | |
{ | |
ikMgr = avatar.AddComponent<CustomAvatar.VRIKManager>(); | |
} | |
{ | |
ikMgr.references_root = avatar.transform; | |
ikMgr.references_pelvis = animator.GetBoneTransform(HumanBodyBones.Hips); | |
ikMgr.references_spine = animator.GetBoneTransform(HumanBodyBones.Spine); | |
ikMgr.references_chest = animator.GetBoneTransform(HumanBodyBones.Chest); | |
ikMgr.references_neck = animator.GetBoneTransform(HumanBodyBones.Neck); | |
ikMgr.references_head = animator.GetBoneTransform(HumanBodyBones.Head); | |
ikMgr.references_leftShoulder = animator.GetBoneTransform(HumanBodyBones.LeftShoulder); | |
ikMgr.references_leftUpperArm = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm); | |
ikMgr.references_leftForearm = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm); | |
ikMgr.references_leftHand = animator.GetBoneTransform(HumanBodyBones.LeftHand); | |
ikMgr.references_rightShoulder = animator.GetBoneTransform(HumanBodyBones.RightShoulder); | |
ikMgr.references_rightUpperArm = animator.GetBoneTransform(HumanBodyBones.RightUpperArm); | |
ikMgr.references_rightForearm = animator.GetBoneTransform(HumanBodyBones.RightLowerArm); | |
ikMgr.references_rightHand = animator.GetBoneTransform(HumanBodyBones.RightHand); | |
ikMgr.references_leftThigh = animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg); | |
ikMgr.references_leftCalf = animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg); | |
ikMgr.references_leftFoot = animator.GetBoneTransform(HumanBodyBones.LeftFoot); | |
ikMgr.references_leftToes = animator.GetBoneTransform(HumanBodyBones.LeftToes); | |
ikMgr.references_rightThigh = animator.GetBoneTransform(HumanBodyBones.RightUpperLeg); | |
ikMgr.references_rightCalf = animator.GetBoneTransform(HumanBodyBones.RightLowerLeg); | |
ikMgr.references_rightFoot = animator.GetBoneTransform(HumanBodyBones.RightFoot); | |
ikMgr.references_rightToes = animator.GetBoneTransform(HumanBodyBones.RightToes); | |
} | |
{ | |
ikMgr.solver_spine_headTarget = FindGameObject(top, "HeadTarget").transform; | |
ikMgr.solver_spine_pelvisTarget = FindGameObject(top, "PelvisTarget").transform; | |
// ikMgr.solver_leftArm_target = FindGameObject(top, "LeftHandTarget").transform; | |
// ikMgr.solver_rightArm_target = FindGameObject(top, "RightHandTarget").transform; | |
ikMgr.solver_leftLeg_target = FindGameObject(top, "LeftLegTarget").transform; | |
ikMgr.solver_rightLeg_target = FindGameObject(top, "RightLegTarget").transform; | |
} | |
} | |
static void MirrorTransform(Transform A, Transform B, float angleMul = 1.0f) | |
{ | |
B.transform.localPosition = new Vector3( | |
-A.transform.localPosition.x, | |
A.transform.localPosition.y, | |
A.transform.localPosition.z); | |
B.transform.localEulerAngles = new Vector3( | |
A.transform.localEulerAngles.x * angleMul, | |
-A.transform.localEulerAngles.y * angleMul, | |
-A.transform.localEulerAngles.z * angleMul); | |
} | |
[MenuItem("BeatSaber/Mirror Targets")] | |
static void Mirror() | |
{ | |
var top = GameObject.Find("_CustomAvatar"); | |
{ | |
var leftHand = top.transform.Find("LeftHand"); | |
var leftHandTarget = leftHand.transform.Find("LeftHandTarget"); | |
var rightHand = top.transform.Find("RightHand"); | |
var rightHandTarget = rightHand.transform.Find("RightHandTarget"); | |
MirrorTransform(leftHand, rightHand); | |
leftHandTarget.transform.parent = top.transform; | |
rightHandTarget.transform.parent = top.transform; | |
MirrorTransform(leftHandTarget, rightHandTarget, -1.0f); | |
leftHandTarget.transform.parent = leftHand.transform; | |
rightHandTarget.transform.parent = rightHand.transform; | |
} | |
{ | |
var leftLeg = top.transform.Find("LeftLeg"); | |
var leftLegTarget = leftLeg.transform.Find("LeftLegTarget"); | |
var rightLeg = top.transform.Find("RightLeg"); | |
var rightLegTarget = rightLeg.transform.Find("RightLegTarget"); | |
MirrorTransform(leftLeg, rightLeg); | |
leftLegTarget.transform.parent = top.transform; | |
rightLegTarget.transform.parent = top.transform; | |
MirrorTransform(leftLegTarget, rightLegTarget); | |
leftLegTarget.transform.parent = leftLeg.transform; | |
rightLegTarget.transform.parent = rightLeg.transform; | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment