2020-02-17 11:22:12 +08:00
using UnityEditor ;
2018-06-22 18:48:14 +08:00
using UnityEditor.UI ;
using UnityEngine ;
2018-11-28 18:55:56 +08:00
using System.Collections.Generic ;
using System.Linq ;
2018-06-22 18:48:14 +08:00
namespace Coffee.UIExtensions
{
2020-02-12 20:38:06 +08:00
[CustomEditor(typeof(UIParticle))]
[CanEditMultipleObjects]
2020-08-20 03:42:16 +08:00
internal class UIParticleEditor : GraphicEditor
2020-02-12 20:38:06 +08:00
{
//################################
// Constant or Static Members.
//################################
2020-08-20 03:42:16 +08:00
private static readonly GUIContent s_ContentParticleMaterial = new GUIContent ( "Particle Material" , "The material for rendering particles" ) ;
private static readonly GUIContent s_ContentTrailMaterial = new GUIContent ( "Trail Material" , "The material for rendering particle trails" ) ;
private static readonly GUIContent s_ContentAdvancedOptions = new GUIContent ( "Advanced Options" ) ;
private static readonly GUIContent s_Content3D = new GUIContent ( "3D" ) ;
private static readonly GUIContent s_ContentScale = new GUIContent ( "Scale" ) ;
private static readonly List < ParticleSystem > s_ParticleSystems = new List < ParticleSystem > ( ) ;
private SerializedProperty _spParticleSystem ;
private SerializedProperty _spScale3D ;
private SerializedProperty _spIgnoreCanvasScaler ;
private SerializedProperty _spAnimatableProperties ;
private bool _xyzMode ;
private static readonly List < string > s_MaskablePropertyNames = new List < string >
2020-02-12 20:38:06 +08:00
{
"_Stencil" ,
"_StencilComp" ,
"_StencilOp" ,
"_StencilWriteMask" ,
"_StencilReadMask" ,
"_ColorMask" ,
} ;
2020-08-20 03:42:16 +08:00
2020-02-12 20:38:06 +08:00
//################################
// Public/Protected Members.
//################################
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable ( )
{
base . OnEnable ( ) ;
_spParticleSystem = serializedObject . FindProperty ( "m_ParticleSystem" ) ;
2020-08-20 03:42:16 +08:00
_spScale3D = serializedObject . FindProperty ( "m_Scale3D" ) ;
_spIgnoreCanvasScaler = serializedObject . FindProperty ( "m_IgnoreCanvasScaler" ) ;
2020-02-12 20:38:06 +08:00
_spAnimatableProperties = serializedObject . FindProperty ( "m_AnimatableProperties" ) ;
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI ( )
{
2020-08-20 03:42:16 +08:00
var current = target as UIParticle ;
if ( current = = null ) return ;
2020-02-12 20:38:06 +08:00
serializedObject . Update ( ) ;
2020-08-11 23:19:14 +08:00
EditorGUI . BeginDisabledGroup ( true ) ;
2020-02-12 20:38:06 +08:00
EditorGUILayout . PropertyField ( _spParticleSystem ) ;
2020-08-11 23:19:14 +08:00
EditorGUI . EndDisabledGroup ( ) ;
2020-08-20 03:42:16 +08:00
// Draw materials.
2020-02-12 20:38:06 +08:00
EditorGUI . indentLevel + + ;
var ps = _spParticleSystem . objectReferenceValue as ParticleSystem ;
2020-08-20 03:42:16 +08:00
if ( ps ! = null )
2020-02-12 20:38:06 +08:00
{
var pr = ps . GetComponent < ParticleSystemRenderer > ( ) ;
var sp = new SerializedObject ( pr ) . FindProperty ( "m_Materials" ) ;
2020-08-11 23:19:14 +08:00
EditorGUI . BeginChangeCheck ( ) ;
{
EditorGUILayout . PropertyField ( sp . GetArrayElementAtIndex ( 0 ) , s_ContentParticleMaterial ) ;
if ( 2 < = sp . arraySize )
{
EditorGUILayout . PropertyField ( sp . GetArrayElementAtIndex ( 1 ) , s_ContentTrailMaterial ) ;
}
}
if ( EditorGUI . EndChangeCheck ( ) )
2020-08-11 23:09:55 +08:00
{
2020-08-11 23:19:14 +08:00
sp . serializedObject . ApplyModifiedProperties ( ) ;
2020-08-11 23:09:55 +08:00
}
2020-02-12 20:38:06 +08:00
if ( ! Application . isPlaying & & pr . enabled )
{
EditorGUILayout . HelpBox ( "UIParticles disable the RendererModule in ParticleSystem at runtime to prevent double rendering." , MessageType . Warning ) ;
}
}
2020-08-12 22:19:08 +08:00
2020-02-12 20:38:06 +08:00
EditorGUI . indentLevel - - ;
2020-08-20 03:42:16 +08:00
// Advanced Options
EditorGUILayout . Space ( ) ;
EditorGUILayout . LabelField ( s_ContentAdvancedOptions , EditorStyles . boldLabel ) ;
2020-02-12 20:38:06 +08:00
2020-08-20 03:42:16 +08:00
_xyzMode = DrawFloatOrVector3Field ( _spScale3D , _xyzMode ) ;
2020-02-12 20:38:06 +08:00
2020-08-20 03:42:16 +08:00
EditorGUILayout . PropertyField ( _spIgnoreCanvasScaler ) ;
2020-02-12 20:38:06 +08:00
// AnimatableProperties
AnimatedPropertiesEditor . DrawAnimatableProperties ( _spAnimatableProperties , current . material ) ;
2020-08-20 03:42:16 +08:00
// Fix
current . GetComponentsInChildren ( true , s_ParticleSystems ) ;
2020-02-12 20:38:06 +08:00
if ( s_ParticleSystems . Any ( x = > x . GetComponent < UIParticle > ( ) = = null ) )
{
GUILayout . BeginHorizontal ( ) ;
EditorGUILayout . HelpBox ( "There are child ParticleSystems that does not have a UIParticle component.\nAdd UIParticle component to them." , MessageType . Warning ) ;
GUILayout . BeginVertical ( ) ;
if ( GUILayout . Button ( "Fix" ) )
{
foreach ( var p in s_ParticleSystems . Where ( x = > ! x . GetComponent < UIParticle > ( ) ) )
{
p . gameObject . AddComponent < UIParticle > ( ) ;
}
}
2020-08-12 22:19:08 +08:00
2020-02-12 20:38:06 +08:00
GUILayout . EndVertical ( ) ;
GUILayout . EndHorizontal ( ) ;
}
2020-08-12 22:19:08 +08:00
2020-02-12 20:38:06 +08:00
s_ParticleSystems . Clear ( ) ;
2020-08-20 03:42:16 +08:00
// Does the shader support UI masks?
2020-02-12 20:38:06 +08:00
if ( current . maskable & & current . material & & current . material . shader )
{
var mat = current . material ;
var shader = mat . shader ;
foreach ( var propName in s_MaskablePropertyNames )
{
2020-08-20 03:42:16 +08:00
if ( mat . HasProperty ( propName ) ) continue ;
EditorGUILayout . HelpBox ( string . Format ( "Shader '{0}' doesn't have '{1}' property. This graphic cannot be masked." , shader . name , propName ) , MessageType . Warning ) ;
break ;
2020-02-12 20:38:06 +08:00
}
}
serializedObject . ApplyModifiedProperties ( ) ;
}
2020-08-20 03:42:16 +08:00
private static bool DrawFloatOrVector3Field ( SerializedProperty sp , bool showXyz )
2020-02-12 20:38:06 +08:00
{
2020-08-20 03:42:16 +08:00
var x = sp . FindPropertyRelative ( "x" ) ;
var y = sp . FindPropertyRelative ( "y" ) ;
var z = sp . FindPropertyRelative ( "z" ) ;
2020-02-12 20:38:06 +08:00
2020-08-20 03:42:16 +08:00
showXyz | = ! Mathf . Approximately ( x . floatValue , y . floatValue ) | |
! Mathf . Approximately ( y . floatValue , z . floatValue ) | |
y . hasMultipleDifferentValues | |
z . hasMultipleDifferentValues ;
2020-02-12 20:38:06 +08:00
2020-08-20 03:42:16 +08:00
EditorGUILayout . BeginHorizontal ( ) ;
if ( showXyz )
2020-08-12 01:10:22 +08:00
{
2020-08-20 03:42:16 +08:00
EditorGUILayout . PropertyField ( sp ) ;
2020-08-12 01:10:22 +08:00
}
2020-08-20 03:42:16 +08:00
else
2020-08-12 01:10:22 +08:00
{
2020-08-20 03:42:16 +08:00
EditorGUI . BeginChangeCheck ( ) ;
EditorGUILayout . PropertyField ( x , s_ContentScale ) ;
if ( EditorGUI . EndChangeCheck ( ) )
z . floatValue = y . floatValue = x . floatValue ;
2020-08-12 01:10:22 +08:00
}
2020-02-12 20:38:06 +08:00
2020-08-20 03:42:16 +08:00
EditorGUI . BeginChangeCheck ( ) ;
showXyz = GUILayout . Toggle ( showXyz , s_Content3D , EditorStyles . miniButton , GUILayout . Width ( 30 ) ) ;
if ( EditorGUI . EndChangeCheck ( ) & & ! showXyz )
z . floatValue = y . floatValue = x . floatValue ;
EditorGUILayout . EndHorizontal ( ) ;
return showXyz ;
2020-02-12 20:38:06 +08:00
}
}
}