198 lines
5.7 KiB
C#
198 lines
5.7 KiB
C#
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 = @"
|
||
<summary>
|
||
加载并绑定到新样条线
|
||
</summary>
|
||
<param name=""path"">对象相对路径,若对象不存在则作为脚本相对路径加载</param>
|
||
";
|
||
|
||
/// <summary>
|
||
/// 加载并绑定到新样条线
|
||
/// </summary>
|
||
/// <param name="path">对象相对路径,若对象不存在则作为脚本相对路径加载</param>
|
||
public static IEnumerator LoadSplineTool(this IDependOnSplineCore self, string path)
|
||
{
|
||
var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false);
|
||
if (spline == null)
|
||
yield return self.SharedInterfaceScriptObject.DoLoadSubScriptAsync(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<SplineCore>();
|
||
}
|
||
|
||
[Content] public SplineComputer MySplineComputer;
|
||
[Content] public int NodeContent = 0;
|
||
[Content] public List<SplineNode> 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<SplineComputer>();
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置样条线类型
|
||
/// </summary>
|
||
/// <param name="mode">CatmullRom, BSpline, Bezier, Linear </param>
|
||
[ScriptableCall(@"
|
||
<summary>
|
||
设置样条线类型
|
||
</summary>
|
||
<param name=""mode"">CatmullRom, BSpline, Bezier, Linear </param>
|
||
")]
|
||
public void SetType(string mode)
|
||
{
|
||
MyType = Enum.Parse<Spline.Type>(mode);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置采样类型
|
||
/// </summary>
|
||
/// <param name="mode">Default, Uniform, Optimized</param>
|
||
[ScriptableCall(@"
|
||
<summary>
|
||
设置采样类型
|
||
</summary>
|
||
<param name=""mode"">Default, Uniform, Optimized</param>
|
||
")]
|
||
public void SetSampleMode(string mode)
|
||
{
|
||
MySampleMode = Enum.Parse<SplineComputer.SampleMode>(mode);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 闭环曲线
|
||
/// </summary>
|
||
[ScriptableCall(@"
|
||
<summary>
|
||
闭环曲线
|
||
</summary>
|
||
")]
|
||
public void SetClose()
|
||
{
|
||
IsClose = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载并加入新节点
|
||
/// </summary>
|
||
/// <param name="path">脚本位置</param>
|
||
[ScriptableCall(@"
|
||
<summary>
|
||
加载并加入新节点
|
||
</summary>
|
||
<param name=""path"">脚本位置</param>
|
||
")]
|
||
public IEnumerator LoadNode(string path)
|
||
{
|
||
yield return DoLoadSubScriptAsync(nameof(SplineNode), path, node =>
|
||
{
|
||
if (node is SplineNode _node)
|
||
{
|
||
MySplineNodes.Add(_node );
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"{path} is not {nameof(SplineNode)}", this);
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加入已加载的节点,如果目标脚本不是SplineNode,
|
||
/// 那么为其添加SplineNode组件
|
||
/// </summary>
|
||
/// <param name="path">脚本位置</param>
|
||
[ScriptableCall(@"
|
||
<summary>
|
||
加入已加载的节点,如果目标脚本不是SplineNode,
|
||
那么为其添加SplineNode组件
|
||
</summary>
|
||
<param name=""path"">脚本位置</param>
|
||
")]
|
||
public void AddNode(string path)
|
||
{
|
||
var node = FindWithPath(path);
|
||
if (node != null)
|
||
{
|
||
MySplineNodes.Add(node.GetOrAddComponent<SplineNode>());
|
||
}
|
||
}
|
||
}
|
||
}
|