intial commit

This commit is contained in:
Caleb Sandford deQuincey
2025-06-27 23:27:49 +01:00
commit ecdd3e2a9e
31269 changed files with 4937644 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
using UnityEngine;
using UnityEditor;
using System.Reflection;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(AxisStatePropertyAttribute))]
internal sealed class AxisStatePropertyDrawer : PropertyDrawer
{
const int vSpace = 2;
bool mExpanded = true;
AxisState def = new AxisState(); // to access name strings
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
float height = EditorGUIUtility.singleLineHeight;
rect.height = height;
mExpanded = EditorGUI.Foldout(rect, mExpanded, EditorGUI.BeginProperty(rect, label, property), true);
if (mExpanded)
{
++EditorGUI.indentLevel;
rect.y += height + vSpace;
EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.Value));
if (!ValueRangeIsLocked(property))
{
rect.y += height + vSpace;
InspectorUtility.MultiPropertyOnLine(rect, new GUIContent("Value Range"),
new [] { property.FindPropertyRelative(() => def.m_MinValue),
property.FindPropertyRelative(() => def.m_MaxValue),
property.FindPropertyRelative(() => def.m_Wrap) },
new [] { GUIContent.none, new GUIContent("to "), null });
}
rect.y += height + vSpace;
InspectorUtility.MultiPropertyOnLine(rect, new GUIContent("Speed"),
new [] { property.FindPropertyRelative(() => def.m_MaxSpeed),
property.FindPropertyRelative(() => def.m_SpeedMode) },
new [] { GUIContent.none, new GUIContent("as") });
rect.y += height + vSpace;
InspectorUtility.MultiPropertyOnLine(
rect, null,
new [] { property.FindPropertyRelative(() => def.m_AccelTime),
property.FindPropertyRelative(() => def.m_DecelTime)},
new [] { GUIContent.none, null });
if (HasRecentering(property))
{
var rDef = new AxisState.Recentering();
var recentering = property.FindPropertyRelative(() => def.m_Recentering);
rect.y += height + vSpace;
InspectorUtility.MultiPropertyOnLine(
rect, new GUIContent(recentering.displayName, recentering.tooltip),
new [] {
recentering.FindPropertyRelative(() => rDef.m_enabled),
recentering.FindPropertyRelative(() => rDef.m_WaitTime),
recentering.FindPropertyRelative(() => rDef.m_RecenteringTime)},
new [] { new GUIContent(""),
new GUIContent("Wait"),
new GUIContent("Time")} );
}
if (!HasInputProvider(property))
{
rect.y += height + vSpace;
EditorGUI.PropertyField(
rect, property.FindPropertyRelative(() => def.m_InputAxisName));
}
rect.y += height + vSpace;
InspectorUtility.MultiPropertyOnLine(rect, null,
new [] { property.FindPropertyRelative(() => def.m_InputAxisValue),
property.FindPropertyRelative(() => def.m_InvertInput) },
new [] { GUIContent.none, new GUIContent("Invert") });
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = EditorGUIUtility.singleLineHeight + vSpace;
if (mExpanded)
{
int lines = 5;
if (!ValueRangeIsLocked(property))
++lines;
if (!HasInputProvider(property))
++lines;
if (HasRecentering(property))
++lines;
height *= lines;
}
return height - vSpace;
}
bool ValueRangeIsLocked(SerializedProperty property)
{
bool value = false;
PropertyInfo pi = typeof(AxisState).GetProperty(
"ValueRangeLocked", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (pi != null)
value = bool.Equals(true, pi.GetValue(SerializedPropertyHelper.GetPropertyValue(property), null));
return value;
}
bool HasRecentering(SerializedProperty property)
{
bool value = false;
PropertyInfo pi = typeof(AxisState).GetProperty(
"HasRecentering", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (pi != null)
value = bool.Equals(true, pi.GetValue(SerializedPropertyHelper.GetPropertyValue(property), null));
return value;
}
bool HasInputProvider(SerializedProperty property)
{
bool value = false;
PropertyInfo pi = typeof(AxisState).GetProperty(
"HasInputProvider", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (pi != null)
value = bool.Equals(true, pi.GetValue(SerializedPropertyHelper.GetPropertyValue(property), null));
return value;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70f1be76e10cd9f44ad1a86b9e05745e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using UnityEngine;
using UnityEditor;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(CinemachineBlendDefinitionPropertyAttribute))]
internal sealed class CinemachineBlendDefinitionPropertyDrawer : PropertyDrawer
{
CinemachineBlendDefinition myClass = new CinemachineBlendDefinition(); // to access name strings
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
float vSpace = 0;
float floatFieldWidth = EditorGUIUtility.singleLineHeight * 2.5f;
SerializedProperty timeProp = property.FindPropertyRelative(() => myClass.m_Time);
GUIContent timeText = new GUIContent(" s", timeProp.tooltip);
var textDimensions = GUI.skin.label.CalcSize(timeText);
rect = EditorGUI.PrefixLabel(rect, EditorGUI.BeginProperty(rect, label, property));
rect.y += vSpace; rect.height = EditorGUIUtility.singleLineHeight;
rect.width -= floatFieldWidth + textDimensions.x;
SerializedProperty styleProp = property.FindPropertyRelative(() => myClass.m_Style);
bool isCustom = styleProp.enumValueIndex == (int)CinemachineBlendDefinition.Style.Custom;
var r = rect;
if (isCustom)
r.width -= 2 * r.height;
EditorGUI.PropertyField(r, styleProp, GUIContent.none);
if (isCustom)
{
SerializedProperty curveProp = property.FindPropertyRelative(() => myClass.m_CustomCurve);
r.x += r.width;
r.width = 2 * rect.height;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(r, curveProp, GUIContent.none);
if (EditorGUI.EndChangeCheck())
{
curveProp.animationCurveValue = InspectorUtility.NormalizeCurve(curveProp.animationCurveValue);
curveProp.serializedObject.ApplyModifiedProperties();
}
}
if (styleProp.intValue != (int)CinemachineBlendDefinition.Style.Cut)
{
float oldWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = textDimensions.x;
rect.x += rect.width; rect.width = floatFieldWidth + EditorGUIUtility.labelWidth;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(rect, timeProp, timeText);
if (EditorGUI.EndChangeCheck())
timeProp.floatValue = Mathf.Max(timeProp.floatValue, 0);
EditorGUIUtility.labelWidth = oldWidth;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a9c464b0191f7d4da1d129d97d8240b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using UnityEngine;
using UnityEditor;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(TagFieldAttribute))]
internal sealed class CinemachineTagFieldPropertyDrawer : PropertyDrawer
{
const float hSpace = 2;
private string tagValue = "";
GUIContent clearText = new GUIContent("Clear", "Set the tag to empty");
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
var textDimensions = GUI.skin.button.CalcSize(clearText);
rect.width -= textDimensions.x + hSpace;
tagValue = property.stringValue;
EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
EditorGUI.BeginChangeCheck();
tagValue = EditorGUI.TagField(rect, EditorGUI.BeginProperty(rect, label, property), tagValue);
if (EditorGUI.EndChangeCheck())
property.stringValue = tagValue;
EditorGUI.showMixedValue = false;
rect.x += rect.width + hSpace; rect.width = textDimensions.x; rect.height -=1;
GUI.enabled = tagValue.Length > 0;
if (GUI.Button(rect, clearText))
property.stringValue = string.Empty;
GUI.enabled = true;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ed3efd28525441947b55ec9b5d68ba31
timeCreated: 1510677929
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,280 @@
using UnityEngine;
using UnityEditor;
using System;
using Cinemachine.Utility;
using System.Linq;
using System.Collections.Generic;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(CinemachineEmbeddedAssetPropertyAttribute))]
internal sealed class EmbeddedAssetPropertyDrawer : PropertyDrawer
{
const float vSpace = 2;
const float kIndentAmount = 15;
const float kBoxMargin = 3;
float HelpBoxHeight { get { return EditorGUIUtility.singleLineHeight * 2.5f; } }
bool mExpanded = false;
bool WarnIfNull
{
get
{
var attr = attribute as CinemachineEmbeddedAssetPropertyAttribute;
return attr == null ? false : attr.WarnIfNull;
}
}
float HeaderHeight { get { return EditorGUIUtility.singleLineHeight * 1.5f; } }
float DrawHeader(Rect rect, string text)
{
float delta = HeaderHeight - EditorGUIUtility.singleLineHeight;
rect.y += delta; rect.height -= delta;
EditorGUI.LabelField(rect, new GUIContent(text), EditorStyles.boldLabel);
return HeaderHeight;
}
string HeaderText(SerializedProperty property)
{
var attrs = property.serializedObject.targetObject.GetType()
.GetCustomAttributes(typeof(HeaderAttribute), false);
if (attrs != null && attrs.Length > 0)
return ((HeaderAttribute)attrs[0]).header;
return null;
}
bool AssetHasCustomEditor(SerializedProperty property)
{
ScriptableObject asset = property.objectReferenceValue as ScriptableObject;
if (asset != null)
return ActiveEditorTracker.HasCustomEditor(asset);
return false;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
bool hasCustomEditor = AssetHasCustomEditor(property);
float height = base.GetPropertyHeight(property, label);
height += + 2 * (kBoxMargin + vSpace);
if (mExpanded && !hasCustomEditor)
{
height += HelpBoxHeight + kBoxMargin;
ScriptableObject asset = property.objectReferenceValue as ScriptableObject;
if (asset != null)
{
SerializedObject so = new SerializedObject(asset);
var prop = so.GetIterator();
prop.NextVisible(true);
do
{
if (prop.name == "m_Script")
continue;
string header = HeaderText(prop);
if (header != null)
height += HeaderHeight + vSpace;
height += EditorGUI.GetPropertyHeight(prop, false) + vSpace;
}
while (prop.NextVisible(prop.isExpanded));
height += kBoxMargin;
}
}
return height;
}
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
bool hasCustomEditor = AssetHasCustomEditor(property);
rect.y += vSpace; rect.height -= 2 * vSpace;
GUI.Box(rect, GUIContent.none, GUI.skin.box);
rect.y += kBoxMargin;
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUIUtility.labelWidth -= kBoxMargin;
AssetFieldWithCreateButton(
new Rect(rect.x + kBoxMargin, rect.y, rect.width - 2 * kBoxMargin, rect.height),
property, WarnIfNull,
property.serializedObject.targetObject.name + " " + label.text);
ScriptableObject asset = property.objectReferenceValue as ScriptableObject;
if (asset != null && !hasCustomEditor)
{
mExpanded = EditorGUI.Foldout(rect, mExpanded, GUIContent.none, true);
if (mExpanded)
{
rect.y += rect.height + kBoxMargin + vSpace;
rect.x += kIndentAmount + kBoxMargin;
rect.width -= kIndentAmount + 2 * kBoxMargin;
EditorGUIUtility.labelWidth -= kIndentAmount;
EditorGUI.HelpBox(
new Rect(rect.x, rect.y, rect.width, HelpBoxHeight),
"This is a shared asset.\n"
+ "Changes made here will apply to all users of this asset",
MessageType.Info);
rect.y += HelpBoxHeight + kBoxMargin;
SerializedObject so = new SerializedObject(property.objectReferenceValue);
var prop = so.GetIterator();
prop.NextVisible(true);
var indent = EditorGUI.indentLevel;
do
{
if (prop.name == "m_Script")
continue;
string header = HeaderText(prop);
if (header != null)
{
DrawHeader(rect, header);
rect.y += HeaderHeight + vSpace;
rect.height -= HeaderHeight + vSpace;
}
rect.height = EditorGUI.GetPropertyHeight(prop, false);
EditorGUI.indentLevel = indent + prop.depth;
EditorGUI.PropertyField(rect, prop);
rect.y += rect.height + vSpace;
} while (prop.NextVisible(prop.isExpanded));
if (GUI.changed)
so.ApplyModifiedProperties();
}
EditorGUIUtility.labelWidth += kIndentAmount;
}
EditorGUIUtility.labelWidth += kBoxMargin;
}
Type EmbeddedAssetType(SerializedProperty property)
{
Type type = property.serializedObject.targetObject.GetType();
var a = property.propertyPath.Split('.');
for (int i = 0; i < a.Length; ++i)
{
var field = type.GetField(a[i],
System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance);
if (field == null) continue;
type = field.FieldType;
}
return type;
}
Type[] mAssetTypes = null;
List<ScriptableObject> mAssetPresets;
GUIContent[] mAssetPresetNames;
void RebuildPresetList()
{
if (mAssetPresets != null && mAssetPresetNames != null)
return;
mAssetPresets = new List<ScriptableObject>();
if (mAssetTypes != null)
{
for (int i = 0; i < mAssetTypes.Length; ++i)
InspectorUtility.AddAssetsFromPackageSubDirectory(
mAssetTypes[i], mAssetPresets, "Presets/Noise");
}
List<GUIContent> presetNameList = new List<GUIContent>();
foreach (var n in mAssetPresets)
presetNameList.Add(new GUIContent("Presets/" + n.name));
mAssetPresetNames = presetNameList.ToArray();
}
void AssetFieldWithCreateButton(
Rect r, SerializedProperty property, bool warnIfNull, string defaultName)
{
// Collect all the eligible asset types
Type type = EmbeddedAssetType(property);
if (mAssetTypes == null)
mAssetTypes = ReflectionHelpers.GetTypesInAllDependentAssemblies(
(Type t) => type.IsAssignableFrom(t) && !t.IsAbstract).ToArray();
float iconSize = r.height + 4;
r.width -= iconSize;
GUIContent label = new GUIContent(property.displayName, property.tooltip);
if (warnIfNull && property.objectReferenceValue == null)
label.image = EditorGUIUtility.IconContent("console.warnicon.sml").image;
EditorGUI.PropertyField(r, property, label);
r.x += r.width; r.width = iconSize; r.height = iconSize;
if (GUI.Button(r, EditorGUIUtility.IconContent("_Popup"), GUI.skin.label))
{
GenericMenu menu = new GenericMenu();
if (property.objectReferenceValue != null)
{
menu.AddItem(new GUIContent("Edit"), false, ()
=> Selection.activeObject = property.objectReferenceValue);
menu.AddItem(new GUIContent("Clone"), false, () =>
{
ScriptableObject copyFrom = property.objectReferenceValue as ScriptableObject;
if (copyFrom != null)
{
string title = "Create New " + copyFrom.GetType().Name + " asset";
ScriptableObject asset = CreateAsset(
copyFrom.GetType(), copyFrom, defaultName, title);
if (asset != null)
{
property.objectReferenceValue = asset;
property.serializedObject.ApplyModifiedProperties();
}
}
});
menu.AddItem(new GUIContent("Locate"), false, ()
=> EditorGUIUtility.PingObject(property.objectReferenceValue));
}
RebuildPresetList();
int i = 0;
foreach (var a in mAssetPresets)
{
menu.AddItem(mAssetPresetNames[i++], false, () =>
{
property.objectReferenceValue = a;
property.serializedObject.ApplyModifiedProperties();
});
}
foreach (var t in mAssetTypes)
{
menu.AddItem(new GUIContent("New " + InspectorUtility.NicifyClassName(t.Name)), false, () =>
{
string title = "Create New " + t.Name + " asset";
ScriptableObject asset = CreateAsset(t, null, defaultName, title);
if (asset != null)
{
property.objectReferenceValue = asset;
property.serializedObject.ApplyModifiedProperties();
}
});
}
menu.ShowAsContext();
}
}
ScriptableObject CreateAsset(
Type assetType, ScriptableObject copyFrom, string defaultName, string dialogTitle)
{
ScriptableObject asset = null;
string path = EditorUtility.SaveFilePanelInProject(
dialogTitle, defaultName, "asset", string.Empty);
if (!string.IsNullOrEmpty(path))
{
if (copyFrom != null)
{
string fromPath = AssetDatabase.GetAssetPath(copyFrom);
if (AssetDatabase.CopyAsset(fromPath, path))
asset = AssetDatabase.LoadAssetAtPath(path, assetType) as ScriptableObject;
}
else
{
asset = ScriptableObjectUtility.CreateAt(assetType, path);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
return asset;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 57baee20e53f7b54782519af44a9468f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(NoiseSettingsPropertyAttribute))]
internal sealed class NoiseSettingsPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
RebuildProfileList();
float iconSize = rect.height + 4;
rect.width -= iconSize;
int preset = sNoisePresets.IndexOf((NoiseSettings)property.objectReferenceValue);
EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
preset = EditorGUI.Popup(rect, EditorGUI.BeginProperty(rect, label, property), preset, sNoisePresetNames);
EditorGUI.showMixedValue = false;
string labelText = label.text;
NoiseSettings newProfile = preset < 0 ? null : sNoisePresets[preset] as NoiseSettings;
if ((NoiseSettings)property.objectReferenceValue != newProfile)
{
property.objectReferenceValue = newProfile;
property.serializedObject.ApplyModifiedProperties();
}
rect.x += rect.width; rect.width = iconSize; rect.height = iconSize; rect.y -= 2;
if (GUI.Button(rect, EditorGUIUtility.IconContent("_Popup"), GUI.skin.label))
{
GenericMenu menu = new GenericMenu();
if (property.objectReferenceValue != null)
{
menu.AddItem(new GUIContent("Edit"), false, ()
=> Selection.activeObject = property.objectReferenceValue);
menu.AddItem(new GUIContent("Clone"), false, () =>
{
NoiseSettings pp = CreateProfile(
property, labelText,
(NoiseSettings)property.objectReferenceValue);
if (pp != null)
{
property.objectReferenceValue = pp;
property.serializedObject.ApplyModifiedProperties();
InvalidateProfileList();
}
});
menu.AddItem(new GUIContent("Locate"), false, ()
=> EditorGUIUtility.PingObject(property.objectReferenceValue));
}
menu.AddItem(new GUIContent("New"), false, () =>
{
//Undo.RecordObject(Target, "Change Noise Profile");
NoiseSettings pp = CreateProfile(property, labelText, null);
if (pp != null)
{
property.objectReferenceValue = pp;
property.serializedObject.ApplyModifiedProperties();
InvalidateProfileList();
}
});
menu.ShowAsContext();
}
}
static List<ScriptableObject> sNoisePresets;
static GUIContent[] sNoisePresetNames;
static float sLastPresetRebuildTime = 0;
public static void InvalidateProfileList()
{
sNoisePresets = null;
sNoisePresetNames = null;
}
static void RebuildProfileList()
{
if (sLastPresetRebuildTime < Time.realtimeSinceStartup - 5)
InvalidateProfileList();
if (sNoisePresets != null && sNoisePresetNames != null)
return;
sNoisePresets = FindAssetsByType<NoiseSettings>();
InspectorUtility.AddAssetsFromPackageSubDirectory(
typeof(NoiseSettings), sNoisePresets, "Presets/Noise");
sNoisePresets.Insert(0, null);
List<GUIContent> presetNameList = new List<GUIContent>();
foreach (var n in sNoisePresets)
presetNameList.Add(new GUIContent((n == null) ? "(none)" : n.name));
sNoisePresetNames = presetNameList.ToArray();
sLastPresetRebuildTime = Time.realtimeSinceStartup;
}
static List<ScriptableObject> FindAssetsByType<T>() where T : UnityEngine.Object
{
List<ScriptableObject> assets = new List<ScriptableObject>();
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T)));
for (int i = 0; i < guids.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
ScriptableObject asset = AssetDatabase.LoadAssetAtPath<T>(assetPath) as ScriptableObject;
if (asset != null)
assets.Add(asset);
}
return assets;
}
NoiseSettings CreateProfile(SerializedProperty property, string label, NoiseSettings copyFrom)
{
string path = InspectorUtility.GetVirtualCameraObjectName(property) + " " + label;
path = EditorUtility.SaveFilePanelInProject(
"Create Noise Profile asset", path, "asset",
"This asset will generate a procedural noise signal");
if (!string.IsNullOrEmpty(path))
{
NoiseSettings profile = null;
if (copyFrom != null)
{
string fromPath = AssetDatabase.GetAssetPath(copyFrom);
if (AssetDatabase.CopyAsset(fromPath, path))
{
profile = AssetDatabase.LoadAssetAtPath(
path, typeof(NoiseSettings)) as NoiseSettings;
}
}
else
{
profile = ScriptableObjectUtility.CreateAt(
typeof(NoiseSettings), path) as NoiseSettings;
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return profile;
}
return null;
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 7d0d800d47186f0468d962ccf338ab97
timeCreated: 1518034045
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using UnityEngine;
using UnityEditor;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(OrbitalTransposerHeadingPropertyAttribute))]
internal sealed class OrbitalTransposerHeadingPropertyDrawer : PropertyDrawer
{
const int vSpace = 2;
bool mExpanded = true;
CinemachineOrbitalTransposer.Heading def = new CinemachineOrbitalTransposer.Heading(); // to access name strings
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
float height = EditorGUIUtility.singleLineHeight;
rect.height = height;
mExpanded = EditorGUI.Foldout(rect, mExpanded, EditorGUI.BeginProperty(rect, label, property), true);
if (mExpanded)
{
++EditorGUI.indentLevel;
rect.y += height + vSpace;
EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.m_Definition));
if (IsVelocityMode(property))
{
rect.y += height + vSpace;
EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.m_VelocityFilterStrength));
}
rect.y += height + vSpace;
EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.m_Bias));
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = EditorGUIUtility.singleLineHeight + vSpace;
if (mExpanded)
height *= IsVelocityMode(property) ? 4 : 3;
return height;
}
bool IsVelocityMode(SerializedProperty property)
{
var mode = property.FindPropertyRelative(() => def.m_Definition);
var value = (CinemachineOrbitalTransposer.Heading.HeadingDefinition)
(System.Enum.GetValues(typeof(CinemachineOrbitalTransposer.Heading.HeadingDefinition))).GetValue(mode.enumValueIndex);
return value == CinemachineOrbitalTransposer.Heading.HeadingDefinition.Velocity
|| value == CinemachineOrbitalTransposer.Heading.HeadingDefinition.PositionDelta;
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: cd1b3b6848c215f4cba3ace2c38f9bce
timeCreated: 1514911474
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace Cinemachine.Editor
{
[CustomPropertyDrawer(typeof(VcamTargetPropertyAttribute))]
internal sealed class VcamTargetPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
const float hSpace = 2;
float iconSize = rect.height + 4;
rect.width -= iconSize + hSpace;
EditorGUI.PropertyField(rect, property, EditorGUI.BeginProperty(rect, label, property));
rect.x += rect.width + hSpace; rect.width = iconSize;
var oldEnabled = GUI.enabled;
var target = property.objectReferenceValue as Transform;
if (target == null || target.GetComponent<CinemachineTargetGroup>() != null)
GUI.enabled = false;
if (GUI.Button(rect, EditorGUIUtility.IconContent("_Popup"), GUI.skin.label))
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Convert to TargetGroup"), false, () =>
{
GameObject go = ObjectFactory.CreateGameObject("Target Group", typeof(CinemachineTargetGroup));
var group = go.GetComponent<CinemachineTargetGroup>();
group.m_RotationMode = CinemachineTargetGroup.RotationMode.GroupAverage;
group.AddMember(target, 1, 1);
property.objectReferenceValue = group.Transform;
property.serializedObject.ApplyModifiedProperties();
});
menu.ShowAsContext();
}
GUI.enabled = oldEnabled;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b0a256055e11cf4999a9ee9e8b0db2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: