Skip to content

Instantly share code, notes, and snippets.

@boxp
Forked from wraikny/SetDynamicBoneProperty.cs
Last active December 11, 2018 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boxp/137751c9645034e0cb1a53a6d2366058 to your computer and use it in GitHub Desktop.
Save boxp/137751c9645034e0cb1a53a6d2366058 to your computer and use it in GitHub Desktop.
DynamicBone一括指定スクリプトに位置指定も追加しようとしたやつ forked from: Dynamic Boneのプロパティ操作を楽にするやつ
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement; //!< 追加
#endif
// 参考: https://qiita.com/sango/items/4b9035c3e75d497f91ef#_reference-00718cd16d3962c60da9
public class SetDynamicBoneProperty : MonoBehaviour
{
[System.Serializable]
public class DynamicBoneValueHolder
{
[SerializeField] public string Name;
[SerializeField] public float Damping;
[SerializeField] public float Elastisity;
[SerializeField] public float Stiffness;
[SerializeField] public float Inert;
// 前髪など特定の位置にあるボーンの値のみを変更するためのインデックス
[SerializeField] public int[] PositionIndices;
public DynamicBoneValueHolder()
{
Name = "";
Damping = 0.0f;
Elastisity = 0.0f;
Stiffness = 0.0f;
Inert = 0.0f;
}
public DynamicBoneValueHolder(string name, float d, float e, float s, float i)
{
Name = name;
Damping = d;
Elastisity = e;
Stiffness = s;
Inert = i;
}
public DynamicBoneValueHolder(string name, float d, float e, float s, float i, int[] positionIndices)
{
Name = name;
Damping = d;
Elastisity = e;
Stiffness = s;
Inert = i;
PositionIndices = positionIndices;
}
}
[SerializeField]
DynamicBoneValueHolder Default = new DynamicBoneValueHolder("Default", 0.2f, 0.2f, 0.3f, 0.2f);
[SerializeField]
DynamicBoneValueHolder[] Properties = new DynamicBoneValueHolder[]
{
new DynamicBoneValueHolder("Bust", 0.8f, 0.8f, 0.8f, 0.8f),
// 前髪
new DynamicBoneValueHolder("Hair", 0.2f, 0.5f, 0.5f, 0.0f, new int[] { 5, 6, 7 }),
// 三つ編み
new DynamicBoneValueHolder("Hair", 0.2f, 0.5f, 0.5f, 0.0f, new int[] { 3, 4 }),
// 後ろ髪
new DynamicBoneValueHolder("Hair", 0.2f, 0.5f, 0.5f, 0.0f, new int[] { 2 }),
new DynamicBoneValueHolder("Skirt", 0.2f, 0.2f, 0.3f, 0.2f)
};
IEnumerable<DynamicBone> GetDynamicBones()
{
return gameObject.GetComponents<DynamicBone>();
}
void DeleteSameRoot()
{
var roots = new List<Transform>();
foreach (var c in GetDynamicBones())
{
if (roots.Contains(c.m_Root))
{
Debug.Log("Deleted Dynamic Bone which has same root");
DestroyImmediate(c);
}
else
{
roots.Add(c.m_Root);
}
}
}
void DeleteArmAndLegs()
{
foreach (var c in GetDynamicBones())
{
var list = new string[] { "Arm", "Leg" };
if (list.Any(c.m_Root.name.Contains))
{
Debug.Log("Deleted Dynamic Bone having root:" + c.m_Root.name);
DestroyImmediate(c);
}
}
}
void SetPropertyOne(DynamicBone c, DynamicBoneValueHolder h)
{
c.m_UpdateRate = 30;
c.m_Damping = h.Damping;
c.m_Elasticity = h.Elastisity;
c.m_Stiffness = h.Stiffness;
c.m_Inert = h.Inert;
}
bool isRootBoneNameContainsName(DynamicBone dynamicBone, string name)
{
return dynamicBone.m_Root.name.Contains(name);
}
bool isPositionIndicesIncludesDynamicBone(int dynamicBoneIndex, int[] positionIndices)
{
return positionIndices.Any(x => dynamicBoneIndex == x);
}
void SetProperty()
{
foreach (var v in GetDynamicBones().Select((dynamicBone, index) => new { dynamicBone, index }))
{
//
if (Properties.Any(x => isRootBoneNameContainsName(v.dynamicBone, x.Name) && isPositionIndicesIncludesDynamicBone(v.index, x.PositionIndices)))
{
SetPropertyOne(v.dynamicBone, Properties.Where(x => isRootBoneNameContainsName(v.dynamicBone, x.Name) && isPositionIndicesIncludesDynamicBone(v.index, x.PositionIndices)).First());
return;
}
if (Properties.Any(x => isRootBoneNameContainsName(v.dynamicBone, x.Name)))
{
SetPropertyOne(v.dynamicBone, Properties.Where(x => isRootBoneNameContainsName(v.dynamicBone, x.Name)).First());
return;
}
SetPropertyOne(v.dynamicBone, Default);
}
}
#if UNITY_EDITOR
/** -- Editor拡張クラス -- */
[CustomEditor(typeof(SetDynamicBoneProperty))]
public class SetDynamicBonePropertyEditor : Editor
{
SerializedProperty Default;
SerializedProperty Properties;
void OnEnable()
{
Default = serializedObject.FindProperty("Default");
Properties = serializedObject.FindProperty("Properties");
}
void Line()
{
GUILayout.Space(5.0f);
GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
GUILayout.Space(5.0f);
}
void SetDBProperty(SerializedProperty s, string name)
{
var guiStyle = new GUIStyle()
{
fontStyle = FontStyle.Bold
};
// GUILayout.Label(name, guiStyle);
EditorGUILayout.PropertyField(s, true);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
Draw();
serializedObject.ApplyModifiedProperties();
}
void Draw()
{
GUILayout.Label("同じRootを参照しているDynamic Bone(重複したうちの片方)を削除します");
if (GUILayout.Button("Delete Dynamic Bones having Same Root"))
{
var tc = target as SetDynamicBoneProperty;
tc.DeleteSameRoot();
EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
}
Line();
// GUILayout.Label("Rootの名前にArmまたはLegが含まれているものを削除します");
// GUILayout.Label("(このDynamic Boneが必要なのかどうなのかよくわかってない……)");
// if (GUILayout.Button("Delete Dynamic Bones of Arm or Leg"))
// {
// var tc = target as SetDynamicBoneProperty;
// tc.DeleteArmAndLegs();
// EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
// }
// Line();
// Line();
SetDBProperty(Default, "Default");
Line();
GUILayout.Label("以下はRootの名前にNameの文字列が含まれているかどうかで判別しています。");
Line();
SetDBProperty(Properties, "Properties");
if (GUILayout.Button("SetProperty"))
{
var t = target as SetDynamicBoneProperty;
foreach (var c in t.GetDynamicBones())
{
Undo.RecordObject(c, "Update Dynamic Bone Properties");
}
t.SetProperty();
EditorUtility.SetDirty(t);
}
}
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment