Files
Convention-Unity-Demo/Assets/Scripts/MoreSpline/SplineCore.cs
2025-12-12 15:19:10 +08:00

161 lines
5.0 KiB
C#

using Convention;
using Demo.Attr;
using Dreamteck.Splines;
using System;
using System.Collections;
using System.Collections.Generic;
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; }
void 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 SplineCore LoadSplineTool(this IDependOnSplineCore self, string path)
{
var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false);
if (spline == null)
spline = self.SharedInterfaceScriptObject.LoadSubScript(nameof(SplineCore), new ToolFile(path).GetFilename(true), path);
self.MySplineCore = (SplineCore)spline;
return self.MySplineCore;
}
}
[Scriptable]
public class SplineCore : ScriptableObject
{
protected override bool IsSelfEnableUpdate => false;
public static SplineCore Make()
{
SplineCore result = new GameObject("").AddComponent<SplineCore>();
var core = result.GetOrAddComponent<SplineComputer>();
result.m_MySplineComputer = core;
core.multithreaded = true;
return result;
}
[Content] private SplineComputer m_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 SplineComputer MySplineComputer => m_MySplineComputer;
//{
// get
// {
// if (m_MySplineComputer == null)
// m_MySplineComputer = this.GetComponent<SplineComputer>();
// return m_MySplineComputer;
// }
//}
/// <summary>
/// <see cref="SplineCore"/>需要在子<see cref="SplineNode"/>都添加后再应用脚本才能使得节点生效
/// </summary>
/// <returns></returns>
protected override IEnumerator DoSomethingDuringApplyScript()
{
yield return base.DoSomethingDuringApplyScript();
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;
MySplineComputer.Rebuild();
}
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
{
if (tickType != TickType.Update)
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>
[Convention.RScript.Variable.Attr.Method]
public void SetType(Spline.Type mode)
{
MyType = mode;
}
/// <summary>
/// 设置采样类型
/// </summary>
/// <param name="mode">Default, Uniform, Optimized</param>
[Convention.RScript.Variable.Attr.Method]
public void SetSampleMode(SplineComputer.SampleMode mode)
{
MySampleMode = mode;
}
/// <summary>
/// 闭环曲线
/// </summary>
[Convention.RScript.Variable.Attr.Method]
public void SetClose()
{
IsClose = true;
}
/// <summary>
/// 加入节点或者添加节点组件后加入节点
/// </summary>
/// <param name="path">脚本位置</param>
[Convention.RScript.Variable.Attr.Method]
public void LoadNode(SplineNode node)
{
MySplineNodes.Add(node);
}
}
}