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.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(); 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 } }