using System; using System.Collections; using System.Collections.Generic; using Convention; using Dreamteck.Splines; using UnityEngine; namespace Demo.Game { public struct SplineClipDuration { public float ClipFrom; public float ClipTo; public SplineClipDuration(float clipFrom = 0, float clipTo = 1) { this.ClipFrom = clipFrom; this.ClipTo = clipTo; } } public interface IDependOnSplineCore : IScriptableObject { SplineCore MySplineCore { get; set; } IEnumerator LoadSpline(string path); } public static class DependOnSplineCoreUtility { public const string LoadSplineDescription = @" 加载并绑定到新样条线 对象相对路径,若对象不存在则作为脚本相对路径加载 "; /// /// 加载并绑定到新样条线 /// /// 对象相对路径,若对象不存在则作为脚本相对路径加载 public static IEnumerator LoadSplineTool(this IDependOnSplineCore self, string path) { var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false); if (spline == null) yield return self.SharedInterfaceScriptObject.LoadSubScriptAsync(nameof(SplineCore), path, x => spline = x); if (spline is SplineCore sc) { self.MySplineCore = sc; } else { Debug.LogWarning($"{path} is not a SplineCore", self.SharedInterfaceScriptObject); } } } public class SplineCore : ScriptableObject { public static SplineCore Make() { return new GameObject("", typeof(SplineComputer)).AddComponent(); } [Content] public SplineComputer MySplineComputer; [Content] public int NodeContent = 0; [Content] public List MySplineNodes = new(); [Content] public SplineComputer.SampleMode MySampleMode = default; [Content] public Spline.Type MyType = default; public bool IsClose = false; public override IEnumerator LoadScript(string script) { MySplineComputer = GetComponent(); yield return base.LoadScript(script); NodeContent = 0; MySplineComputer.SetPoints(new SplinePoint[MySplineNodes.Count]); foreach (SplineNode node in MySplineNodes) { node.AddTo(this); NodeContent++; } if (IsClose) MySplineComputer.Close(); else MySplineComputer.Break(); MySplineComputer.sampleMode = MySampleMode; MySplineComputer.type = MyType; yield return null; MySplineComputer.Rebuild(); } protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType) { if (tickType == TickType.Start || tickType == TickType.Reset) MySplineComputer.Rebuild(); } public override IEnumerator UnloadScript() { yield return base.UnloadScript(); NodeContent = 0; MySplineNodes.Clear(); IsClose = false; } /// /// 设置样条线类型 /// /// CatmullRom, BSpline, Bezier, Linear [ScriptableCall(@" 设置样条线类型 CatmullRom, BSpline, Bezier, Linear ")] public void SetType(string mode) { MyType = Enum.Parse(mode); } /// /// 设置采样类型 /// /// Default, Uniform, Optimized [ScriptableCall(@" 设置采样类型 Default, Uniform, Optimized ")] public void SetSampleMode(string mode) { MySampleMode = Enum.Parse(mode); } /// /// 闭环曲线 /// [ScriptableCall(@" 闭环曲线 ")] public void SetClose() { IsClose = true; } /// /// 加载并加入新节点 /// /// 脚本位置 [ScriptableCall(@" 加载并加入新节点 脚本位置 ")] public IEnumerator LoadNode(string path) { yield return LoadSubScriptAsync(nameof(SplineNode), path, node => { if (node != null) { MySplineNodes.Add(node as SplineNode); } }); } /// /// 加入已加载的节点,如果目标脚本不是SplineNode, /// 那么为其添加SplineNode组件 /// /// 脚本位置 [ScriptableCall(@" 加入已加载的节点,如果目标脚本不是SplineNode, 那么为其添加SplineNode组件 脚本位置 ")] public void AddNode(string path) { var node = FindWithPath(path); if (node != null) { MySplineNodes.Add(node.GetOrAddComponent()); } } } }