79 lines
3.1 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace Streamingle.Gaze
{
[TrackColor(0.23f, 0.74f, 0.92f)]
[TrackBindingType(typeof(BlendshapeGazeDriver))]
[TrackClipType(typeof(BlendshapeGazeClip))]
public sealed class BlendshapeGazeTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<BlendshapeGazeMixerBehaviour>.Create(graph, inputCount);
}
#if UNITY_EDITOR
public override void GatherProperties(PlayableDirector director, IPropertyCollector collector)
{
var gazeDriver = director != null
? director.GetGenericBinding(this) as BlendshapeGazeDriver
: null;
var targetRenderer = gazeDriver != null ? gazeDriver.TargetRenderer : null;
var profile = gazeDriver != null ? gazeDriver.Profile : null;
var channels = profile != null ? profile.Channels : null;
var mesh = targetRenderer != null ? targetRenderer.sharedMesh : null;
if (targetRenderer != null && mesh != null && channels != null)
{
var channelNames = new HashSet<string>();
var previewBindings = new AnimationClip
{
name = "Blendshape Gaze Preview Bindings",
hideFlags = HideFlags.HideAndDontSave
};
try
{
for (var i = 0; i < channels.Count; i++)
{
var channel = channels[i];
if (object.ReferenceEquals(channel, null))
continue;
var blendShapeIndex = profile.FindBlendShapeIndex(mesh, i);
if (blendShapeIndex < 0)
continue;
// AddFromName expects a SerializedProperty path, while
// blendShape.* is a synthetic Animator curve binding.
// Register it through a clip so Timeline's AnimationMode
// resolves and restores the real renderer property.
var channelName = mesh.GetBlendShapeName(blendShapeIndex);
if (string.IsNullOrWhiteSpace(channelName) || !channelNames.Add(channelName))
continue;
previewBindings.SetCurve(
string.Empty,
typeof(SkinnedMeshRenderer),
"blendShape." + channelName,
AnimationCurve.Constant(0f, 1f, 0f));
}
if (channelNames.Count > 0)
collector.AddFromClip(targetRenderer.gameObject, previewBindings);
}
finally
{
Object.DestroyImmediate(previewBindings);
}
}
base.GatherProperties(director, collector);
}
#endif
}
}