| using System; |
| using System.Linq; |
| using System.Collections.Generic; |
| using UnityEngine; |
| using UnityEngine.Timeline; |
|
|
| namespace UnityEditor.Timeline |
| { |
| |
| |
| |
| public struct TrackDrawOptions |
| { |
| |
| |
| |
| |
| |
| |
| public string errorText { get; set; } |
|
|
| |
| |
| |
| public Color trackColor { get; set; } |
|
|
| |
| |
| |
| public float minimumHeight { get; set; } |
|
|
| |
| |
| |
| |
| |
| |
| public Texture2D icon { get; set; } |
|
|
| |
| |
| |
| |
| |
| public override bool Equals(object obj) |
| { |
| if (!(obj is TrackDrawOptions)) |
| return false; |
|
|
| return Equals((TrackDrawOptions)obj); |
| } |
|
|
| |
| |
| |
| |
| |
| public bool Equals(TrackDrawOptions other) |
| { |
| return errorText == other.errorText && |
| trackColor == other.trackColor && |
| minimumHeight == other.minimumHeight && |
| icon == other.icon; |
| } |
|
|
| |
| |
| |
| |
| public override int GetHashCode() |
| { |
| return HashUtility.CombineHash( |
| errorText != null ? errorText.GetHashCode() : 0, |
| trackColor.GetHashCode(), |
| minimumHeight.GetHashCode(), |
| icon != null ? icon.GetHashCode() : 0 |
| ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public static bool operator ==(TrackDrawOptions options1, TrackDrawOptions options2) |
| { |
| return options1.Equals(options2); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public static bool operator !=(TrackDrawOptions options1, TrackDrawOptions options2) |
| { |
| return !options1.Equals(options2); |
| } |
| } |
|
|
|
|
| |
| |
| |
| public enum TrackBindingErrors |
| { |
| |
| |
| |
| None = 0, |
|
|
| |
| |
| |
| BoundGameObjectDisabled = 1 << 0, |
|
|
| |
| |
| |
| NoValidComponent = 1 << 1, |
|
|
| |
| |
| |
| BehaviourIsDisabled = 1 << 2, |
|
|
| |
| |
| |
| InvalidBinding = 1 << 3, |
|
|
| |
| |
| |
| PrefabBound = 1 << 4, |
|
|
| |
| |
| |
| All = Int32.MaxValue |
| } |
|
|
| |
| |
| |
| public class TrackEditor |
| { |
| static readonly string k_BoundGameObjectDisabled = L10n.Tr("The bound GameObject is disabled."); |
| static readonly string k_NoValidComponent = L10n.Tr("Could not find appropriate component on this gameObject"); |
| static readonly string k_RequiredComponentIsDisabled = L10n.Tr("The component is disabled"); |
| static readonly string k_InvalidBinding = L10n.Tr("The bound object is not the correct type."); |
| static readonly string k_PrefabBound = L10n.Tr("The bound object is a Prefab"); |
|
|
| readonly Dictionary<TrackAsset, System.Type> m_BindingCache = new Dictionary<TrackAsset, System.Type>(); |
|
|
| |
| |
| |
| public static readonly float DefaultTrackHeight = 30.0f; |
|
|
| |
| |
| |
| public static readonly float MinimumTrackHeight = 10.0f; |
|
|
| |
| |
| |
| public static readonly float MaximumTrackHeight = 256.0f; |
|
|
| |
| |
| |
| |
| |
| |
| public virtual TrackDrawOptions GetTrackOptions(TrackAsset track, UnityEngine.Object binding) |
| { |
| return new TrackDrawOptions() |
| { |
| errorText = GetErrorText(track, binding, TrackBindingErrors.All), |
| minimumHeight = DefaultTrackHeight, |
| trackColor = GetTrackColor(track), |
| icon = null |
| }; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public string GetErrorText(TrackAsset track, UnityEngine.Object boundObject, TrackBindingErrors detectErrors) |
| { |
| if (track == null || boundObject == null) |
| return string.Empty; |
|
|
| var bindingType = GetBindingType(track); |
| if (bindingType != null) |
| { |
| |
| if (HasFlag(detectErrors, TrackBindingErrors.PrefabBound) && PrefabUtility.IsPartOfPrefabAsset(boundObject)) |
| { |
| return k_PrefabBound; |
| } |
|
|
| |
| if (typeof(Component).IsAssignableFrom(bindingType)) |
| { |
| var gameObject = boundObject as GameObject; |
| var component = boundObject as Component; |
| if (component != null) |
| gameObject = component.gameObject; |
|
|
| |
| if (HasFlag(detectErrors, TrackBindingErrors.NoValidComponent) && gameObject != null && component == null) |
| { |
| component = gameObject.GetComponent(bindingType); |
| if (component == null) |
| { |
| return k_NoValidComponent; |
| } |
| } |
|
|
| |
| if (HasFlag(detectErrors, TrackBindingErrors.BoundGameObjectDisabled) && gameObject != null && !gameObject.activeInHierarchy) |
| { |
| return k_BoundGameObjectDisabled; |
| } |
|
|
| |
| var behaviour = component as Behaviour; |
| if (HasFlag(detectErrors, TrackBindingErrors.BehaviourIsDisabled) && behaviour != null && !behaviour.enabled) |
| { |
| return k_RequiredComponentIsDisabled; |
| } |
|
|
| |
| if (HasFlag(detectErrors, TrackBindingErrors.InvalidBinding) && component != null && !bindingType.IsAssignableFrom(component.GetType())) |
| { |
| return k_InvalidBinding; |
| } |
| } |
| |
| else if (HasFlag(detectErrors, TrackBindingErrors.InvalidBinding) && !bindingType.IsAssignableFrom(boundObject.GetType())) |
| { |
| return k_InvalidBinding; |
| } |
| } |
|
|
| return string.Empty; |
| } |
|
|
| |
| |
| |
| |
| |
| public Color GetTrackColor(TrackAsset track) |
| { |
| return TrackResourceCache.GetTrackColor(track); |
| } |
|
|
| |
| |
| |
| |
| |
| public System.Type GetBindingType(TrackAsset track) |
| { |
| if (track == null) |
| return null; |
|
|
| if (m_BindingCache.TryGetValue(track, out var result)) |
| return result; |
|
|
| result = track.outputs.Select(x => x.outputTargetType).FirstOrDefault(); |
| m_BindingCache[track] = result; |
| return result; |
| } |
|
|
| |
| |
| |
| |
| |
| public virtual void OnCreate(TrackAsset track, TrackAsset copiedFrom) |
| { |
| } |
|
|
| |
| |
| |
| |
| public virtual void OnTrackChanged(TrackAsset track) |
| { |
| } |
|
|
| static bool HasFlag(TrackBindingErrors errors, TrackBindingErrors flag) |
| { |
| return (errors & flag) != 0; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public virtual bool IsBindingAssignableFrom(UnityEngine.Object candidate, TrackAsset track) |
| { |
| var action = BindingUtility.GetBindingAction(GetBindingType(track), candidate); |
| return action != BindingUtility.BindingAction.DoNotBind; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public virtual UnityEngine.Object GetBindingFrom(UnityEngine.Object candidate, TrackAsset track) |
| { |
| Type bindingType = GetBindingType(track); |
| BindingUtility.BindingAction action = BindingUtility.GetBindingAction(bindingType, candidate); |
| return BindingUtility.GetBinding(action, candidate, bindingType); |
| } |
| } |
|
|
| static class TrackEditorExtension |
| { |
| public static bool SupportsBindingAssign(this TrackEditor editor) |
| { |
| return TypeUtility.HasOverrideMethod(editor.GetType(), nameof(TrackEditor.GetBindingFrom)); |
| } |
|
|
| public static void OnCreate_Safe(this TrackEditor editor, TrackAsset track, TrackAsset copiedFrom) |
| { |
| try |
| { |
| editor.OnCreate(track, copiedFrom); |
| } |
| catch (Exception e) |
| { |
| Debug.LogException(e); |
| } |
| } |
|
|
| public static TrackDrawOptions GetTrackOptions_Safe(this TrackEditor editor, TrackAsset track, UnityEngine.Object binding) |
| { |
| try |
| { |
| return editor.GetTrackOptions(track, binding); |
| } |
| catch (Exception e) |
| { |
| Debug.LogException(e); |
| return CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, binding); |
| } |
| } |
|
|
| public static UnityEngine.Object GetBindingFrom_Safe(this TrackEditor editor, UnityEngine.Object candidate, TrackAsset track) |
| { |
| try |
| { |
| return editor.GetBindingFrom(candidate, track); |
| } |
| catch (Exception e) |
| { |
| Debug.LogException(e); |
| return candidate; |
| } |
| } |
|
|
| public static bool IsBindingAssignableFrom_Safe(this TrackEditor editor, UnityEngine.Object candidate, TrackAsset track) |
| { |
| try |
| { |
| return editor.IsBindingAssignableFrom(candidate, track); |
| } |
| catch (Exception e) |
| { |
| Debug.LogException(e); |
| return false; |
| } |
| } |
|
|
| public static void OnTrackChanged_Safe(this TrackEditor editor, TrackAsset track) |
| { |
| try |
| { |
| editor.OnTrackChanged(track); |
| } |
| catch (Exception e) |
| { |
| Debug.LogException(e); |
| } |
| } |
| } |
| } |
|
|