// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using UnityEditor;
using UnityEngine;
namespace MagicaCloth
{
///
/// Editorインスペクタ表示に関するユーティリティ
///
public static class EditorInspectorUtility
{
///
/// 現在のデータ状態をインスペクタにヘルプボックスで表示する
///
///
public static void DispDataStatus(IDataVerify verify)
{
if (verify == null)
return;
var code = verify.VerifyData();
//bool valid = verify.VerifyData() == Define.Error.None;
//var mestype = valid ? MessageType.Info : MessageType.Error;
var mestype = MessageType.Info;
if (Define.IsWarning(code))
mestype = MessageType.Warning;
if (Define.IsError(code))
mestype = MessageType.Error;
EditorGUILayout.HelpBox(verify.GetInformation(), mestype);
}
///
/// 現在のデータバージョン状態をインスペクタにヘルプボックスで表示する
///
///
public static void DispVersionStatus(CoreComponent core)
{
// Data Version
var code = core.VerifyDataVersion();
if (Define.IsNormal(code) == false)
EditorGUILayout.HelpBox(Define.GetErrorMessage(code), MessageType.Warning);
// Algorithm Version
var cloth = core as BaseCloth;
if (cloth != null)
{
code = cloth.VerifyAlgorithmVersion();
if (Define.IsNormal(code) == false)
EditorGUILayout.HelpBox(Define.GetErrorMessage(code), MessageType.Warning);
}
}
//===============================================================================
///
/// ベジェ曲線パラメータのインスペクタ描画と変更操作
///
/// パラメータ名
/// ベジェ曲線パラメータクラス
/// ベジェ曲線の最小値
/// ベジェ曲線の最大値
/// パラメータ表示浮動小数点数フォーマット
///
public static void BezierInspector(
string title,
SerializedProperty bval,
float minVal,
float maxVal,
string valFmt = "F2"
)
{
var startValue = bval.FindPropertyRelative("startValue");
var endValue = bval.FindPropertyRelative("endValue");
var curveValue = bval.FindPropertyRelative("curveValue");
var useEndValue = bval.FindPropertyRelative("useEndValue");
var useCurveValue = bval.FindPropertyRelative("useCurveValue");
// グラフ描画
float sv, ev, cv;
GetBezierValue(bval, out sv, out ev, out cv);
DrawGraph(sv, ev, cv, minVal, maxVal, valFmt);
// パラメータ
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("", GUILayout.Width(32));
EditorGUILayout.Slider(startValue, minVal, maxVal, "start");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
useEndValue.boolValue = EditorGUILayout.Toggle(useEndValue.boolValue, GUILayout.Width(32));
EditorGUI.BeginDisabledGroup(!useEndValue.boolValue);
EditorGUILayout.Slider(endValue, minVal, maxVal, "end");
EditorGUI.EndDisabledGroup();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
useCurveValue.boolValue = EditorGUILayout.Toggle(useCurveValue.boolValue, GUILayout.Width(32));
EditorGUI.BeginDisabledGroup(!useCurveValue.boolValue || !useEndValue.boolValue);
EditorGUILayout.Slider(curveValue, -1.0f, 1.0f, "curve");
EditorGUI.EndDisabledGroup();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
static void GetBezierValue(SerializedProperty bval, out float start, out float end, out float curve)
{
var startValue = bval.FindPropertyRelative("startValue");
var endValue = bval.FindPropertyRelative("endValue");
var curveValue = bval.FindPropertyRelative("curveValue");
var useEndValue = bval.FindPropertyRelative("useEndValue");
var useCurveValue = bval.FindPropertyRelative("useCurveValue");
start = startValue.floatValue;
end = useEndValue.boolValue ? endValue.floatValue : start;
curve = useCurveValue.boolValue && useEndValue.boolValue ? curveValue.floatValue : 0.0f;
}
// ベジェ曲線グラフ描画
static void DrawGraph(float startVal, float endVal, float curveVal, float minVal, float maxVal, string valFmt)
{
EditorGUILayout.Space();
// 表示領域
const float headOffsetX = 40;
const float tailOffsetX = 10;
float w = GUILayoutUtility.GetLastRect().width;
//Rect drect = GUILayoutUtility.GetRect(w, 100f);
Rect drect = GUILayoutUtility.GetRect(w, 120f);
//float indentWidth = EditorGUI.indentLevel * 16;
//drect.x += indentWidth;
//drect.width -= indentWidth;
Rect area = new Rect(drect.x + headOffsetX, drect.y, drect.width - headOffsetX - tailOffsetX, drect.height);
// grid
Handles.color = new Color(1f, 1f, 1f, 0.5f);
Handles.DrawLine(new Vector2(area.xMin, area.yMin), new Vector2(area.xMax, area.yMin));
Handles.DrawLine(new Vector2(area.xMin, area.yMax), new Vector2(area.xMax, area.yMax));
Handles.DrawLine(new Vector2(area.xMin, area.yMin), new Vector2(area.xMin, area.yMax));
Handles.DrawLine(new Vector2(area.xMax, area.yMin), new Vector2(area.xMax, area.yMax));
Handles.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
Handles.DrawLine(new Vector2(area.xMin, (area.yMin + area.yMax) * 0.5f), new Vector2(area.xMax, (area.yMin + area.yMax) * 0.5f));
Handles.DrawLine(new Vector2((area.xMin + area.xMax) * 0.5f, area.yMin), new Vector2((area.xMin + area.xMax) * 0.5f, area.yMax));
// grid数値
Handles.Label(new Vector3(drect.xMin, drect.yMin - 4), maxVal.ToString("F1"));
Handles.Label(new Vector3(drect.xMin, drect.yMax - 12), minVal.ToString("F1"));
// データ領域
Rect vrect = new Rect(0.0f, minVal, 1.0f, maxVal - minVal);
// データ領域での位置
Vector3 svpos = Rect.PointToNormalized(vrect, new Vector2(0.0f, startVal));
Vector3 evpos = Rect.PointToNormalized(vrect, new Vector2(1.0f, endVal));
// 表示のためyを逆転
svpos.y = 1.0f - svpos.y;
evpos.y = 1.0f - evpos.y;
// グラフ上の座標
Vector3 spos = Rect.NormalizedToPoint(area, svpos);
Vector3 epos = Rect.NormalizedToPoint(area, evpos);
// 対角線計算用
Vector3 spos0 = Rect.NormalizedToPoint(area, new Vector2(0.0f, evpos.y));
Vector3 epos0 = Rect.NormalizedToPoint(area, new Vector2(1.0f, svpos.y));
// ベジェ制御点(対角線を補間)
Vector3 stan = Vector3.Lerp(spos0, epos0, curveVal * 0.5f + 0.5f);
Vector3 etan = stan;
// ベジェ描画
Color bcol = GUI.enabled ? Color.green : new Color(0.0f, 0.5f, 0.0f, 1.0f);
Handles.DrawBezier(spos, epos, stan, etan, bcol, null, 2.0f);
// 両端値
Handles.Label(spos, startVal.ToString(valFmt));
Handles.Label(epos + new Vector3(-38, 0, 0), endVal.ToString(valFmt));
#if false
// 制御点描画
Handles.color = Color.red;
Handles.DrawWireCube(stan, Vector3.one * 2);
#endif
EditorGUILayout.Space();
EditorGUILayout.Space();
}
//===============================================================================
///
/// 折りたたみ制御
///
/// 折りたたみ保存キー
///
/// 内容描画アクション
/// 有効フラグアクション(null=無効)
/// 現在の有効フラグ
public static void Foldout(
string foldKey,
string title = null,
System.Action drawAct = null,
System.Action enableAct = null,
bool enable = false,
bool warning = false
)
{
var style = new GUIStyle("ShurikenModuleTitle");
style.font = new GUIStyle(EditorStyles.label).font;
style.border = new RectOffset(15, 7, 4, 4);
style.fixedHeight = 22;
style.contentOffset = new Vector2(20f, -2f);
var rect = GUILayoutUtility.GetRect(16f, 22f, style);
GUI.backgroundColor = warning ? Color.yellow : Color.white;
GUI.Box(rect, title, style);
GUI.backgroundColor = Color.white;
var e = Event.current;
bool foldOut = EditorPrefs.GetBool(foldKey);
if (enableAct == null)
{
if (e.type == EventType.Repaint)
{
var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f);
EditorStyles.foldout.Draw(toggleRect, false, false, foldOut, false);
}
}
else
{
// 有効チェック
var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f);
bool sw = GUI.Toggle(toggleRect, enable, string.Empty, new GUIStyle("ShurikenCheckMark"));
if (sw != enable)
{
enableAct(sw);
}
}
if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
{
foldOut = !foldOut;
EditorPrefs.SetBool(foldKey, foldOut);
e.Use();
}
if (foldOut && drawAct != null)
{
drawAct();
}
}
///
/// タイトルバーのみ表示
///
///
///
public static void TitleBar(string title, bool warning)
{
var style = new GUIStyle("ShurikenModuleTitle");
style.font = new GUIStyle(EditorStyles.label).font;
style.border = new RectOffset(15, 7, 4, 4);
style.fixedHeight = 22;
style.contentOffset = new Vector2(20f, -2f);
var rect = GUILayoutUtility.GetRect(16f, 22f, style);
GUI.backgroundColor = warning ? Color.yellow : Color.white;
GUI.Box(rect, title, style);
GUI.backgroundColor = Color.white;
}
//===============================================================================
static bool MinMaxCurveInspector(string title, string valueName, SerializedProperty bval, float minval, float maxval)
{
EditorGUI.BeginChangeCheck();
float sv, ev, cv;
GetBezierValue(bval, out sv, out ev, out cv);
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", sv, "/", ev, "]");
Foldout(title, StaticStringBuilder.ToString(), () =>
{
if (string.IsNullOrEmpty(valueName) == false)
EditorGUILayout.LabelField(valueName);
BezierInspector(title, bval, minval, maxval);
});
return EditorGUI.EndChangeCheck();
}
static bool UseMinMaxCurveInspector(
string title,
SerializedProperty use,
string valueName,
SerializedProperty bval, float minval, float maxval,
string valFmt = "F2",
bool warning = false
)
{
EditorGUI.BeginChangeCheck();
float sv, ev, cv;
GetBezierValue(bval, out sv, out ev, out cv);
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", sv, "/", ev, "]");
bool wuse = use.boolValue;
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
if (string.IsNullOrEmpty(valueName) == false)
EditorGUILayout.LabelField(valueName);
EditorGUI.BeginDisabledGroup(!wuse);
BezierInspector(title, bval, minval, maxval, valFmt);
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
wuse = sw;
},
wuse,
warning
);
use.boolValue = wuse;
return EditorGUI.EndChangeCheck();
}
public static bool OneSliderInspector(
string title,
string name1, SerializedProperty property1, float min1, float max1
)
{
EditorGUI.BeginChangeCheck();
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", property1.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUILayout.Slider(property1, min1, max1, name1);
}
);
return EditorGUI.EndChangeCheck();
}
public static bool TwoSliderInspector(
string title,
string name1, SerializedProperty property1, float min1, float max1,
string name2, SerializedProperty property2, float min2, float max2
)
{
EditorGUI.BeginChangeCheck();
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", property1.floatValue, "/", property2.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUILayout.Slider(property1, min1, max1, name1);
EditorGUILayout.Slider(property2, min2, max2, name2);
}
);
return EditorGUI.EndChangeCheck();
}
public static bool UseOneSliderInspector(
string title, SerializedProperty use,
string name1, SerializedProperty val1, float min1, float max1
)
{
EditorGUI.BeginChangeCheck();
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", val1.floatValue, "]");
bool workuse = use.boolValue;
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!workuse);
EditorGUILayout.Slider(val1, min1, max1, name1);
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
workuse = sw;
},
workuse
);
use.boolValue = workuse;
return EditorGUI.EndChangeCheck();
}
public static bool UseTwoSliderInspector(
string title, SerializedProperty use,
string name1, SerializedProperty val1, float min1, float max1,
string name2, SerializedProperty val2, float min2, float max2
)
{
EditorGUI.BeginChangeCheck();
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", val1.floatValue, "/", val2.floatValue, "]");
bool workuse = use.boolValue;
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!workuse);
EditorGUILayout.Slider(val1, min1, max1, name1);
EditorGUILayout.Slider(val2, min2, max2, name2);
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
workuse = sw;
},
workuse
);
use.boolValue = workuse;
return EditorGUI.EndChangeCheck();
}
//===============================================================================
public static bool AlgorithmInspector(SerializedProperty cparam, bool changed, System.Action convertAction)
{
EditorGUI.BeginChangeCheck();
//TitleBar("Algorithm", changed);
var algo = cparam.FindPropertyRelative("algorithm");
var algoType = (ClothParams.Algorithm)algo.enumValueIndex;
bool isPlaying = EditorApplication.isPlaying;
const string title = "Algorithm";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", algoType, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(isPlaying);
EditorGUILayout.PropertyField(algo, new GUIContent("Algorithm"));
EditorGUI.EndDisabledGroup();
switch (algoType)
{
case ClothParams.Algorithm.Algorithm_1:
EditorGUILayout.HelpBox("This algorithm is deprecated.\nPlease use the more stable algorithm 2.\nAlgorithm 1 will be removed in the future.", MessageType.Warning);
break;
case ClothParams.Algorithm.Algorithm_2:
EditorGUILayout.HelpBox("Algorithm 2 was introduced from v1.11.0.\nClampRotation / RestoreRotation / TriangleBend will be more stable.\nHowever, the parameters need to be readjusted.", MessageType.Info);
break;
}
// Convert
if (algoType == ClothParams.Algorithm.Algorithm_2)
{
EditorGUI.BeginDisabledGroup(isPlaying);
EditorGUILayout.Space();
using (var horizontalScope = new GUILayout.HorizontalScope())
{
EditorGUILayout.Space();
if (GUILayout.Button("Convert To Latest Algorithm Parameters", GUILayout.Width(300)))
{
if (EditorUtility.DisplayDialog("Parameter conversion", "Converts the parameters of an old algorithm to the latest algorithm.", "Ok", "Cancel"))
{
//Debug.Log("OK!");
convertAction?.Invoke();
}
}
EditorGUILayout.Space();
}
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Parameters of old algorithms can be converted to the latest algorithms.\nNote, however, that the same parameter may work slightly differently depending on the algorithm.", MessageType.Info);
EditorGUILayout.Space();
EditorGUI.EndDisabledGroup();
}
},
warning: changed
);
return EditorGUI.EndChangeCheck();
}
public static bool WorldInfluenceInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var influenceTarget = cparam.FindPropertyRelative("influenceTarget");
var moveInfluence = cparam.FindPropertyRelative("worldMoveInfluence");
var rotInfluence = cparam.FindPropertyRelative("worldRotationInfluence");
var maxSpeed = cparam.FindPropertyRelative("maxMoveSpeed");
var maxRotationSpeed = cparam.FindPropertyRelative("maxRotationSpeed");
var useTeleport = cparam.FindPropertyRelative("useResetTeleport");
var teleportDistance = cparam.FindPropertyRelative("teleportDistance");
var teleportRotation = cparam.FindPropertyRelative("teleportRotation");
var teleportMode = cparam.FindPropertyRelative("teleportMode");
var stabilizationTime = cparam.FindPropertyRelative("resetStabilizationTime");
float ms, me, mc;
GetBezierValue(moveInfluence, out ms, out me, out mc);
float rs, re, rc;
GetBezierValue(rotInfluence, out rs, out re, out rc);
const string title = "World Influence";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", ms, "/", me, "] [", rs, "/", re, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUILayout.PropertyField(influenceTarget);
EditorGUILayout.Slider(maxSpeed, 0.0f, 20.0f, "Max Move Speed");
EditorGUILayout.LabelField("Movement Influence");
BezierInspector("Move Influence", moveInfluence, 0.0f, 1.0f);
EditorGUILayout.Slider(maxRotationSpeed, 0.0f, 720.0f, "Max Rotation Speed");
EditorGUILayout.LabelField("Rotation Influence");
BezierInspector("Rotation Influence", rotInfluence, 0.0f, 1.0f);
useTeleport.boolValue = EditorGUILayout.Toggle("Reset After Teleport", useTeleport.boolValue);
EditorGUI.BeginDisabledGroup(!useTeleport.boolValue);
EditorGUILayout.PropertyField(teleportMode);
EditorGUILayout.Slider(teleportDistance, 0.0f, 1.0f, "Teleport Distance");
EditorGUILayout.Slider(teleportRotation, 0.0f, 180.0f, "Teleport Rotation");
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
//EditorGUILayout.LabelField("Stabilize After Reset");
//EditorGUILayout.Slider(stabilizationTime, 0.0f, 3.0f, "Stabilization Time");
EditorGUILayout.Slider(stabilizationTime, 0.0f, 1.0f, "Stabilization Time After Reset");
},
warning: changed
);
return EditorGUI.EndChangeCheck();
}
public static bool DistanceDisableInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useDistanceDisable");
var referenceObject = cparam.FindPropertyRelative("disableReferenceObject");
var disableDisance = cparam.FindPropertyRelative("disableDistance");
var fadeDistance = cparam.FindPropertyRelative("disableFadeDistance");
const string title = "Distance Disable";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title);
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUILayout.HelpBox("If Reference Object is [None], the main camera is referred.", MessageType.None);
//EditorGUILayout.PropertyField(referenceObject);
referenceObject.objectReferenceValue = EditorGUILayout.ObjectField("Reference Object", referenceObject.objectReferenceValue, typeof(Transform), true);
EditorGUILayout.Slider(disableDisance, 0.0f, 100.0f, "Distance");
EditorGUILayout.Slider(fadeDistance, 0.0f, 10.0f, "Fade Distance");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool ExternalForceInspector(SerializedProperty cparam)
{
EditorGUI.BeginChangeCheck();
//var massInfluence = cparam.FindPropertyRelative("massInfluence");
var depthInfluence = cparam.FindPropertyRelative("depthInfluence");
var windInfluence = cparam.FindPropertyRelative("windInfluence");
var windRandomScale = cparam.FindPropertyRelative("windRandomScale");
var windSynchronization = cparam.FindPropertyRelative("windSynchronization");
const string title = "External Force";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title);
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
//EditorGUILayout.Slider(massInfluence, 0.0f, 1.0f, "Mass Influence");
//EditorGUILayout.LabelField("Wind");
EditorGUILayout.LabelField("Depth Influence");
BezierInspector("Depth Influence", depthInfluence, 0.0f, 1.0f, "F2");
EditorGUILayout.Space();
EditorGUILayout.Slider(windInfluence, 0.0f, 2.0f, "Wind Influence");
EditorGUILayout.Slider(windSynchronization, 0.0f, 1.0f, "Wind Synchronization");
EditorGUILayout.Slider(windRandomScale, 0.0f, 1.0f, "Wind Random Scale");
}
);
return EditorGUI.EndChangeCheck();
}
public static bool RadiusInspector(SerializedProperty cparam)
{
return MinMaxCurveInspector("Radius", "Radius", cparam.FindPropertyRelative("radius"), 0.001f, 0.3f);
}
public static bool MassInspector(SerializedProperty cparam)
{
return MinMaxCurveInspector("Mass", "Mass", cparam.FindPropertyRelative("mass"), 1.0f, 20.0f);
}
public static bool GravityInspector(SerializedProperty cparam)
{
//return UseMinMaxCurveInspector("Gravity", cparam.FindPropertyRelative("useGravity"), "Gravity Acceleration", cparam.FindPropertyRelative("gravity"), -20.0f, 0.0f);
EditorGUI.BeginChangeCheck();
var useGravity = cparam.FindPropertyRelative("useGravity");
var gravity = cparam.FindPropertyRelative("gravity");
var gravityDirection = cparam.FindPropertyRelative("gravityDirection");
//var useDirectional = cparam.FindPropertyRelative("useDirectionalDamping");
//var refObject = cparam.FindPropertyRelative("directionalDampingObject");
//var directionaDamping = cparam.FindPropertyRelative("directionalDamping");
float sv, ev, cv;
GetBezierValue(gravity, out sv, out ev, out cv);
StaticStringBuilder.Clear();
StaticStringBuilder.Append("Gravity", " [", sv, "/", ev, "]");
bool wuse = useGravity.boolValue;
Foldout("Gravity", StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!wuse);
EditorGUILayout.LabelField("Gravity Acceleration");
BezierInspector("Gravity", gravity, -10.0f, 0.0f, "F2");
EditorGUILayout.PropertyField(gravityDirection, true);
//useDirectional.boolValue = EditorGUILayout.Toggle("Directional Damping", useDirectional.boolValue);
//refObject.objectReferenceValue = EditorGUILayout.ObjectField("Reference Object", refObject.objectReferenceValue, typeof(Transform), true);
//EditorGUILayout.LabelField("Angular Damping");
//EditorGUILayout.HelpBox("The horizontal axis is the angle 0-90-180.", MessageType.None);
//BezierInspector("Angular Damping", directionaDamping, 0.0f, 1.0f, "F2");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
wuse = sw;
},
wuse
);
useGravity.boolValue = wuse;
return EditorGUI.EndChangeCheck();
}
public static bool DragInspector(SerializedProperty cparam)
{
return UseMinMaxCurveInspector("Drag", cparam.FindPropertyRelative("useDrag"), "Drag", cparam.FindPropertyRelative("drag"), 0.0f, 0.3f);
}
public static bool MaxVelocityInspector(SerializedProperty cparam)
{
return UseMinMaxCurveInspector("Max Velocity", cparam.FindPropertyRelative("useMaxVelocity"), "Max Velocity", cparam.FindPropertyRelative("maxVelocity"), 0.01f, 10.0f);
}
public static bool TriangleBendInspector(SerializedProperty cparam, bool changed, ClothData clothData)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useTriangleBend");
//var useIncludeFixed = cparam.FindPropertyRelative("useTriangleBendIncludeFixed");
var useTiwstCorrection = cparam.FindPropertyRelative("useTwistCorrection");
var tiwstPower = cparam.FindPropertyRelative("twistRecoveryPower");
var algo = cparam.FindPropertyRelative("algorithm");
var algoType = EditorApplication.isPlaying ? clothData.triangleBendAlgorithm : (ClothParams.Algorithm)algo.enumValueIndex;
string powerStr = string.Empty;
switch (algoType)
{
case ClothParams.Algorithm.Algorithm_1:
powerStr = "triangleBend";
break;
case ClothParams.Algorithm.Algorithm_2:
powerStr = "triangleBend2";
break;
}
var power = cparam.FindPropertyRelative(powerStr);
const string title = "Triangle Bend";
StaticStringBuilder.Clear();
float sv = 0, ev = 0, cv = 0;
GetBezierValue(power, out sv, out ev, out cv);
StaticStringBuilder.Append("Triangle Bend", " [", sv, "/", ev, "]");
StaticStringBuilder.Append(" (", algoType, ")");
bool isPlaying = EditorApplication.isPlaying;
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
//useIncludeFixed.boolValue = EditorGUILayout.Toggle("Include Fixed", useIncludeFixed.boolValue);
EditorGUILayout.LabelField("Bend Power");
BezierInspector("Triangle Bend", power, 0.0f, 1.0f);
EditorGUI.EndDisabledGroup();
// Twist
if (algoType == ClothParams.Algorithm.Algorithm_2)
{
EditorGUI.BeginDisabledGroup(isPlaying);
useTiwstCorrection.boolValue = EditorGUILayout.Toggle("Twist Correction (Experimental)", useTiwstCorrection.boolValue);
EditorGUI.EndDisabledGroup();
EditorGUILayout.Slider(tiwstPower, 0.0f, 1.0f, "Twist Recovery Power");
}
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool DirectionMoveLimitInspector(SerializedProperty cparam)
{
return UseMinMaxCurveInspector("Limit Move To Hits", cparam.FindPropertyRelative("useDirectionMoveLimit"), "Move Limit", cparam.FindPropertyRelative("directionMoveLimit"), -0.2f, 0.2f);
}
public static bool RestoreRotationInspector(SerializedProperty cparam, bool changed, ClothData clothData)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useRestoreRotation");
var algo = cparam.FindPropertyRelative("algorithm");
var algoType = EditorApplication.isPlaying ? clothData.restoreRotationAlgorithm : (ClothParams.Algorithm)algo.enumValueIndex;
string powerStr = string.Empty;
string influenceStr = string.Empty;
switch (algoType)
{
case ClothParams.Algorithm.Algorithm_1:
powerStr = "restoreRotation";
influenceStr = "restoreRotationVelocityInfluence";
break;
case ClothParams.Algorithm.Algorithm_2:
powerStr = "restoreRotation2";
influenceStr = "restoreRotationVelocityInfluence2";
break;
}
var power = cparam.FindPropertyRelative(powerStr);
var influence = cparam.FindPropertyRelative(influenceStr);
const string title = "Restore Rotation";
float sv, ev, cv;
GetBezierValue(power, out sv, out ev, out cv);
StaticStringBuilder.Clear();
StaticStringBuilder.Append("Restore Rotation", " [", sv, "/", ev, "] (", algoType, ")");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUILayout.LabelField("Restore Power");
BezierInspector("Restore Power", power, 0.0f, 1.0f);
EditorGUILayout.Slider(influence, 0.0f, 1.0f, "Velocity Influence");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool ClampRotationInspector(SerializedProperty cparam, bool changed, ClothData clothData)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useClampRotation");
var algo = cparam.FindPropertyRelative("algorithm");
var algoType = EditorApplication.isPlaying ? clothData.clampRotationAlgorithm : (ClothParams.Algorithm)algo.enumValueIndex;
string angleStr = string.Empty;
switch (algoType)
{
case ClothParams.Algorithm.Algorithm_1:
angleStr = "clampRotationAngle";
break;
case ClothParams.Algorithm.Algorithm_2:
angleStr = "clampRotationAngle2";
break;
}
var angle = cparam.FindPropertyRelative(angleStr);
var influence = cparam.FindPropertyRelative("clampRotationVelocityInfluence");
var limit = cparam.FindPropertyRelative("clampRotationVelocityLimit");
const string title = "Clamp Rotation";
float sv, ev, cv;
GetBezierValue(angle, out sv, out ev, out cv);
StaticStringBuilder.Clear();
StaticStringBuilder.Append("Clamp Rotation", " [", sv, "/", ev, "] (", algoType, ")");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUILayout.LabelField("Clamp Angle");
BezierInspector("Angle", angle, 0.0f, 180.0f);
if (algoType == ClothParams.Algorithm.Algorithm_1)
{
EditorGUILayout.Slider(limit, 0.0f, 2.0f, "Velocity Limit");
EditorGUILayout.Slider(influence, 0.0f, 1.0f, "Velocity Influence");
}
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool CollisionInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useCollision");
var dynamicFriction = cparam.FindPropertyRelative("friction");
var staticFriction = cparam.FindPropertyRelative("staticFriction");
const string title = "Collider Collision";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", dynamicFriction.floatValue, ", ", staticFriction.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUILayout.Slider(dynamicFriction, 0.0f, 0.5f, "Dynamic Friction");
EditorGUILayout.Slider(staticFriction, 0.0f, 0.5f, "Static Friction");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool PenetrationInspector(SerializedObject team, SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("usePenetration");
var mode = cparam.FindPropertyRelative("penetrationMode");
var axis = cparam.FindPropertyRelative("penetrationAxis");
var maxDepth = cparam.FindPropertyRelative("penetrationMaxDepth");
var connectDistance = cparam.FindPropertyRelative("penetrationConnectDistance");
//var stiffness = cparam.FindPropertyRelative("penetrationStiffness");
var radius = cparam.FindPropertyRelative("penetrationRadius");
var ignoreCollider = team.FindProperty("teamData.penetrationIgnoreColliderList");
var distance = cparam.FindPropertyRelative("penetrationDistance");
bool isPlaying = EditorApplication.isPlaying;
const string title = "Penetration";
Foldout(title, title,
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUI.BeginDisabledGroup(isPlaying);
EditorGUILayout.PropertyField(mode);
if (mode.enumValueIndex == (int)ClothParams.PenetrationMode.SurfacePenetration)
{
EditorGUILayout.Slider(maxDepth, 0.0f, 1.0f, "Max Connection Depth");
EditorGUILayout.PropertyField(axis);
EditorGUI.EndDisabledGroup();
EditorGUILayout.LabelField("Penetration Distance");
BezierInspector("Penetration Distance", distance, 0.0f, 1.0f);
EditorGUILayout.LabelField("Moving Radius");
BezierInspector("Moving Radius", radius, 0.0f, 5.0f);
}
else if (mode.enumValueIndex == (int)ClothParams.PenetrationMode.ColliderPenetration)
{
EditorGUILayout.Slider(maxDepth, 0.0f, 1.0f, "Max Connection Depth");
EditorGUILayout.LabelField("Connection Distance");
BezierInspector("Connection Distance", connectDistance, 0.0f, 1.0f);
EditorGUI.EndDisabledGroup();
//EditorGUILayout.LabelField("Stiffness");
//BezierInspector("Connection Stiffness", stiffness, 0.0f, 1.0f);
EditorGUILayout.LabelField("Penetration Distance");
BezierInspector("Penetration Distance", distance, 0.0f, 1.0f);
EditorGUILayout.LabelField("Moving Radius");
BezierInspector("Moving Radius", radius, 0.0f, 5.0f);
EditorGUI.BeginDisabledGroup(isPlaying);
//EditorGUILayout.LabelField("Ignore Collider List");
EditorGUILayout.PropertyField(ignoreCollider, true);
EditorGUI.EndDisabledGroup();
}
#if false // 一旦休眠
else if (mode.enumValueIndex == (int)ClothParams.PenetrationMode.BonePenetration)
{
// help
EditorGUI.EndDisabledGroup();
EditorGUILayout.HelpBox("Bone Penetration controls the penetration in the direction of the bones registered in the [Skinning Bone List].\nThe particles must be skinning by[User Animation] or[Generate From Bones].", MessageType.Info);
//EditorGUI.BeginDisabledGroup(isPlaying);
EditorGUILayout.Slider(maxDepth, 0.0f, 1.0f, "Max Connection Depth");
//EditorGUI.EndDisabledGroup();
EditorGUILayout.LabelField("Penetration Distance");
BezierInspector("Penetration Distance", distance, 0.0f, 1.0f);
EditorGUILayout.LabelField("Moving Radius");
BezierInspector("Moving Radius", radius, 0.0f, 5.0f);
}
#endif
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool BaseSkinningInspector(SerializedObject team, SerializedProperty cparam)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useBaseSkinning");
//var boneList = team.FindProperty("teamData.skinningBoneList");
var ignoreCollider = team.FindProperty("teamData.skinningIgnoreColliderList");
const string title = "Skinning";
Foldout(title, title,
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
//EditorGUILayout.PropertyField(boneList, true);
EditorGUILayout.PropertyField(ignoreCollider, true);
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue
);
return EditorGUI.EndChangeCheck();
}
public static bool ClampDistanceInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var use = cparam.FindPropertyRelative("useClampDistanceRatio");
var minRatio = cparam.FindPropertyRelative("clampDistanceMinRatio");
var maxRatio = cparam.FindPropertyRelative("clampDistanceMaxRatio");
var influence = cparam.FindPropertyRelative("clampDistanceVelocityInfluence");
const string title = "Clamp Distance";
StaticStringBuilder.Clear();
StaticStringBuilder.Append("Clamp Distance", " [", minRatio.floatValue, "/", maxRatio.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!use.boolValue);
EditorGUILayout.Slider(minRatio, 0.0f, 1.0f, "Min Distance Ratio");
EditorGUILayout.Slider(maxRatio, 1.0f, 2.0f, "Max Distance Ratio");
EditorGUILayout.Slider(influence, 0.0f, 1.0f, "Velocity Influence");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
use.boolValue = sw;
},
use.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool RestoreDistanceInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var influence = cparam.FindPropertyRelative("restoreDistanceVelocityInfluence");
var structStiffness = cparam.FindPropertyRelative("structDistanceStiffness");
var useBend = cparam.FindPropertyRelative("useBendDistance");
var bendMaxCount = cparam.FindPropertyRelative("bendDistanceMaxCount");
var bendStiffness = cparam.FindPropertyRelative("bendDistanceStiffness");
var useNear = cparam.FindPropertyRelative("useNearDistance");
var nearLength = cparam.FindPropertyRelative("nearDistanceLength");
var nearStiffness = cparam.FindPropertyRelative("nearDistanceStiffness");
var nearMaxCount = cparam.FindPropertyRelative("nearDistanceMaxCount");
var nearMaxDepth = cparam.FindPropertyRelative("nearDistanceMaxDepth");
const string title = "Restore Distance";
Foldout(title, title,
() =>
{
EditorGUILayout.LabelField("Struct Point [Always ON]");
EditorGUILayout.LabelField("Struct Stiffness");
BezierInspector("Struct Stiffness", structStiffness, 0.0f, 1.0f);
useBend.boolValue = EditorGUILayout.Toggle("Bend Point", useBend.boolValue);
EditorGUILayout.IntSlider(bendMaxCount, 1, 6, "Bend Max Connection");
EditorGUILayout.LabelField("Bend Stiffness");
BezierInspector("Bend Stiffness", bendStiffness, 0.0f, 1.0f);
useNear.boolValue = EditorGUILayout.Toggle("Near Point", useNear.boolValue);
EditorGUILayout.IntSlider(nearMaxCount, 1, 6, "Near Max Connection");
EditorGUILayout.Slider(nearMaxDepth, 0.0f, 1.0f, "Near Max Depth");
EditorGUILayout.LabelField("Near Point Length");
BezierInspector("Near Point Length", nearLength, 0.0f, 0.5f);
EditorGUILayout.LabelField("Near Stiffness");
BezierInspector("Near Stiffness", nearStiffness, 0.0f, 1.0f);
EditorGUILayout.Slider(influence, 0.0f, 1.0f, "Velocity Influence");
},
warning: changed
);
return EditorGUI.EndChangeCheck();
}
public static bool FullSpringInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var springPower = cparam.FindPropertyRelative("springPower");
var useSpring = cparam.FindPropertyRelative("useSpring");
var springRadius = cparam.FindPropertyRelative("springRadius");
var springScaleX = cparam.FindPropertyRelative("springScaleX");
var springScaleY = cparam.FindPropertyRelative("springScaleY");
var springScaleZ = cparam.FindPropertyRelative("springScaleZ");
var springDirectionAtten = cparam.FindPropertyRelative("springDirectionAtten");
var springDistanceAtten = cparam.FindPropertyRelative("springDistanceAtten");
var springIntensity = cparam.FindPropertyRelative("springIntensity");
const string title = "Spring";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", springPower.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!useSpring.boolValue);
EditorGUILayout.Slider(springRadius, 0.01f, 0.5f, "Spring Radius");
EditorGUILayout.Slider(springScaleX, 0.01f, 1.0f, "Spring Radius Scale X");
EditorGUILayout.Slider(springScaleY, 0.01f, 1.0f, "Spring Radius Scale Y");
EditorGUILayout.Slider(springScaleZ, 0.01f, 1.0f, "Spring Radius Scale Z");
EditorGUILayout.Slider(springPower, 0.0f, 0.1f, "Spring Power");
EditorGUILayout.LabelField("Spring Direction Atten");
BezierInspector("Spring Direction Atten", springDirectionAtten, 0.0f, 1.0f);
EditorGUILayout.LabelField("Spring Distance Atten");
BezierInspector("Spring Distance Atten", springDistanceAtten, 0.0f, 1.0f);
EditorGUILayout.Slider(springIntensity, 0.1f, 3.0f, "Spring Atten Intensity");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
useSpring.boolValue = sw;
},
useSpring.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool SimpleSpringInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var springPower = cparam.FindPropertyRelative("springPower");
var useSpring = cparam.FindPropertyRelative("useSpring");
const string title = "Spring";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", springPower.floatValue, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!useSpring.boolValue);
EditorGUILayout.Slider(springPower, 0.0f, 0.1f, "Spring Power");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
useSpring.boolValue = sw;
},
useSpring.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool AdjustRotationInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
//var useAdjustRotation = cparam.FindPropertyRelative("useAdjustRotation");
var adjustMode = cparam.FindPropertyRelative("adjustMode");
var adjustRotationPower = cparam.FindPropertyRelative("adjustRotationPower");
var enumName = adjustMode.enumDisplayNames[adjustMode.enumValueIndex];
const string title = "Adjust Rotation";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", enumName, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUILayout.PropertyField(adjustMode);
EditorGUI.BeginDisabledGroup(adjustMode.enumValueIndex == 0);
EditorGUILayout.Slider(adjustRotationPower, -20.0f, 20.0f, "Adjust Rotation Power");
EditorGUI.EndDisabledGroup();
},
//(sw) =>
//{
// useAdjustRotation.boolValue = sw;
//},
//useAdjustRotation.boolValue,
warning: changed
);
return EditorGUI.EndChangeCheck();
}
public static bool ClampPositionInspector(SerializedProperty cparam, bool full, bool changed)
{
EditorGUI.BeginChangeCheck();
var clampPositionLength = cparam.FindPropertyRelative("clampPositionLength");
var useClampPositionLength = cparam.FindPropertyRelative("useClampPositionLength");
var clampPositionRatioX = cparam.FindPropertyRelative("clampPositionRatioX");
var clampPositionRatioY = cparam.FindPropertyRelative("clampPositionRatioY");
var clampPositionRatioZ = cparam.FindPropertyRelative("clampPositionRatioZ");
var influence = cparam.FindPropertyRelative("clampPositionVelocityInfluence");
float sv, ev, cv;
GetBezierValue(clampPositionLength, out sv, out ev, out cv);
const string title = "Clamp Position";
StaticStringBuilder.Clear();
StaticStringBuilder.Append(title, " [", sv, "/", ev, "]");
Foldout(title, StaticStringBuilder.ToString(),
() =>
{
EditorGUI.BeginDisabledGroup(!useClampPositionLength.boolValue);
EditorGUILayout.LabelField("Clamp Position Length");
BezierInspector("Clamp Position Length", clampPositionLength, 0.0f, 1.0f);
if (full)
{
EditorGUILayout.Slider(clampPositionRatioX, 0.0f, 1.0f, "Clamp Position Ratio X");
EditorGUILayout.Slider(clampPositionRatioY, 0.0f, 1.0f, "Clamp Position Ratio Y");
EditorGUILayout.Slider(clampPositionRatioZ, 0.0f, 1.0f, "Clamp Position Ratio Z");
}
EditorGUILayout.Slider(influence, 0.0f, 1.0f, "Velocity Influence");
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
useClampPositionLength.boolValue = sw;
},
useClampPositionLength.boolValue,
changed
);
return EditorGUI.EndChangeCheck();
}
public static bool VolumeInspector(SerializedProperty cparam)
{
EditorGUI.BeginChangeCheck();
var useVolume = cparam.FindPropertyRelative("useVolume");
var maxVolumeLength = cparam.FindPropertyRelative("maxVolumeLength");
var volumeStretchStiffness = cparam.FindPropertyRelative("volumeStretchStiffness");
var volumeShearStiffness = cparam.FindPropertyRelative("volumeShearStiffness");
const string title = "Volume";
Foldout(title, title,
() =>
{
EditorGUI.BeginDisabledGroup(!useVolume.boolValue);
EditorGUILayout.Slider(maxVolumeLength, 0.0f, 0.5f, "Max Volume Length");
EditorGUILayout.LabelField("Stretch Stiffness");
BezierInspector("Stretch Stiffness", volumeStretchStiffness, 0.0f, 1.0f);
EditorGUILayout.LabelField("Shear Stiffness");
BezierInspector("Shear Stiffness", volumeShearStiffness, 0.0f, 1.0f);
EditorGUI.EndDisabledGroup();
},
(sw) =>
{
useVolume.boolValue = sw;
},
useVolume.boolValue
);
return EditorGUI.EndChangeCheck();
}
public static bool RotationInterpolationInspector(SerializedProperty cparam, bool changed)
{
EditorGUI.BeginChangeCheck();
var avarage = cparam.FindPropertyRelative("useLineAvarageRotation");
var fixnonrot = cparam.FindPropertyRelative("useFixedNonRotation");
const string title = "Rotation Interpolation";
Foldout(title, title,
() =>
{
fixnonrot.boolValue = EditorGUILayout.Toggle("Fixed Non-Rotation", fixnonrot.boolValue);
avarage.boolValue = EditorGUILayout.Toggle("Line Avarage Rotation", avarage.boolValue);
},
warning: changed
);
return EditorGUI.EndChangeCheck();
}
//===============================================================================
public static void WindComponentInspector(WindComponent wind, SerializedObject so)
{
var areaWind = wind as MagicaAreaWind;
var windType = wind.GetWindType();
var shapeType = wind.GetShapeType();
var dirType = wind.GetDirectionType();
EditorGUILayout.PropertyField(so.FindProperty("main"));
EditorGUILayout.PropertyField(so.FindProperty("turbulence"));
EditorGUILayout.PropertyField(so.FindProperty("frequency"));
if (windType == PhysicsManagerWindData.WindType.Area)
{
if (areaWind)
{
EditorGUILayout.PropertyField(so.FindProperty("shapeType"));
}
switch (shapeType)
{
case PhysicsManagerWindData.ShapeType.Box:
EditorGUILayout.PropertyField(so.FindProperty("areaSize"));
break;
case PhysicsManagerWindData.ShapeType.Sphere:
EditorGUILayout.PropertyField(so.FindProperty("areaRadius"));
break;
}
//EditorGUILayout.PropertyField(so.FindProperty("anchor"));
}
if (windType == PhysicsManagerWindData.WindType.Area && shapeType == PhysicsManagerWindData.ShapeType.Sphere)
{
EditorGUILayout.PropertyField(so.FindProperty("directionType"));
}
if (windType == PhysicsManagerWindData.WindType.Direction || dirType == PhysicsManagerWindData.DirectionType.OneDirection)
{
EditorGUILayout.PropertyField(so.FindProperty("directionAngleX"));
EditorGUILayout.PropertyField(so.FindProperty("directionAngleY"));
}
if (windType == PhysicsManagerWindData.WindType.Area && shapeType == PhysicsManagerWindData.ShapeType.Sphere && dirType == PhysicsManagerWindData.DirectionType.Radial)
{
EditorGUILayout.LabelField("Attenuation");
BezierInspector("Attenuation", so.FindProperty("attenuation"), 0.0f, 1.0f);
}
if (areaWind)
{
EditorGUILayout.PropertyField(so.FindProperty("isAddition"));
}
}
//===============================================================================
///
/// 水平線を引く
///
public static void DrawHorizoneLine()
{
GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
}
///
/// インスペクタにオブジェクトリストと全選択ボタンを表示する
///
///
///
public static void DrawObjectList(
SerializedProperty dlist, GameObject obj, bool allselect, bool allclear, System.Func func,
string allSelectName = null, string allClearName = null
)
where T : UnityEngine.Object
{
// リスト表示
EditorGUILayout.PropertyField(dlist, true);
// 全選択/削除ボタン
if (allselect || allclear)
{
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (allselect)
{
if (GUILayout.Button(allSelectName ?? "All Select", GUILayout.Width(80), GUILayout.Height(16)))
{
//var newlist = obj.transform.root.GetComponentsInChildren();
var newlist = func();
int cnt = newlist == null ? 0 : newlist.Length;
dlist.arraySize = cnt;
for (int i = 0; i < cnt; i++)
{
dlist.GetArrayElementAtIndex(i).objectReferenceValue = newlist[i];
}
}
}
if (allclear)
{
if (GUILayout.Button(allClearName ?? "Clear", GUILayout.Width(70), GUILayout.Height(16)))
{
dlist.arraySize = 0;
}
}
EditorGUILayout.EndHorizontal();
}
}
//===============================================================================
///
/// クロスモニターを開くボタン
///
public static void MonitorButtonInspector()
{
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUI.backgroundColor = Color.yellow;
if (GUILayout.Button("Open Cloth Monitor", GUILayout.Width(150)))
{
ClothMonitorMenu.InitWindow();
}
GUI.backgroundColor = Color.white;
EditorGUILayout.EndHorizontal();
}
}
}