2025-09-25 19:04:05 +08:00
|
|
|
|
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; }
|
2025-10-06 16:09:52 +08:00
|
|
|
|
IEnumerator LoadSpline(string path);
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static class DependOnSplineCoreUtility
|
|
|
|
|
|
{
|
|
|
|
|
|
public const string LoadSplineDescription = @"
|
|
|
|
|
|
<summary>
|
|
|
|
|
|
加载并绑定到新样条线
|
|
|
|
|
|
</summary>
|
|
|
|
|
|
<param name=""path"">对象相对路径,若对象不存在则作为脚本相对路径加载</param>
|
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载并绑定到新样条线
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path">对象相对路径,若对象不存在则作为脚本相对路径加载</param>
|
2025-10-06 16:09:52 +08:00
|
|
|
|
public static IEnumerator LoadSplineTool(this IDependOnSplineCore self, string path)
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false);
|
|
|
|
|
|
if (spline == null)
|
2025-10-12 00:54:25 +08:00
|
|
|
|
yield return self.SharedInterfaceScriptObject.DoLoadSubScriptAsync(nameof(SplineCore), path, x => spline = x);
|
2025-10-06 16:09:52 +08:00
|
|
|
|
if (spline is SplineCore sc)
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
2025-10-06 16:09:52 +08:00
|
|
|
|
self.MySplineCore = sc;
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
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>
|
2025-10-27 20:24:15 +08:00
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
2025-09-25 19:04:05 +08:00
|
|
|
|
public void SetType(string mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
MyType = Enum.Parse<Spline.Type>(mode);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置采样类型
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mode">Default, Uniform, Optimized</param>
|
2025-10-27 20:24:15 +08:00
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
2025-09-25 19:04:05 +08:00
|
|
|
|
public void SetSampleMode(string mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
MySampleMode = Enum.Parse<SplineComputer.SampleMode>(mode);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 闭环曲线
|
|
|
|
|
|
/// </summary>
|
2025-10-27 20:24:15 +08:00
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
2025-09-25 19:04:05 +08:00
|
|
|
|
public void SetClose()
|
|
|
|
|
|
{
|
|
|
|
|
|
IsClose = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载并加入新节点
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path">脚本位置</param>
|
2025-10-27 20:24:15 +08:00
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
2025-10-06 16:09:52 +08:00
|
|
|
|
public IEnumerator LoadNode(string path)
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
2025-10-12 00:54:25 +08:00
|
|
|
|
yield return DoLoadSubScriptAsync(nameof(SplineNode), path, node =>
|
2025-09-25 19:04:05 +08:00
|
|
|
|
{
|
2025-10-06 17:43:21 +08:00
|
|
|
|
if (node is SplineNode _node)
|
2025-10-06 16:09:52 +08:00
|
|
|
|
{
|
2025-11-12 16:12:01 +08:00
|
|
|
|
MySplineNodes.Add(_node);
|
2025-10-06 17:43:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"{path} is not {nameof(SplineNode)}", this);
|
2025-10-06 16:09:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-12 16:12:01 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加入节点脚本对象
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
|
|
|
|
|
public void AddNode(ScriptableObject node)
|
|
|
|
|
|
{
|
|
|
|
|
|
MySplineNodes.Add(node.GetOrAddComponent<SplineNode>());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-25 19:04:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加入已加载的节点,如果目标脚本不是SplineNode,
|
|
|
|
|
|
/// 那么为其添加SplineNode组件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path">脚本位置</param>
|
2025-10-27 20:24:15 +08:00
|
|
|
|
[Convention.RScript.Variable.Attr.Method]
|
2025-09-25 19:04:05 +08:00
|
|
|
|
public void AddNode(string path)
|
|
|
|
|
|
{
|
|
|
|
|
|
var node = FindWithPath(path);
|
|
|
|
|
|
if (node != null)
|
|
|
|
|
|
{
|
2025-11-12 16:12:01 +08:00
|
|
|
|
AddNode(node);
|
2025-09-25 19:04:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|