Ragdoll 自動配置

 人物骨骼的引用綁定,如果是要一個個手動設置,大概是相當讓人頭痛的事情吧。

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Reflection;
using System.IO;
using System;

public class SetRagdoll : EditorWindow
    {
    private GUIStyle m_HeaderLabelStyle;
    //  public Animator animator;
    public static GameObject Character;

        [MenuItem("Tool/SetRagdoll", false, 11)]
        public static void SetRagdollWindow()
        {

        var window = EditorWindow.GetWindow<SetRagdoll>(true, "SetRagdoll");
        window.minSize = new Vector2(500, 100);
    }

    private void OnEnable()
    {
        if(m_HeaderLabelStyle == null)
        {
            m_HeaderLabelStyle = new GUIStyle(EditorStyles.label);
            m_HeaderLabelStyle.wordWrap = true;
        }

    }
    private void OnGUI()
        {
        var description = "This is set Ragdoll for a character";
        EditorGUILayout.LabelField(description, m_HeaderLabelStyle);
        GUILayout.Space(5);
        Character = EditorGUILayout.ObjectField("character", Character, typeof(GameObject), true) as GameObject;
        GUILayout.Space(20);
        if (GUILayout.Button("Build")) {
            AddRagdoll();
            Close();
            }
        }

        private  void AddRagdoll()
        {
            //  AddAbility(controller, typeof(Opsive.ThirdPersonController.Wrappers.Abilities.Die), string.Empty, Abilities.Ability.AbilityStartType.Manual, Abilities.Ability.AbilityStopType.Manual);

            var ragdollBuilderType = Type.GetType("UnityEditor.RagdollBuilder, UnityEditor");
            var windows = Resources.FindObjectsOfTypeAll(ragdollBuilderType);
            // Open the Ragdoll Builder if it isn't already opened.
            if(windows == null || windows.Length == 0)
            {
                EditorApplication.ExecuteMenuItem("GameObject/3D Object/Ragdoll...");
                windows = Resources.FindObjectsOfTypeAll(ragdollBuilderType);
            }

            if(windows != null && windows.Length > 0)
            {
                var ragdollWindow = windows[0] as ScriptableWizard;
                var animator = Character.GetComponentInChildren<Animator>();
#if UNITY_4_6 || UNITY_4_7
                SetFieldValue(ragdollWindow, "root", animator.GetBoneTransform(HumanBodyBones.Hips));
#else
                SetFieldValue(ragdollWindow, "pelvis", animator.GetBoneTransform(HumanBodyBones.Hips));
#endif
                SetFieldValue(ragdollWindow, "leftHips", animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg));
                SetFieldValue(ragdollWindow, "leftKnee", animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg));
                SetFieldValue(ragdollWindow, "leftFoot",  animator.GetBoneTransform(HumanBodyBones.LeftFoot));
                SetFieldValue(ragdollWindow, "rightHips", animator.GetBoneTransform(HumanBodyBones.RightUpperLeg));
                SetFieldValue(ragdollWindow, "rightKnee", animator.GetBoneTransform(HumanBodyBones.RightLowerLeg));
                SetFieldValue(ragdollWindow, "rightFoot", animator.GetBoneTransform(HumanBodyBones.RightFoot));
                SetFieldValue(ragdollWindow, "leftArm",   animator.GetBoneTransform(HumanBodyBones.LeftUpperArm));
                SetFieldValue(ragdollWindow, "leftElbow", animator.GetBoneTransform(HumanBodyBones.LeftLowerArm));
                SetFieldValue(ragdollWindow, "rightArm",   animator.GetBoneTransform(HumanBodyBones.RightUpperArm));
                SetFieldValue(ragdollWindow, "rightElbow", animator.GetBoneTransform(HumanBodyBones.RightLowerArm));
                SetFieldValue(ragdollWindow, "middleSpine", animator.GetBoneTransform(HumanBodyBones.Spine));
                SetFieldValue(ragdollWindow, "head", animator.GetBoneTransform(HumanBodyBones.Head));
            

                var method = ragdollWindow.GetType().GetMethod("CheckConsistency", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                if(method != null)
                {
                    ragdollWindow.errorString = (string)method.Invoke(ragdollWindow, null);
                    ragdollWindow.isValid = string.IsNullOrEmpty(ragdollWindow.errorString);
                }
            }
        }

        /// <summary>
        /// Use reflection to set the value of the field.
        /// </summary>
        private  void SetFieldValue(ScriptableWizard obj, string name, object value)
        {
            if(value == null)
            {
                return;
            }

            var field = obj.GetType().GetField(name);
            if(field != null)
            {
                field.SetValue(obj, value);
            }
        }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章