using System.Collections.Generic; using UnityEngine; namespace AibisDream.FrameAnimation { [CreateAssetMenu(fileName = "FrameAnimationGraph", menuName = "AibisDream/Frame Animation/Frame Animation Graph")] public sealed class FrameAnimationGraph : ScriptableObject { [SerializeField] private string id = string.Empty; [SerializeField] private string displayName = string.Empty; [SerializeField] private List clips = new List(); [SerializeField] private List nodes = new List(); [SerializeField] private List edges = new List(); [SerializeField] private List flows = new List(); [SerializeField] private List importSources = new List(); [SerializeField] private FrameAnimationGraphSettings settings = new FrameAnimationGraphSettings(); [SerializeField] private FrameAnimationGraphEditorData editorData = new FrameAnimationGraphEditorData(); public string Id => id; public string DisplayName => displayName; public IReadOnlyList Clips => clips; public IReadOnlyList Nodes => nodes; public IReadOnlyList Edges => edges; public IReadOnlyList Flows => flows; public IReadOnlyList ImportSources => importSources; public FrameAnimationGraphSettings Settings => settings; public FrameAnimationGraphEditorData EditorData => editorData; private void OnEnable() { EnsureCollections(); } #if UNITY_EDITOR private void OnValidate() { EnsureCollections(); EnsureMissingInternalIds(); } #endif internal void Configure( string graphId, string graphDisplayName, IEnumerable graphClips, IEnumerable graphNodes, IEnumerable graphEdges, IEnumerable graphFlows, string defaultPlayableId) { id = graphId ?? string.Empty; displayName = graphDisplayName ?? id; clips = graphClips != null ? new List(graphClips) : new List(); nodes = graphNodes != null ? new List(graphNodes) : new List(); edges = graphEdges != null ? new List(graphEdges) : new List(); flows = graphFlows != null ? new List(graphFlows) : new List(); importSources ??= new List(); settings ??= new FrameAnimationGraphSettings(); settings.SetDefaultPlayableId(defaultPlayableId); editorData ??= new FrameAnimationGraphEditorData(); EnsureMissingInternalIds(); } internal void EnsureMissingInternalIds() { if (nodes != null) { foreach (var node in nodes) { node?.EnsureInternalId(); } } if (edges != null) { foreach (var edge in edges) { edge?.EnsureInternalId(); } } if (importSources != null) { foreach (var source in importSources) { source?.EnsureInternalId(); } } } internal void AddImportedClip(FrameClip clip) { EnsureCollections(); if (clip != null && !clips.Contains(clip)) { clips.Add(clip); } } internal void AddClip(FrameClip clip) { AddImportedClip(clip); } internal bool RemoveClip(FrameClip clip) { EnsureCollections(); return clip != null && clips.Remove(clip); } internal void AddFlow(AnimationFlow flow) { EnsureCollections(); if (flow != null && !flows.Contains(flow)) { flows.Add(flow); } } internal bool RemoveFlow(AnimationFlow flow) { EnsureCollections(); return flow != null && flows.Remove(flow); } internal void AddNode(AnimationNode node) { EnsureCollections(); if (node != null && !nodes.Contains(node)) { node.EnsureInternalId(); nodes.Add(node); } } internal bool RemoveNode(AnimationNode node) { EnsureCollections(); return node != null && nodes.Remove(node); } internal void AddEdge(AnimationEdge edge) { EnsureCollections(); if (edge != null && !edges.Contains(edge)) { edge.EnsureInternalId(); edges.Add(edge); } } internal bool RemoveEdge(AnimationEdge edge) { EnsureCollections(); return edge != null && edges.Remove(edge); } internal void AddImportSource(FrameAnimationImportSource source) { EnsureCollections(); if (source != null && !importSources.Contains(source)) { source.EnsureInternalId(); importSources.Add(source); } } internal bool RemoveImportSource(FrameAnimationImportSource source) { EnsureCollections(); return source != null && importSources.Remove(source); } internal void SetId(string value) { id = value ?? string.Empty; } internal void SetDisplayName(string value) { displayName = value ?? string.Empty; } private void EnsureCollections() { clips ??= new List(); nodes ??= new List(); edges ??= new List(); flows ??= new List(); importSources ??= new List(); settings ??= new FrameAnimationGraphSettings(); editorData ??= new FrameAnimationGraphEditorData(); } } }