Timeline功能强大,但可控的参数还是较少,官方提供了自定义编写Playable的方法,用于扩展Timeline,使其更加强大。
上一篇我们介绍了一些官方发布到Asset Store上的免费Playable,我们以其为模板,创建自己的Playable。
官方的例子提供了控制Text,Light,等。我们来尝试控制下Particle,粒子系统。
根据这个模板,我们可以进行扩展,进而可以使用Timeline控制粒子系统的任意参数
本篇目标:
通过Timeline控制粒子系统的StartColor,即
我们需要创建如下五个脚本
Drawer用来绘制,ParticleClip在Inspector中的颜色块,粒子将会根据这个颜色块更改颜色
在ParticleBehaivour中,定义要更改的变量
几个脚本的代码内容如下:
ParticleBehaivour:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
[Serializable]
public class ParticleBehaviour : PlayableBehaviour
{
public Color p_startColor = Color.white;
}
ParticleClip.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using System;
[Serializable]
public class ParticleClip : PlayableAsset , ITimelineClipAsset
{
public ParticleBehaviour templete = new ParticleBehaviour();
public ClipCaps clipCaps {
get { return ClipCaps.Blending; }
}
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner) {
var playable = ScriptPlayable.Create(graph, templete);
return playable;
}
}
ParticleMixerBehviour.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class ParticleMixerBehviour : PlayableBehaviour
{
Color m_DefaultColor;
ParticleSystem m_TrackBinding;
bool m_firstFrameHappened;
public override void ProcessFrame(Playable playable, FrameData info, object playerData) {
m_TrackBinding = playerData as ParticleSystem;
if (m_TrackBinding == null)
return;
if (!m_firstFrameHappened) {
//
var p_main = m_TrackBinding.main;
m_DefaultColor = p_main.startColor.color;
m_firstFrameHappened = true;
}
int inputCount = playable.GetInputCount();
Color blendedColor = Color.clear;
float totalWeight = 0f;
float greatestWeight = 0f;
int currentInputs = 0;
for(int i = 0; i < inputCount; i++) {
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable inputPlayable = (ScriptPlayable)playable.GetInput(i);
ParticleBehaviour input = inputPlayable.GetBehaviour();
blendedColor += input.p_startColor * inputWeight;
totalWeight += inputWeight;
if (inputWeight > greatestWeight) {
greatestWeight = inputWeight;
}
if (!Mathf.Approximately(inputWeight, 0))
currentInputs++;
}
var main = m_TrackBinding.main;
main.startColor = blendedColor + m_DefaultColor * (1f - totalWeight);
}
public override void OnPlayableDestroy(Playable playable) {
m_firstFrameHappened = false;
if (m_TrackBinding == null)
return;
var main = m_TrackBinding.main;
main.startColor = m_DefaultColor;
}
}
ParticleTrack.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[TrackColor(0.35f,0.97f,0.64f)]
[TrackClipType(typeof(ParticleClip))]
[TrackBindingType(typeof(ParticleSystem))]
public class ParticleTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) {
return ScriptPlayable.Create(graph, inputCount);
}
public override void GatherProperties(PlayableDirector director, IPropertyCollector driver) {
#if UNITY_EDITOR
ParticleSystem trackBinding = director.GetGenericBinding(this) as ParticleSystem;
if (trackBinding == null)
return;
var serializedObject = new UnityEditor.SerializedObject(trackBinding);
var iterator = serializedObject.GetIterator();
while (iterator.NextVisible(true)) {
if (iterator.hasVisibleChildren)
continue;
//driver.AddFromName(trackBinding.gameObject, iterator.propertyPath);
}
#endif
base.GatherProperties(director, driver);
}
}
ParticleDrawer.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(ParticleBehaviour))]
public class ParticleDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
int fieldCount = 1;
return fieldCount * EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty colorProp = property.FindPropertyRelative("p_startColor");
Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, colorProp);
}
}
创建如上脚本,粘贴以上代码,即可在Timeline中创建相应轨道。拖拽任意物体到Timeline中,也可创建Particle轨道
源码在这:
https://download.csdn.net/download/u011643463/11268727
同篇笔记(这里也能下到源码,万恶资本主义,我没法在本站上传0积分资源)
http://note.youdao.com/noteshare?id=28beb40d88f30e41af212c72e8de1d8f&sub=432815D8787545BB9FE0B1E57067AB99