321 lines
12 KiB
C#
321 lines
12 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEngine.VFX;
|
|
using UnityEditorInternal;
|
|
using System.Collections.Generic;
|
|
|
|
namespace UnityEditor.VFX
|
|
{
|
|
static class VFXEventTesterWindow
|
|
{
|
|
public static bool visible { get { return s_Visible; } set { SetVisibility(value); } }
|
|
|
|
static bool s_Visible;
|
|
|
|
[SerializeField]
|
|
static string m_CustomEvent = "CustomEvent";
|
|
[SerializeField]
|
|
static List<EventAttribute> m_Attributes;
|
|
|
|
static VisualEffect m_Effect;
|
|
static ReorderableList list;
|
|
static readonly string PreferenceName = "VFXEventTester.Visible";
|
|
|
|
static VFXEventTesterWindow()
|
|
{
|
|
m_Attributes = new List<EventAttribute>();
|
|
|
|
s_Visible = EditorPrefs.GetBool(PreferenceName, false);
|
|
|
|
list = new ReorderableList(m_Attributes, typeof(EventAttribute), true, true, true, true);
|
|
list.drawHeaderCallback = drawHeader;
|
|
list.drawElementCallback = drawItem;
|
|
list.onAddDropdownCallback = drawAddDropDown;
|
|
}
|
|
|
|
static void SetVisibility(bool visible)
|
|
{
|
|
if (visible != s_Visible)
|
|
{
|
|
s_Visible = visible;
|
|
EditorPrefs.SetBool(PreferenceName, visible);
|
|
|
|
UpdateVisibility();
|
|
}
|
|
}
|
|
|
|
[InitializeOnLoadMethod]
|
|
static void UpdateVisibility()
|
|
{
|
|
if (s_Visible)
|
|
SceneView.duringSceneGui += DrawWindow;
|
|
else
|
|
SceneView.duringSceneGui -= DrawWindow;
|
|
}
|
|
|
|
private static void drawAddDropDown(Rect buttonRect, ReorderableList list)
|
|
{
|
|
GenericMenu menu = new GenericMenu();
|
|
// Add Generic Attributes
|
|
menu.AddItem(new GUIContent("Standard/Position"), false, AddVector3, "position");
|
|
menu.AddItem(new GUIContent("Standard/Velocity"), false, AddVector3, "velocity");
|
|
menu.AddItem(new GUIContent("Standard/Size"), false, AddFloat, "size");
|
|
menu.AddItem(new GUIContent("Standard/Mass"), false, AddFloat, "mass");
|
|
menu.AddItem(new GUIContent("Standard/Color"), false, AddColor, "color");
|
|
menu.AddItem(new GUIContent("Standard/Alpha"), false, AddFloat, "alpha");
|
|
menu.AddItem(new GUIContent("Standard/Age"), false, AddFloat, "age");
|
|
menu.AddItem(new GUIContent("Standard/Lifetime"), false, AddFloat, "lifetime");
|
|
menu.AddItem(new GUIContent("Standard/Alive"), false, AddBool, "alive");
|
|
menu.AddItem(new GUIContent("Standard/Scale.X"), false, AddFloat, "scaleX");
|
|
menu.AddItem(new GUIContent("Standard/Scale.Y"), false, AddFloat, "scaleY");
|
|
menu.AddItem(new GUIContent("Standard/Scale.Z"), false, AddFloat, "scaleZ");
|
|
menu.AddItem(new GUIContent("Standard/Angle.X"), false, AddFloat, "angleX");
|
|
menu.AddItem(new GUIContent("Standard/Angle.Y"), false, AddFloat, "angleY");
|
|
menu.AddItem(new GUIContent("Standard/Angle.Z"), false, AddFloat, "angleZ");
|
|
// Add Advanced Attributes
|
|
menu.AddItem(new GUIContent("Advanced/OldPosition"), false, AddVector3, "oldPosition");
|
|
menu.AddItem(new GUIContent("Advanced/TargetPosition"), false, AddVector3, "targetPosition");
|
|
menu.AddItem(new GUIContent("Advanced/Direction"), false, AddVector3, "direction");
|
|
menu.AddItem(new GUIContent("Advanced/AngularVelocity.X"), false, AddFloat, "angularVelocityX");
|
|
menu.AddItem(new GUIContent("Advanced/AngularVelocity.Y"), false, AddFloat, "angularVelocityY");
|
|
menu.AddItem(new GUIContent("Advanced/AngularVelocity.Z"), false, AddFloat, "angularVelocityZ");
|
|
// Add Generic Attributes
|
|
menu.AddItem(new GUIContent("Custom/Custom bool"), false, AddBool, "customBool");
|
|
menu.AddItem(new GUIContent("Custom/Custom Float"), false, AddFloat, "customFloat");
|
|
menu.AddItem(new GUIContent("Custom/Custom Vector2"), false, AddVector2, "customVector2");
|
|
menu.AddItem(new GUIContent("Custom/Custom Vector3"), false, AddVector3, "customVector3");
|
|
menu.AddItem(new GUIContent("Custom/Custom Color"), false, AddColor, "customColor");
|
|
|
|
// Add Custom Types
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
static void AddFloat(object name)
|
|
{
|
|
m_Attributes.Add(new EventAttribute(name as string, EventAttributeType.Float, 0.0f));
|
|
}
|
|
|
|
static void AddBool(object name)
|
|
{
|
|
m_Attributes.Add(new EventAttribute(name as string, EventAttributeType.Bool, true));
|
|
}
|
|
|
|
static void AddVector2(object name)
|
|
{
|
|
m_Attributes.Add(new EventAttribute(name as string, EventAttributeType.Vector2, Vector2.zero));
|
|
}
|
|
|
|
static void AddVector3(object name)
|
|
{
|
|
m_Attributes.Add(new EventAttribute(name as string, EventAttributeType.Vector3, Vector3.zero));
|
|
}
|
|
|
|
static void AddColor(object name)
|
|
{
|
|
m_Attributes.Add(new EventAttribute(name as string, EventAttributeType.Color, Color.white));
|
|
}
|
|
|
|
static void DrawWindow(SceneView sceneView)
|
|
{
|
|
if (Selection.activeGameObject != null)
|
|
{
|
|
if (Selection.activeGameObject.TryGetComponent<VisualEffect>(out m_Effect))
|
|
{
|
|
SceneViewOverlay.Window(Contents.title, WindowFunction, 599, SceneViewOverlay.WindowDisplayOption.OneWindowPerTitle);
|
|
}
|
|
else
|
|
{
|
|
m_Effect = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void WindowFunction(UnityEngine.Object target, SceneView sceneView)
|
|
{
|
|
WindowGUI();
|
|
}
|
|
|
|
[System.Serializable]
|
|
enum EventAttributeType
|
|
{
|
|
Float = 0,
|
|
Vector2 = 1,
|
|
Vector3 = 2,
|
|
Color = 3,
|
|
Bool = 4
|
|
}
|
|
|
|
[System.Serializable]
|
|
class EventAttribute
|
|
{
|
|
public string name;
|
|
public EventAttributeType type;
|
|
public object value;
|
|
|
|
public EventAttribute()
|
|
{
|
|
name = "Attribute";
|
|
type = EventAttributeType.Float;
|
|
value = 0.0f;
|
|
}
|
|
|
|
public EventAttribute(string name, EventAttributeType type, object value)
|
|
{
|
|
this.name = name;
|
|
this.type = type;
|
|
this.value = value;
|
|
}
|
|
}
|
|
|
|
private static void drawHeader(Rect rect)
|
|
{
|
|
GUI.Label(rect, "Event Attributes");
|
|
}
|
|
|
|
static void drawItem(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
if (m_Attributes[index] == null)
|
|
{
|
|
var color = GUI.color;
|
|
GUI.color = Color.red;
|
|
EditorGUI.LabelField(rect, "NULL OR DELETED");
|
|
GUI.color = color;
|
|
return;
|
|
}
|
|
|
|
rect.yMin += 2;
|
|
rect.height = 16;
|
|
|
|
var namerect = rect;
|
|
namerect.width = 100;
|
|
|
|
m_Attributes[index].name = GUI.TextField(namerect, m_Attributes[index].name);
|
|
|
|
var typerect = rect;
|
|
typerect.xMin = rect.xMin + 108;
|
|
typerect.width = 76;
|
|
m_Attributes[index].type = (EventAttributeType)EditorGUI.EnumPopup(typerect, m_Attributes[index].type);
|
|
|
|
var valueRect = rect;
|
|
valueRect.xMin = rect.xMin + 192;
|
|
switch (m_Attributes[index].type)
|
|
{
|
|
case EventAttributeType.Bool:
|
|
if (m_Attributes[index].value == null || !(m_Attributes[index].value is bool))
|
|
m_Attributes[index].value = true;
|
|
|
|
m_Attributes[index].value = (bool)EditorGUI.Toggle(valueRect, (bool)m_Attributes[index].value);
|
|
break;
|
|
|
|
case EventAttributeType.Float:
|
|
if (m_Attributes[index].value == null || !(m_Attributes[index].value is float))
|
|
m_Attributes[index].value = 1.0f;
|
|
|
|
m_Attributes[index].value = (float)EditorGUI.FloatField(valueRect, (float)m_Attributes[index].value);
|
|
break;
|
|
|
|
case EventAttributeType.Vector2:
|
|
if (m_Attributes[index].value == null || !(m_Attributes[index].value is Vector2))
|
|
m_Attributes[index].value = Vector2.zero;
|
|
|
|
m_Attributes[index].value = (Vector2)EditorGUI.Vector2Field(valueRect, "", (Vector2)m_Attributes[index].value);
|
|
break;
|
|
|
|
case EventAttributeType.Vector3:
|
|
if (m_Attributes[index].value == null || !(m_Attributes[index].value is Vector3))
|
|
m_Attributes[index].value = Vector3.zero;
|
|
|
|
m_Attributes[index].value = (Vector3)EditorGUI.Vector3Field(valueRect, "", (Vector3)m_Attributes[index].value);
|
|
break;
|
|
|
|
case EventAttributeType.Color:
|
|
if (m_Attributes[index].value == null || !(m_Attributes[index].value is Color))
|
|
m_Attributes[index].value = Color.white;
|
|
|
|
m_Attributes[index].value = (Color)EditorGUI.ColorField(valueRect, (Color)m_Attributes[index].value);
|
|
// The is a hotControl id hash collision with the selection rectangle that cause of a lost of selection on mouseup.
|
|
if (Event.current.type == EventType.MouseUp && valueRect.Contains(Event.current.mousePosition))
|
|
GUIUtility.hotControl = 0;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void WindowGUI()
|
|
{
|
|
EditorGUI.BeginDisabled(m_Effect == null);
|
|
EditorGUILayout.Space();
|
|
list.DoLayoutList();
|
|
EditorGUILayout.Space();
|
|
using (new GUILayout.HorizontalScope(GUILayout.Width(358)))
|
|
{
|
|
if (GUILayout.Button("Play", Styles.leftButton, GUILayout.Height(24)))
|
|
{
|
|
SendEvent("OnPlay");
|
|
}
|
|
if (GUILayout.Button("Stop", Styles.middleButton, GUILayout.Height(24)))
|
|
{
|
|
SendEvent("OnStop");
|
|
}
|
|
if (GUILayout.Button("Custom", Styles.rightButton, GUILayout.Height(24)))
|
|
{
|
|
SendEvent(m_CustomEvent);
|
|
}
|
|
}
|
|
m_CustomEvent = EditorGUILayout.TextField("Custom Event", m_CustomEvent);
|
|
EditorGUI.EndDisabled();
|
|
}
|
|
|
|
static void SendEvent(string name)
|
|
{
|
|
if (m_Effect == null) return;
|
|
var attrib = m_Effect.CreateVFXEventAttribute();
|
|
if (attrib == null) return;
|
|
|
|
// set all attributes
|
|
foreach (var attribute in m_Attributes)
|
|
{
|
|
if (attribute == null) continue;
|
|
switch (attribute.type)
|
|
{
|
|
case EventAttributeType.Bool: attrib.SetBool(attribute.name, (bool)attribute.value); break;
|
|
case EventAttributeType.Float: attrib.SetFloat(attribute.name, (float)attribute.value); break;
|
|
case EventAttributeType.Vector2: attrib.SetVector2(attribute.name, (Vector2)attribute.value); break;
|
|
case EventAttributeType.Vector3: attrib.SetVector3(attribute.name, (Vector3)attribute.value); break;
|
|
case EventAttributeType.Color: attrib.SetVector4(attribute.name, (Color)attribute.value); break;
|
|
}
|
|
}
|
|
|
|
// then send event with attributes
|
|
if (name == "OnPlay")
|
|
m_Effect.Play(attrib);
|
|
else if (name == "OnStop")
|
|
m_Effect.Stop(attrib);
|
|
else
|
|
m_Effect.SendEvent(name, attrib);
|
|
}
|
|
|
|
static class Contents
|
|
{
|
|
public static readonly GUIContent title = new GUIContent("VFX Event Tester");
|
|
}
|
|
|
|
static class Styles
|
|
{
|
|
public static GUIStyle leftButton;
|
|
public static GUIStyle middleButton;
|
|
public static GUIStyle rightButton;
|
|
|
|
static Styles()
|
|
{
|
|
leftButton = new GUIStyle(EditorStyles.miniButtonLeft);
|
|
middleButton = new GUIStyle(EditorStyles.miniButtonMid);
|
|
rightButton = new GUIStyle(EditorStyles.miniButtonRight);
|
|
leftButton.fontSize = 12;
|
|
middleButton.fontSize = 12;
|
|
rightButton.fontSize = 12;
|
|
}
|
|
}
|
|
}
|
|
}
|