Skip to content

Commit

Permalink
close #42; Support changing material property by AnimationClip
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Feb 23, 2019
1 parent 4982f39 commit 233d3a9
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ protected override void OnEnable ()
_spTrailParticle = serializedObject.FindProperty ("m_TrailParticle");
_spScale = serializedObject.FindProperty ("m_Scale");
_spIgnoreParent = serializedObject.FindProperty ("m_IgnoreParent");
_spAnimatableProperties = serializedObject.FindProperty ("m_AnimatableProperties");

if (!s_Material)
{
Expand Down Expand Up @@ -86,6 +87,9 @@ public override void OnInspectorGUI ()
EditorGUILayout.PropertyField (_spScale);
EditorGUI.EndDisabledGroup ();

// AnimatableProperties
AnimatedProperty.DrawAnimatableProperties (_spAnimatableProperties, current.material);

current.GetComponentsInChildren<ParticleSystem> (true, s_ParticleSystems);
if (s_ParticleSystems.Any (x => x.GetComponent<UIParticle> () == null))
{
Expand All @@ -107,13 +111,117 @@ public override void OnInspectorGUI ()
serializedObject.ApplyModifiedProperties ();
}

class AnimatedProperty
{
static readonly List<string> s_ActiveNames = new List<string> ();
static readonly System.Text.StringBuilder s_Sb = new System.Text.StringBuilder ();

public string name;
public ShaderUtil.ShaderPropertyType type;

static string CollectActiveNames (SerializedProperty sp, List<string> result)
{
result.Clear ();
for (int i = 0; i < sp.arraySize; i++)
{
result.Add (sp.GetArrayElementAtIndex (i).FindPropertyRelative ("name").stringValue);
}

s_Sb.Length = 0;
if (result.Count == 0)
{
s_Sb.Append ("Nothing");
}
else
{
result.Aggregate (s_Sb, (a, b) => s_Sb.AppendFormat ("{0}, ", b));
s_Sb.Length -= 2;
}

return s_Sb.ToString ();
}

public static void DrawAnimatableProperties (SerializedProperty sp, Material mat)
{
if (!mat || !mat.shader)
return;
bool isClicked = false;
using (new EditorGUILayout.HorizontalScope (GUILayout.ExpandWidth(false)))
{
var r = EditorGUI.PrefixLabel (EditorGUILayout.GetControlRect (true), new GUIContent(sp.displayName, sp.tooltip));
isClicked = GUI.Button (r, CollectActiveNames (sp, s_ActiveNames), EditorStyles.popup);
}

if(isClicked)
{
GenericMenu gm = new GenericMenu ();
gm.AddItem (new GUIContent ("Nothing"), s_ActiveNames.Count == 0, () =>
{
sp.ClearArray ();
sp.serializedObject.ApplyModifiedProperties ();
});


for (int i = 0; i < sp.arraySize; i++)
{
var p = sp.GetArrayElementAtIndex (i);
var name = p.FindPropertyRelative ("name").stringValue;
var type = (ShaderUtil.ShaderPropertyType)p.FindPropertyRelative ("type").intValue;
AddMenu (gm, sp, new AnimatedProperty () { name = name, type = type }, false);
}

for (int i = 0; i < ShaderUtil.GetPropertyCount (mat.shader); i++)
{
var pName = ShaderUtil.GetPropertyName (mat.shader, i);
var type = ShaderUtil.GetPropertyType (mat.shader, i);
AddMenu (gm, sp, new AnimatedProperty () { name = pName, type = type }, true);

if (type == ShaderUtil.ShaderPropertyType.TexEnv)
{
AddMenu (gm, sp, new AnimatedProperty () { name = pName + "_ST", type = ShaderUtil.ShaderPropertyType.Vector }, true);
AddMenu (gm, sp, new AnimatedProperty () { name = pName + "_HDR", type = ShaderUtil.ShaderPropertyType.Vector }, true);
AddMenu (gm, sp, new AnimatedProperty () { name = pName + "_TexelSize", type = ShaderUtil.ShaderPropertyType.Vector }, true);
}

}

gm.ShowAsContext ();
}
}

public static void AddMenu (GenericMenu menu, SerializedProperty sp, AnimatedProperty property, bool add)
{
if (add && s_ActiveNames.Contains (property.name))
return;

menu.AddItem (new GUIContent (string.Format ("{0} ({1})", property.name, property.type)), s_ActiveNames.Contains (property.name), () =>
{
var index = s_ActiveNames.IndexOf (property.name);
if (0 <= index)
{
sp.DeleteArrayElementAtIndex (index);
}
else
{
sp.InsertArrayElementAtIndex (sp.arraySize);
var p = sp.GetArrayElementAtIndex (sp.arraySize - 1);
p.FindPropertyRelative ("name").stringValue = property.name;
p.FindPropertyRelative ("type").intValue = (int)property.type;
}
sp.serializedObject.ApplyModifiedProperties ();
});
}
}


//################################
// Private Members.
//################################
SerializedProperty _spParticleSystem;
SerializedProperty _spTrailParticle;
SerializedProperty _spScale;
SerializedProperty _spIgnoreParent;
SerializedProperty _spAnimatableProperties;
UIParticle [] _particles;
ArcHandle _arcHandle = new ArcHandle ();
BoxBoundsHandle _boxBoundsHandle = new BoxBoundsHandle ();
Expand Down
81 changes: 77 additions & 4 deletions Assets/Coffee/UIExtensions/UIParticle/Scripts/UIParticle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ public class UIParticle : MaskableGraphic
[Tooltip ("Ignore parent scale")]
[SerializeField] bool m_IgnoreParent = false;

[Tooltip ("Animatable material properties. AnimationでParticleSystemのマテリアルプロパティを変更する場合、有効にしてください。")]
[SerializeField] AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];

static MaterialPropertyBlock s_Mpb;

[System.Serializable]
public class AnimatableProperty
{
public enum ShaderPropertyType
{
Color,
Vector,
Float,
Range,
TexEnv,
};

public string name;
public ShaderPropertyType type;
}



//################################
// Public/Protected Members.
Expand All @@ -57,9 +79,7 @@ public override Texture mainTexture
if (!tex && _renderer)
{
Profiler.BeginSample ("Check material");
var mat = m_IsTrail
? _renderer.trailMaterial
: _renderer.sharedMaterial;
var mat = material;
if (mat && mat.HasProperty (s_IdMainTex))
{
tex = mat.mainTexture;
Expand All @@ -70,6 +90,35 @@ public override Texture mainTexture
}
}

public override Material material
{
get
{
return _renderer
? m_IsTrail
? _renderer.trailMaterial
: _renderer.sharedMaterial
: null;
}

set
{
if (!_renderer)
{
}
else if (m_IsTrail && _renderer.trailMaterial != value)
{
_renderer.trailMaterial = value;
SetMaterialDirty ();
}
else if (!m_IsTrail && _renderer.sharedMaterial != value)
{
_renderer.sharedMaterial = value;
SetMaterialDirty ();
}
}
}

/// <summary>
/// Particle effect scale.
/// </summary>
Expand Down Expand Up @@ -117,7 +166,15 @@ public bool isRoot
/// <param name="baseMaterial">Configured Material.</param>
public override Material GetModifiedMaterial (Material baseMaterial)
{
return base.GetModifiedMaterial (_renderer ? _renderer.sharedMaterial : baseMaterial);
Material mat = null;
if (!_renderer)
mat = baseMaterial;
else if (m_AnimatableProperties.Length == 0)
mat = _renderer.sharedMaterial;
else
mat = new Material (material);

return base.GetModifiedMaterial (mat);
}

/// <summary>
Expand All @@ -129,6 +186,7 @@ protected override void OnEnable ()
if (s_ActiveParticles.Count == 0)
{
Canvas.willRenderCanvases += UpdateMeshes;
s_Mpb = new MaterialPropertyBlock ();
}
s_ActiveParticles.Add (this);

Expand Down Expand Up @@ -369,6 +427,21 @@ void UpdateMesh ()
Profiler.BeginSample ("Set mesh and texture to CanvasRenderer");
canvasRenderer.SetMesh (_mesh);
canvasRenderer.SetTexture (mainTexture);

// Copy the value from MaterialPropertyBlock to CanvasRenderer (#41)
if (Application.isPlaying && 0 < m_AnimatableProperties.Length)
{
_renderer.GetPropertyBlock (s_Mpb);
for (int i = 0; i < canvasRenderer.materialCount; i++)
{
var mat = canvasRenderer.GetMaterial (i);
foreach (var ap in m_AnimatableProperties)
{
mat.SetVector (ap.name, s_Mpb.GetVector (ap.name));
}
}
}

Profiler.EndSample ();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.texcoord = TRANSFORM_TEX(IN.texcoord, _MainTex);
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
Expand Down

0 comments on commit 233d3a9

Please sign in to comment.