Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

211 行
9.6 KiB

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
namespace Cinemachine.Editor
{
[CustomEditor(typeof(CinemachineClearShot))]
internal sealed class CinemachineClearShotEditor
: CinemachineVirtualCameraBaseEditor<CinemachineClearShot>
{
EmbeddeAssetEditor<CinemachineBlenderSettings> m_BlendsEditor;
ColliderState m_ColliderState;
private UnityEditorInternal.ReorderableList mChildList;
protected override void OnEnable()
{
base.OnEnable();
m_BlendsEditor = new EmbeddeAssetEditor<CinemachineBlenderSettings>(
FieldPath(x => x.m_CustomBlends), this);
m_BlendsEditor.OnChanged = (CinemachineBlenderSettings b) =>
{
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
};
m_BlendsEditor.OnCreateEditor = (UnityEditor.Editor ed) =>
{
CinemachineBlenderSettingsEditor editor = ed as CinemachineBlenderSettingsEditor;
if (editor != null)
editor.GetAllVirtualCameras = () => { return Target.ChildCameras; };
};
mChildList = null;
}
protected override void OnDisable()
{
base.OnDisable();
if (m_BlendsEditor != null)
m_BlendsEditor.OnDisable();
}
public override void OnInspectorGUI()
{
BeginInspector();
if (mChildList == null)
SetupChildList();
m_ColliderState = GetColliderState();
switch (m_ColliderState)
{
case ColliderState.ColliderOnParent:
case ColliderState.ColliderOnAllChildren:
break;
case ColliderState.NoCollider:
EditorGUILayout.HelpBox(
"ClearShot requires a Collider extension to rank the shots. Either add one to the ClearShot itself, or to each of the child cameras.",
MessageType.Warning);
break;
case ColliderState.ColliderOnSomeChildren:
EditorGUILayout.HelpBox(
"Some child cameras do not have a Collider extension. ClearShot requires a Collider on all the child cameras, or alternatively on the ClearShot iself.",
MessageType.Warning);
break;
case ColliderState.ColliderOnChildrenAndParent:
EditorGUILayout.HelpBox(
"There is a Collider extention on the ClearShot camera, and also on some of its child cameras. You can't have both.",
MessageType.Error);
break;
}
DrawHeaderInInspector();
DrawPropertyInInspector(FindProperty(x => x.m_Priority));
DrawTargetsInInspector(FindProperty(x => x.m_Follow), FindProperty(x => x.m_LookAt));
DrawRemainingPropertiesInInspector();
// Blends
m_BlendsEditor.DrawEditorCombo(
"Create New Blender Asset",
Target.gameObject.name + " Blends", "asset", string.Empty,
"Custom Blends", false);
// vcam children
EditorGUILayout.Separator();
EditorGUI.BeginChangeCheck();
mChildList.DoLayoutList();
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
// Extensions
DrawExtensionsWidgetInInspector();
}
enum ColliderState
{
NoCollider,
ColliderOnAllChildren,
ColliderOnSomeChildren,
ColliderOnParent,
ColliderOnChildrenAndParent
}
ColliderState GetColliderState()
{
int numChildren = 0;
int numColliderChildren = 0;
bool colliderOnParent = ObjectHasCollider(Target);
var children = Target.m_ChildCameras;
numChildren = children == null ? 0 : children.Length;
for (int i = 0; i < numChildren; ++i)
if (ObjectHasCollider(children[i]))
++numColliderChildren;
if (colliderOnParent)
return (numColliderChildren > 0)
? ColliderState.ColliderOnChildrenAndParent : ColliderState.ColliderOnParent;
if (numColliderChildren > 0)
return (numColliderChildren == numChildren)
? ColliderState.ColliderOnAllChildren : ColliderState.ColliderOnSomeChildren;
return ColliderState.NoCollider;
}
bool ObjectHasCollider(object obj)
{
CinemachineVirtualCameraBase vcam = obj as CinemachineVirtualCameraBase;
var collider = (vcam == null) ? null : vcam.GetComponent<CinemachineCollider>();
return (collider != null && collider.enabled);
}
void SetupChildList()
{
float vSpace = 2;
float hSpace = 3;
float floatFieldWidth = EditorGUIUtility.singleLineHeight * 2.5f;
mChildList = new UnityEditorInternal.ReorderableList(
serializedObject, FindProperty(x => x.m_ChildCameras), true, true, true, true);
mChildList.drawHeaderCallback = (Rect rect) =>
{
EditorGUI.LabelField(rect, "Virtual Camera Children");
GUIContent priorityText = new GUIContent("Priority");
var textDimensions = GUI.skin.label.CalcSize(priorityText);
rect.x += rect.width - textDimensions.x;
rect.width = textDimensions.x;
EditorGUI.LabelField(rect, priorityText);
};
mChildList.drawElementCallback
= (Rect rect, int index, bool isActive, bool isFocused) =>
{
rect.y += vSpace;
rect.width -= floatFieldWidth + hSpace;
rect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty element = mChildList.serializedProperty.GetArrayElementAtIndex(index);
if (m_ColliderState == ColliderState.ColliderOnSomeChildren
|| m_ColliderState == ColliderState.ColliderOnChildrenAndParent)
{
bool hasCollider = ObjectHasCollider(element.objectReferenceValue);
if ((m_ColliderState == ColliderState.ColliderOnSomeChildren && !hasCollider)
|| (m_ColliderState == ColliderState.ColliderOnChildrenAndParent && hasCollider))
{
float width = rect.width;
rect.width = rect.height;
GUIContent label = new GUIContent("");
label.image = EditorGUIUtility.IconContent("console.warnicon.sml").image;
EditorGUI.LabelField(rect, label);
width -= rect.width; rect.x += rect.width; rect.width = width;
}
}
EditorGUI.PropertyField(rect, element, GUIContent.none);
SerializedObject obj = new SerializedObject(element.objectReferenceValue);
rect.x += rect.width + hSpace; rect.width = floatFieldWidth;
SerializedProperty priorityProp = obj.FindProperty(() => Target.m_Priority);
float oldWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = hSpace * 2;
EditorGUI.PropertyField(rect, priorityProp, new GUIContent(" "));
EditorGUIUtility.labelWidth = oldWidth;
obj.ApplyModifiedProperties();
};
mChildList.onChangedCallback = (UnityEditorInternal.ReorderableList l) =>
{
if (l.index < 0 || l.index >= l.serializedProperty.arraySize)
return;
Object o = l.serializedProperty.GetArrayElementAtIndex(
l.index).objectReferenceValue;
CinemachineVirtualCameraBase vcam = (o != null)
? (o as CinemachineVirtualCameraBase) : null;
if (vcam != null)
vcam.transform.SetSiblingIndex(l.index);
};
mChildList.onAddCallback = (UnityEditorInternal.ReorderableList l) =>
{
var index = l.serializedProperty.arraySize;
var vcam = CinemachineMenu.CreateDefaultVirtualCamera();
Undo.SetTransformParent(vcam.transform, Target.transform, "");
var collider = Undo.AddComponent<CinemachineCollider>(vcam.gameObject);
collider.m_AvoidObstacles = false;
Undo.RecordObject(collider, "create ClearShot child");
vcam.transform.SetSiblingIndex(index);
};
mChildList.onRemoveCallback = (UnityEditorInternal.ReorderableList l) =>
{
Object o = l.serializedProperty.GetArrayElementAtIndex(
l.index).objectReferenceValue;
CinemachineVirtualCameraBase vcam = (o != null)
? (o as CinemachineVirtualCameraBase) : null;
if (vcam != null)
Undo.DestroyObjectImmediate(vcam.gameObject);
};
}
}
}