推进同化RScript

This commit is contained in:
2025-11-24 18:02:57 +08:00
parent fc8f48bc7e
commit 2e0d16db49
17 changed files with 400 additions and 864 deletions

View File

@@ -30,11 +30,6 @@ namespace Demo.Game
VirtualCamera = GetComponent<CinemachineVirtualCamera>(); VirtualCamera = GetComponent<CinemachineVirtualCamera>();
} }
public override IEnumerator LoadScript(string script)
{
yield return base.LoadScript(script);
}
public override IEnumerator UnloadScript() public override IEnumerator UnloadScript()
{ {
yield return base.UnloadScript(); yield return base.UnloadScript();
@@ -44,90 +39,74 @@ namespace Demo.Game
/// <summary> /// <summary>
/// 设置是否为正交相机 /// 设置是否为正交相机
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetOrthographic(string arg) public void SetOrthographic(bool orthographic)
{ {
MainCamera.orthographic = ConvertValue<bool>(arg); MainCamera.orthographic = orthographic;
} }
/// <summary> /// <summary>
/// 设置相机视野角度 /// 设置相机视野角度
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetFieldOfView(string arg) public void SetFieldOfView(float fieldOfView)
{ {
MainCamera.fieldOfView = Parse(arg); MainCamera.fieldOfView = fieldOfView;
} }
/// <summary> /// <summary>
/// 设置正交相机的尺寸 /// 设置正交相机的尺寸
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetOrthographicSize(string arg) public void SetOrthographicSize(float orthographicSize)
{ {
MainCamera.orthographicSize = Parse(arg); MainCamera.orthographicSize = orthographicSize;
} }
/// <summary> /// <summary>
/// 设置近裁剪面距离 /// 设置近裁剪面距离
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetNearClipPlane(string arg) public void SetNearClipPlane(float nearClipPlane)
{ {
MainCamera.nearClipPlane = Parse(arg); MainCamera.nearClipPlane = nearClipPlane;
} }
/// <summary> /// <summary>
/// 设置远裁剪面距离 /// 设置远裁剪面距离
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetFarClipPlane(string arg) public void SetFarClipPlane(float farClipPlane)
{ {
MainCamera.farClipPlane = Parse(arg); MainCamera.farClipPlane = farClipPlane;
} }
/// <summary> /// <summary>
/// 设置相机深度 /// 设置相机深度
/// </summary> /// </summary>
/// <param name="arg"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetDepth(string arg) public void SetDepth(float depth)
{ {
MainCamera.depth = Parse(arg); MainCamera.depth = depth;
} }
/// <summary> /// <summary>
/// 设置虚拟相机跟随目标 /// 设置虚拟相机跟随目标
/// </summary> /// </summary>
/// <param name="targetName">对象相对路径</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetVirtualCameraFollow(string targetName) public void SetVirtualCameraFollow(ScriptableObject target)
{
var target = FindWithPath(targetName, false);
if (target != null)
{ {
VirtualCamera.Follow = target.transform; VirtualCamera.Follow = target.transform;
} }
}
/// <summary> /// <summary>
/// 设置虚拟相机观察目标 /// 设置虚拟相机观察目标
/// </summary> /// </summary>
/// <param name="targetName">对象相对路径</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetVirtualCameraLookAt(string targetName) public void SetVirtualCameraLookAt(ScriptableObject target)
{
var target = FindWithPath(targetName, false);
if (target != null)
{ {
VirtualCamera.LookAt = target.transform; VirtualCamera.LookAt = target.transform;
} }
}
/// <summary> /// <summary>
/// 设置虚拟相机跟随偏移 /// 设置虚拟相机跟随偏移
@@ -136,16 +115,12 @@ namespace Demo.Game
/// <param name="y">Y轴偏移</param> /// <param name="y">Y轴偏移</param>
/// <param name="z">Z轴偏移</param> /// <param name="z">Z轴偏移</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetVirtualCameraFollowOffset(string x, string y, string z) public void SetVirtualCameraFollowOffset(float x, float y, float z)
{ {
var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>(); var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>();
if (body != null) if (body != null)
{ {
body.m_FollowOffset = new Vector3( body.m_FollowOffset = new Vector3(x, y, z);
Parse(x),
Parse(y),
Parse(z)
);
} }
} }
@@ -156,14 +131,14 @@ namespace Demo.Game
/// <param name="y">Y轴阻尼</param> /// <param name="y">Y轴阻尼</param>
/// <param name="z">Z轴阻尼</param> /// <param name="z">Z轴阻尼</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetVirtualCameraFollowDamping(string x, string y, string z) public void SetVirtualCameraFollowDamping(float x, float y, float z)
{ {
var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>(); var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>();
if (body != null) if (body != null)
{ {
body.m_XDamping = Parse(x); body.m_XDamping = x;
body.m_YDamping = Parse(y); body.m_YDamping = y;
body.m_ZDamping = Parse(z); body.m_ZDamping = z;
} }
} }
@@ -174,13 +149,13 @@ namespace Demo.Game
/// <param name="y">Y轴阻尼</param> /// <param name="y">Y轴阻尼</param>
/// <param name="z">Z轴阻尼</param> /// <param name="z">Z轴阻尼</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetVirtualCameraLookAtDamping(string x, string y, string z) public void SetVirtualCameraLookAtDamping(float x, float y, float z)
{ {
var aim = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineComposer>(); var aim = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineComposer>();
if (aim != null) if (aim != null)
{ {
aim.m_HorizontalDamping = Parse(x); aim.m_HorizontalDamping = x;
aim.m_VerticalDamping = Parse(y); aim.m_VerticalDamping = y;
} }
} }
} }

View File

@@ -6,8 +6,6 @@ namespace Demo.Game
{ {
public class DDT : ScriptableObject public class DDT : ScriptableObject
{ {
public string BindingDataJson => $"{ScriptPath}.json";
public static DDT Make() public static DDT Make()
{ {
return new GameObject().AddComponent<DDT>(); return new GameObject().AddComponent<DDT>();
@@ -15,12 +13,6 @@ namespace Demo.Game
public List<float> Datas = new(); public List<float> Datas = new();
[Convention.RScript.Variable.Attr.Method]
public void Add(string value)
{
Datas.Add(Parse(value));
}
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(float value) public void Add(float value)
{ {
@@ -32,28 +24,5 @@ namespace Demo.Game
{ {
Datas.Add((barCount + tickCount / (float)barSplitTimes) * OneBarTime); Datas.Add((barCount + tickCount / (float)barSplitTimes) * OneBarTime);
} }
/// <summary>
/// 从特定的json中读取数据, 并调用<see cref="Add(string)"/>
/// </summary>
[Convention.RScript.Variable.Attr.Method]
public void Load()
{
var file = new ToolFile(BindingDataJson);
if (file.Exists() == false)
{
file.MustExistsPath()
.SaveAsJson<List<string>>(new());
Datas.Clear();
}
else
{
Datas.Clear();
foreach (var item in file.LoadAsJson<List<string>>())
{
Add(item);
}
}
}
} }
} }

View File

@@ -205,10 +205,11 @@ namespace Demo.Game
rootGameObject.transform.SetParent(transform); rootGameObject.transform.SetParent(transform);
rootGameObject.ScriptName = rootObject.GetName(true); rootGameObject.ScriptName = rootObject.GetName(true);
rootGameObject.audioSystem = MainAudio; rootGameObject.audioSystem = MainAudio;
rootGameObject.EnableScript(content.RootSourceDir, rootObject.GetFullPath(), this); rootGameObject.EnableScript(content.RootSourceDir, this);
try try
{ {
yield return rootGameObject.LoadScript(rootObject.LoadAsText()); yield return rootGameObject.ParseScript2Expr(rootObject.LoadAsText());
yield return rootGameObject.ApplyScript();
} }
finally finally
{ {

View File

@@ -1,10 +1,8 @@
using Convention;
using Convention.WindowsUI.Variant;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Convention;
using Convention.VFX;
using Convention.WindowsUI.Variant;
using Demo.Editor.UI;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
@@ -16,21 +14,17 @@ namespace Demo.Game
[Content] public GameController RootGameController; [Content] public GameController RootGameController;
public override IEnumerator LoadScript(string script) public string SourcePath;
protected override IEnumerator DoSomethingDuringApplyScript()
{ {
try yield return base.DoSomethingDuringApplyScript();
{ ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Reset);
yield return base.LoadScript(script);
}
finally
{
ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Start);
if (RootGameController.IsMain) if (RootGameController.IsMain)
{ {
Keyboard.current.onTextInput += InputCatchChar; Keyboard.current.onTextInput += InputCatchChar;
} }
} }
}
public override IEnumerator UnloadScript() public override IEnumerator UnloadScript()
{ {
@@ -41,14 +35,15 @@ namespace Demo.Game
yield return base.UnloadScript(); yield return base.UnloadScript();
} }
public void EnableScript(string sourcePath, string scriptPath, GameController parent) public void EnableScript(string sourcePath, GameController parent)
{ {
AllScriptableObjectCounter = 0; AllScriptableObjectCounter = 0;
if (AllScriptableObjectCounterHierarchyItem == null) if (AllScriptableObjectCounterHierarchyItem == null)
{ {
AllScriptableObjectCounterHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(typeof(ScriptableObject))[0]; AllScriptableObjectCounterHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(typeof(ScriptableObject))[0];
} }
base.EnableScript(sourcePath, scriptPath, nameof(RootObject), null); SourcePath = sourcePath;
base.EnableScript(null);
RootGameController = parent; RootGameController = parent;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -17,46 +17,17 @@ namespace Demo.Game
[Content, SerializeField] private string project; [Content, SerializeField] private string project;
[Content, SerializeField] private GameController SubWorldGameController; [Content, SerializeField] private GameController SubWorldGameController;
public override IEnumerator LoadScript(string script) protected override IEnumerator DoSomethingDuringApplyScript()
{ {
yield return base.LoadScript(script); yield return base.DoSomethingDuringApplyScript();
/*
// Load
var content = GameContent.instance;
// Always
content.IsCreateNewProject = false;
// Push Content
var oldContentRootSourceDir = content.RootSourceDir;
var oldSetupSongDuration = content.SetupSongDuration;
var oldSetSongCurrentTime = content.SetSongCurrentTime;
// Setting New
content.RootSourceDir = Path.Combine(PlatformIndicator.StreamingAssetsPath, project) + "/";
content.SetupSongDuration = (x, y) => { };
content.SetSongCurrentTime = x => { };
var ir = SceneManager.LoadSceneAsync(Editor.EditorController.SceneName, LoadSceneMode.Additive); var ir = SceneManager.LoadSceneAsync(Editor.EditorController.SceneName, LoadSceneMode.Additive);
ir.completed += x => ir.completed += x =>
{ {
SubWorldGameController = (from controller in FindObjectsOfType<GameController>() SubWorldGameController = (from controller in FindObjectsOfType<GameController>()
where controller.RootSourcePath == project where controller.RootSourcePath == project
select controller).First(); select controller).First();
ConventionUtility.StartCoroutine(SubWorldGameController.GameInitBySubWorld(GetRoot().InputCatch));
}; };
yield return ir;
// Pull Content
content.RootSourceDir = oldContentRootSourceDir;
content.SetupSongDuration = oldSetupSongDuration;
content.SetSongCurrentTime = oldSetSongCurrentTime;
*/
var ir = SceneManager.LoadSceneAsync(Editor.EditorController.SceneName, LoadSceneMode.Additive);
IEnumerator after = null;
ir.completed += x =>
{
SubWorldGameController = (from controller in FindObjectsOfType<GameController>()
where controller.RootSourcePath == project
select controller).First();
after = SubWorldGameController.GameInitBySubWorld(GetRoot().InputCatch);
};
yield return ir;
yield return after;
} }
public override IEnumerator UnloadScript() public override IEnumerator UnloadScript()

View File

@@ -20,7 +20,7 @@ namespace Demo.Game
} }
public int Content = 0; public int Content = 0;
public List<UpdatementEntry> Entries = new(); public readonly List<UpdatementEntry> Entries = new();
protected abstract void UpdateData(DataType data); protected abstract void UpdateData(DataType data);
protected abstract DataType Lerp(DataType begin, DataType end, float t); protected abstract DataType Lerp(DataType begin, DataType end, float t);
@@ -40,26 +40,15 @@ namespace Demo.Game
}); });
} }
/// <summary>
/// 添加数据
/// </summary>
/// <param name="time"></param>
/// <param name="position"></param>
/// <param name="curveType"></param>
public void ManualAddEntry(string time, DataType position, MathExtension.EaseCurveType curveType)
{
ManualAddEntry(time, position, curveType);
}
private void UpdateEntry(int start, float percent) private void UpdateEntry(int start, float percent)
{ {
UpdatementEntry head = Entries[start], tail = Entries[Mathf.Min(start + 1, Entries.Count - 1)]; UpdatementEntry head = Entries[start], tail = Entries[Mathf.Min(start + 1, Entries.Count - 1)];
UpdateData(Lerp(head.Position, tail.Position, MathExtension.Evaluate(Mathf.Clamp01(percent), head.easeCurveType))); UpdateData(Lerp(head.Position, tail.Position, MathExtension.Evaluate(Mathf.Clamp01(percent), head.easeCurveType)));
} }
public override IEnumerator LoadScript(string script) protected override IEnumerator DoSomethingDuringApplyScript()
{ {
yield return base.LoadScript(script); yield return base.DoSomethingDuringApplyScript();
Entries.Sort((x, y) => x.TimePoint.CompareTo(y.TimePoint)); Entries.Sort((x, y) => x.TimePoint.CompareTo(y.TimePoint));
if (UpdateTarget == null) if (UpdateTarget == null)
{ {
@@ -76,9 +65,10 @@ namespace Demo.Game
public override IEnumerator UnloadScript() public override IEnumerator UnloadScript()
{ {
Content = 0; Content = 0;
Entries = new(); Entries.Clear();
yield return base.UnloadScript(); yield return base.UnloadScript();
} }
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType) protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
{ {
base.UpdateTicks(currentTime, deltaTime, tickType); base.UpdateTicks(currentTime, deltaTime, tickType);
@@ -140,16 +130,12 @@ namespace Demo.Game
/// <summary> /// <summary>
/// 设置更新对象 /// 设置更新对象
/// </summary> /// </summary>
/// <param name="path">脚本的相对路径</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetUpdateTarget(string path) public void SetUpdateTarget(ScriptableObject target)
{ {
var temp = FindWithPath(path); UpdateTarget = target.gameObject;
if (temp != null)
UpdateTarget = temp.gameObject;
else
Debug.LogWarning($"{path}' is not found", this);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -165,7 +151,6 @@ namespace Demo.Game
public interface ILocalUpdatement<DataType>: IScriptableObject public interface ILocalUpdatement<DataType>: IScriptableObject
{ {
int Content { get; set; } int Content { get; set; }
public List<ILocalUpdatementExtension.UpdatementEntry<DataType>> Entries { get; set; } public List<ILocalUpdatementExtension.UpdatementEntry<DataType>> Entries { get; set; }
void UpdateData(DataType data); void UpdateData(DataType data);
@@ -182,11 +167,11 @@ namespace Demo.Game
public MathExtension.EaseCurveType easeCurveType = MathExtension.EaseCurveType.Linear; public MathExtension.EaseCurveType easeCurveType = MathExtension.EaseCurveType.Linear;
} }
public static void AddEntry<DataType>(this ILocalUpdatement<DataType> self, string time, DataType position, MathExtension.EaseCurveType curveType) public static void AddEntry<DataType>(this ILocalUpdatement<DataType> self, float time, DataType position, MathExtension.EaseCurveType curveType)
{ {
self.Entries.Add(new() self.Entries.Add(new()
{ {
TimePoint = self.SharedInterfaceScriptObject.Parse(time), TimePoint = time,
Position = position, Position = position,
easeCurveType = curveType easeCurveType = curveType
}); });

View File

@@ -5,55 +5,40 @@ using UnityEngine;
namespace Demo.Game namespace Demo.Game
{ {
public class LookAtAnchor : Updatement<string> public class LookAtAnchor : Updatement<ScriptableObject>
{ {
public static LookAtAnchor Make() public static LookAtAnchor Make()
{ {
return new GameObject().AddComponent<LookAtAnchor>(); return new GameObject().AddComponent<LookAtAnchor>();
} }
protected override string Lerp(string begin, string end, float t) protected override ScriptableObject Lerp(ScriptableObject begin, ScriptableObject end, float t)
{ {
return begin; return begin;
} }
[Content, SerializeField] private string Cache;
[Content] public ScriptableObject LookAtObject; [Content] public ScriptableObject LookAtObject;
[Content] public bool IsEnableUpdateEveryTick = false; [Content] public bool IsEnableUpdateEveryTick = false;
protected override void UpdateData(string data) protected override void UpdateData(ScriptableObject data)
{ {
if (Cache != data) if (data != LookAtObject)
{ {
LookAtObject = FindWithPath(data, false); LookAtObject = data;
Cache = data; transform.LookAt(LookAtObject.transform);
Foo();
} }
if (IsEnableUpdateEveryTick) else if (IsEnableUpdateEveryTick)
{
Foo();
}
void Foo()
{ {
if (LookAtObject != null) if (LookAtObject != null)
transform.LookAt(LookAtObject.transform); transform.LookAt(LookAtObject.transform);
} }
} }
public override IEnumerator UnloadScript()
{
Cache = null;
yield return base.UnloadScript();
}
/// <summary> /// <summary>
/// 在指定时刻切换面向的物体,并尝试一次更新 /// 在指定时刻切换面向的物体,并尝试一次更新
/// </summary> /// </summary>
/// <param name="time"></param>
/// <param name="target">对象相对路径,不存在时将解除锁定</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, string target) public void Add(float time, ScriptableObject target)
{ {
ManualAddEntry(time, target, default); ManualAddEntry(time, target, default);
} }

View File

@@ -5,30 +5,30 @@ using UnityEngine;
namespace Demo.Game namespace Demo.Game
{ {
public class MaterialUpdatement : Updatement<string>, IAssetBundleLoader public class MaterialUpdatement : Updatement<Material>, IAssetBundleLoader
{ {
public static MaterialUpdatement Make() public static MaterialUpdatement Make()
{ {
return new GameObject().AddComponent<MaterialUpdatement>(); return new GameObject().AddComponent<MaterialUpdatement>();
} }
public string MaterialAssetBundlePath; public string MaterialAssetBundlePath = null;
public AssetBundle MaterialAssetBundle; public AssetBundle MaterialAssetBundle = null;
protected override string Lerp(string begin, string end, float t) protected override Material Lerp(Material begin, Material end, float t)
{ {
return begin; return begin;
} }
[Content, SerializeField] private string Cache; [Content, SerializeField] private Material Cache;
protected override void UpdateData(string data) protected override void UpdateData(Material data)
{ {
if (string.IsNullOrEmpty(MaterialAssetBundlePath)) if (string.IsNullOrEmpty(MaterialAssetBundlePath))
return; return;
if (Cache != data && Parent.TryGetComponent<MeshRenderer>(out var meshRenderer)) if (Cache != data && Parent.TryGetComponent<MeshRenderer>(out var meshRenderer))
{ {
meshRenderer.material = MaterialAssetBundle.LoadAsset<Material>(data); meshRenderer.material = data;
Cache = data; Cache = data;
} }
} }
@@ -38,7 +38,7 @@ namespace Demo.Game
Cache = null; Cache = null;
if (string.IsNullOrEmpty(MaterialAssetBundlePath) == false) if (string.IsNullOrEmpty(MaterialAssetBundlePath) == false)
yield return this.UnloadAssetBundle(MaterialAssetBundlePath); yield return this.UnloadAssetBundle(MaterialAssetBundlePath);
MaterialAssetBundlePath = ""; MaterialAssetBundlePath = null;
yield return base.UnloadScript(); yield return base.UnloadScript();
} }
@@ -59,12 +59,16 @@ namespace Demo.Game
/// <summary> /// <summary>
/// 在指定时刻切换父物体上的MeshRenderer.material /// 在指定时刻切换父物体上的MeshRenderer.material
/// </summary> /// </summary>
/// <param name="time"></param>
/// <param name="material"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, string material) public IEnumerator Add(float time, string material)
{ {
ManualAddEntry(time, material, default); var ir = MaterialAssetBundle.LoadAssetAsync<Material>(material);
ir.completed += x =>
{
var mat = ir.asset as Material;
ManualAddEntry(time, mat, default);
};
yield return ir;
} }
} }
} }

View File

@@ -22,12 +22,37 @@ namespace Demo.Game
public abstract class BasicSplineRenderer : Updatement<SplineClipDuration>, IAssetBundleLoader, IDependOnSplineCore public abstract class BasicSplineRenderer : Updatement<SplineClipDuration>, IAssetBundleLoader, IDependOnSplineCore
{ {
[Content] public SplineCore MySplineCore { get; set; } [Content] public SplineCore MySplineCore { get; set; }
[Content] public MeshRenderer MyMeshRenderer; [Content] private MeshFilter m_MeshFilter;
[Content] private MeshRenderer m_MyMeshRenderer;
[Header("LineRenderer.Material")] [Header("LineRenderer.Material")]
[Content] public string LinesAssetBundlePath; [Content] public string LinesAssetBundlePath;
[Content] public AssetBundle LinesAssetBundle; [Content] public AssetBundle LinesAssetBundle;
[Content] public string LineMaterial; [Content] public Material LineDefaultMaterial;
[Content] public Material MyLineMaterial;
public override void ResetEnterGameStatus()
{
base.ResetEnterGameStatus();
MyMeshRenderer.material = LineDefaultMaterial;
}
public MeshFilter MyMeshFilter
{
get
{
if (m_MeshFilter == null)
m_MeshFilter = this.GetOrAddComponent<MeshFilter>();
return m_MeshFilter;
}
}
public MeshRenderer MyMeshRenderer
{
get
{
if (m_MyMeshRenderer == null)
m_MyMeshRenderer = this.GetOrAddComponent<MeshRenderer>();
return m_MyMeshRenderer;
}
}
public abstract Vector3 EvaluateClipFromPosition(float time); public abstract Vector3 EvaluateClipFromPosition(float time);
@@ -37,26 +62,6 @@ namespace Demo.Game
public abstract SplineSample EvaluateClipTo(float time); public abstract SplineSample EvaluateClipTo(float time);
public override IEnumerator LoadScript(string script)
{
yield return base.LoadScript(script);
// Bind and Init Spline
var splineGameObject = MySplineCore.gameObject;
this.GetOrAddComponent<MeshFilter>();
MyMeshRenderer = this.GetOrAddComponent<MeshRenderer>();
MyMeshRenderer.enabled = true;
if (string.IsNullOrEmpty(LinesAssetBundlePath) == false)
{
var ir = LinesAssetBundle.LoadAssetAsync<Material>(LineMaterial);
ir.completed += x =>
{
MyLineMaterial = ir.asset as Material;
};
yield return ir;
}
MyMeshRenderer.material = MyLineMaterial;
}
public override IEnumerator UnloadScript() public override IEnumerator UnloadScript()
{ {
if (string.IsNullOrEmpty(LinesAssetBundlePath) == false) if (string.IsNullOrEmpty(LinesAssetBundlePath) == false)
@@ -73,15 +78,15 @@ namespace Demo.Game
/// <param name="to"></param> /// <param name="to"></param>
/// <param name="curveType">可取值为30种缓动曲线</param> /// <param name="curveType">可取值为30种缓动曲线</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, float from, float to, string curveType) public void Add(float time, float from, float to, string curveType)
{ {
ManualAddEntry(time, new(from, to), Enum.Parse<MathExtension.EaseCurveType>(curveType)); ManualAddEntry(time, new(from, to), Enum.Parse<MathExtension.EaseCurveType>(curveType));
} }
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public IEnumerator LoadSpline(string path) public void LoadSpline(string path)
{ {
yield return this.LoadSplineTool(path); this.LoadSplineTool(path);
} }
@@ -97,13 +102,14 @@ namespace Demo.Game
/// <param name="ab"></param> /// <param name="ab"></param>
/// <param name="material"></param> /// <param name="material"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public IEnumerator LoadMaterial(string ab, string material) public void LoadMaterial(string ab, string material)
{
yield return this.LoadAssetBundle(ab, x =>
{ {
MyMeshRenderer.enabled = true;
LinesAssetBundlePath = ab; LinesAssetBundlePath = ab;
this.LoadAssetBundle(ab, x =>
{
LinesAssetBundle = x; LinesAssetBundle = x;
LineMaterial = material; LineDefaultMaterial = LinesAssetBundle.LoadAsset<Material>(material);
}); });
} }
@@ -117,11 +123,9 @@ namespace Demo.Game
{ {
[Content] public TMeshGenerator MyMeshGenerator; [Content] public TMeshGenerator MyMeshGenerator;
public override IEnumerator LoadScript(string script) protected override IEnumerator DoSomethingDuringApplyScript()
{ {
yield return base.LoadScript(script); yield return base.DoSomethingDuringApplyScript();
// Setup Mesh Generater
MyMeshRenderer.material = MyLineMaterial;
MyMeshGenerator = this.GetOrAddComponent<TMeshGenerator>(); MyMeshGenerator = this.GetOrAddComponent<TMeshGenerator>();
MyMeshGenerator.spline = MySplineCore.MySplineComputer; MyMeshGenerator.spline = MySplineCore.MySplineComputer;
SetupMeshGenerator(MyMeshGenerator); SetupMeshGenerator(MyMeshGenerator);
@@ -142,9 +146,9 @@ namespace Demo.Game
/// </summary> /// </summary>
/// <param name="mode">Clip, UniformClip, Clamp, UniformClamp</param> /// <param name="mode">Clip, UniformClip, Clamp, UniformClamp</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetUVMode(string mode) public void SetUVMode(MeshGenerator.UVMode mode)
{ {
MyUVMode = Enum.Parse<MeshGenerator.UVMode>(mode); MyUVMode = mode;
} }
#endregion #endregion

View File

@@ -27,37 +27,37 @@ namespace Demo.Game
/// </summary> /// </summary>
/// <param name="path">对象路径, 不存在时则立刻加载</param> /// <param name="path">对象路径, 不存在时则立刻加载</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public IEnumerator LoadSpline(string path) public void LoadSpline(string path)
{ {
yield return this.LoadSplineTool(path); this.LoadSplineTool(path);
} }
/// <summary> /// <summary>
/// 必须先执行LoadSpline加载样条线 /// 必须先执行LoadSpline加载样条线
/// </summary> /// </summary>
/// <param name="value">百分比所在位置,取值范围是[01]</param> /// <param name="offset">百分比所在位置,取值范围是[01]</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void EvaluatePosition(string value) public void EvaluatePosition(float offset)
{ {
MySplineOffset = Parse(value); MySplineOffset = offset;
Updater = () => transform.position = MySplineCore.MySplineComputer.EvaluatePosition(MySplineOffset); Updater = () => transform.position = MySplineCore.MySplineComputer.EvaluatePosition(MySplineOffset);
} }
/// <summary> /// <summary>
/// 绑定到样条线渲染器上(必须已经加载), /// 绑定到样条线渲染器上
/// 并设置跟随指定时间的时刻渲染器所生成的头部 /// 并设置跟随指定时间的时刻渲染器所生成的头部
/// </summary> /// </summary>
/// <param name="path">对象路径, 不存在时则立刻加载</param> /// <param name="splineRenderer">样条线渲染器对象</param>
/// <param name="time">时刻</param> /// <param name="time">时刻</param>
/// <param name="isFollowPosition">是否跟随位置, 默认开启</param> /// <param name="isFollowPosition">是否跟随位置, 默认开启</param>
/// <param name="isFollowRotation">是否跟随旋转, 默认开启</param> /// <param name="isFollowRotation">是否跟随旋转, 默认开启</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void LoadSplineRenderer(string path, string time, string isFollowPosition = "true", string isFollowRotation = "true") public void LoadSplineRenderer(BasicSplineRenderer splineRenderer, float time, bool isFollowPosition = true, bool isFollowRotation = true)
{ {
MySplineRenderer = this.LoadSplineRendererTool(path); MySplineRenderer = splineRenderer;
MySplineOffset = Parse(time); MySplineOffset = time;
bool bIsFollowPosition = ConvertValue<bool>(isFollowPosition); bool bIsFollowPosition = isFollowPosition;
bool bIsFollowRotation = ConvertValue<bool>(isFollowRotation); bool bIsFollowRotation = isFollowRotation;
if (bIsFollowPosition && bIsFollowRotation) if (bIsFollowPosition && bIsFollowRotation)
{ {
Updater = () => Updater = () =>

View File

@@ -22,7 +22,7 @@ namespace Demo.Game
public interface IDependOnSplineCore : IScriptableObject public interface IDependOnSplineCore : IScriptableObject
{ {
SplineCore MySplineCore { get; set; } SplineCore MySplineCore { get; set; }
IEnumerator LoadSpline(string path); void LoadSpline(string path);
} }
public static class DependOnSplineCoreUtility public static class DependOnSplineCoreUtility
@@ -38,19 +38,13 @@ namespace Demo.Game
/// 加载并绑定到新样条线 /// 加载并绑定到新样条线
/// </summary> /// </summary>
/// <param name="path">对象相对路径,若对象不存在则作为脚本相对路径加载</param> /// <param name="path">对象相对路径,若对象不存在则作为脚本相对路径加载</param>
public static IEnumerator LoadSplineTool(this IDependOnSplineCore self, string path) public static SplineCore LoadSplineTool(this IDependOnSplineCore self, string path)
{ {
var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false); var spline = self.SharedInterfaceScriptObject.FindWithPath(path, false);
if (spline == null) if (spline == null)
yield return self.SharedInterfaceScriptObject.DoLoadSubScriptAsync(nameof(SplineCore), path, x => spline = x); spline = self.SharedInterfaceScriptObject.NewSubScript(nameof(SplineCore), new ToolFile(path).GetFilename(true), path);
if (spline is SplineCore sc) self.MySplineCore = (SplineCore)spline;
{ return self.MySplineCore;
self.MySplineCore = sc;
}
else
{
Debug.LogWarning($"{path} is not a SplineCore", self.SharedInterfaceScriptObject);
}
} }
} }
@@ -61,18 +55,31 @@ namespace Demo.Game
return new GameObject("", typeof(SplineComputer)).AddComponent<SplineCore>(); return new GameObject("", typeof(SplineComputer)).AddComponent<SplineCore>();
} }
[Content] public SplineComputer MySplineComputer; [Content] private SplineComputer m_MySplineComputer;
[Content] public int NodeContent = 0; [Content] public int NodeContent = 0;
[Content] public List<SplineNode> MySplineNodes = new(); [Content] public readonly List<SplineNode> MySplineNodes = new();
[Content] public SplineComputer.SampleMode MySampleMode = default; [Content] public SplineComputer.SampleMode MySampleMode = default;
[Content] public Spline.Type MyType = default; [Content] public Spline.Type MyType = default;
public bool IsClose = false; public bool IsClose = false;
public override IEnumerator LoadScript(string script) public SplineComputer MySplineComputer
{ {
MySplineComputer = GetComponent<SplineComputer>(); get
yield return base.LoadScript(script); {
if(m_MySplineComputer==null)
m_MySplineComputer= 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; NodeContent = 0;
MySplineComputer.SetPoints(new SplinePoint[MySplineNodes.Count]); MySplineComputer.SetPoints(new SplinePoint[MySplineNodes.Count]);
foreach (SplineNode node in MySplineNodes) foreach (SplineNode node in MySplineNodes)
@@ -86,13 +93,12 @@ namespace Demo.Game
MySplineComputer.Break(); MySplineComputer.Break();
MySplineComputer.sampleMode = MySampleMode; MySplineComputer.sampleMode = MySampleMode;
MySplineComputer.type = MyType; MySplineComputer.type = MyType;
yield return null;
MySplineComputer.Rebuild(); MySplineComputer.Rebuild();
} }
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType) protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
{ {
if (tickType == TickType.Start || tickType == TickType.Reset) if (tickType != TickType.Update)
MySplineComputer.Rebuild(); MySplineComputer.Rebuild();
} }
@@ -109,9 +115,9 @@ namespace Demo.Game
/// </summary> /// </summary>
/// <param name="mode">CatmullRom, BSpline, Bezier, Linear </param> /// <param name="mode">CatmullRom, BSpline, Bezier, Linear </param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetType(string mode) public void SetType(Spline.Type mode)
{ {
MyType = Enum.Parse<Spline.Type>(mode); MyType = mode;
} }
/// <summary> /// <summary>
@@ -119,9 +125,9 @@ namespace Demo.Game
/// </summary> /// </summary>
/// <param name="mode">Default, Uniform, Optimized</param> /// <param name="mode">Default, Uniform, Optimized</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetSampleMode(string mode) public void SetSampleMode(SplineComputer.SampleMode mode)
{ {
MySampleMode = Enum.Parse<SplineComputer.SampleMode>(mode); MySampleMode = mode;
} }
@@ -135,47 +141,13 @@ namespace Demo.Game
} }
/// <summary> /// <summary>
/// 加载并加入节点 /// 加入节点或者添加节点组件后加入节点
/// </summary> /// </summary>
/// <param name="path">脚本位置</param> /// <param name="path">脚本位置</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public IEnumerator LoadNode(string path) public void LoadNode(ScriptableObject node)
{
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>
/// 加入节点脚本对象
/// </summary>
[Convention.RScript.Variable.Attr.Method]
public void AddNode(ScriptableObject node)
{ {
MySplineNodes.Add(node.GetOrAddComponent<SplineNode>()); MySplineNodes.Add(node.GetOrAddComponent<SplineNode>());
} }
/// <summary>
/// 加入已加载的节点如果目标脚本不是SplineNode
/// 那么为其添加SplineNode组件
/// </summary>
/// <param name="path">脚本位置</param>
[Convention.RScript.Variable.Attr.Method]
public void AddNode(string path)
{
var node = FindWithPath(path);
if (node != null)
{
AddNode(node);
}
}
} }
} }

View File

@@ -11,17 +11,22 @@ namespace Demo.Game
return new GameObject("", typeof(Node)).AddComponent<SplineNode>(); return new GameObject("", typeof(Node)).AddComponent<SplineNode>();
} }
public Node MyNode; private Node m_MyNode;
public float NodeSize = 1; public float NodeSize = 1;
public Color NodeColor = Color.white; public Color NodeColor = Color.white;
public bool IsSetupNodeRotation = false; public bool IsSetupNodeRotation = false;
public Vector3 NodeRotation = Vector3.zero; public Vector3 NodeRotation = Vector3.zero;
public int MyNodeContent = 0; public int MyNodeContent = 0;
public override IEnumerator LoadScript(string script)
public Node MyNode
{ {
MyNode = GetComponent<Node>(); get
yield return base.LoadScript(script); {
if (m_MyNode == null)
m_MyNode = GetComponent<Node>();
return m_MyNode;
}
} }
public void AddTo(SplineCore core) public void AddTo(SplineCore core)
@@ -38,9 +43,9 @@ namespace Demo.Game
/// </summary> /// </summary>
/// <param name="size"></param> /// <param name="size"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetNodeSize(string size) public void SetNodeSize(float size)
{ {
NodeSize = Parse(size); NodeSize = size;
} }
/// <summary> /// <summary>
@@ -51,9 +56,9 @@ namespace Demo.Game
/// <param name="b"></param> /// <param name="b"></param>
/// <param name="a"></param> /// <param name="a"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetNodeColor(string r, string g, string b, string a) public void SetNodeColor(float r, float g, float b, float a)
{ {
NodeColor = new(Parse(r), Parse(g), Parse(b), Parse(a)); NodeColor = new(r, g, b, a);
} }
/// <summary> /// <summary>
@@ -63,10 +68,10 @@ namespace Demo.Game
/// <param name="y"></param> /// <param name="y"></param>
/// <param name="z"></param> /// <param name="z"></param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void SetNodeRotation(string x, string y, string z) public void SetNodeRotation(float x, float y, float z)
{ {
IsSetupNodeRotation = true; IsSetupNodeRotation = true;
this.transform.localEulerAngles = NodeRotation = new(Parse(x), Parse(y), Parse(z)); this.transform.localEulerAngles = NodeRotation = new(x, y, z);
} }
} }
} }

View File

@@ -31,13 +31,11 @@ namespace Demo.Game
/// <param name="x">x</param> /// <param name="x">x</param>
/// <param name="y">y</param> /// <param name="y">y</param>
/// <param name="z">z</param> /// <param name="z">z</param>
/// <param name="curveType">可取值为30种缓动曲线</param> /// <param name="curveType">缓动曲线</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, string x, string y, string z, string curveType) public void Add(float time, float x, float y, float z, MathExtension.EaseCurveType curveType)
{ {
ManualAddEntry(time, ManualAddEntry(time, new(x, y, z), curveType);
new(float.Parse(x), float.Parse(y), float.Parse(z)),
Enum.Parse<MathExtension.EaseCurveType>(curveType));
} }
} }
} }

View File

@@ -28,13 +28,11 @@ namespace Demo.Game
/// <param name="x">x</param> /// <param name="x">x</param>
/// <param name="y">y</param> /// <param name="y">y</param>
/// <param name="z">z</param> /// <param name="z">z</param>
/// <param name="curveType">可取值为30种缓动曲线</param> /// <param name="curveType">缓动曲线</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, string x, string y, string z, string curveType) public void Add(float time, float x, float y, float z, MathExtension.EaseCurveType curveType)
{ {
ManualAddEntry(time, ManualAddEntry(time, new(x, y, z), curveType);
new(float.Parse(x), float.Parse(y), float.Parse(z)),
Enum.Parse<MathExtension.EaseCurveType>(curveType));
} }
} }
} }

View File

@@ -28,13 +28,11 @@ namespace Demo.Game
/// <param name="x">x</param> /// <param name="x">x</param>
/// <param name="y">y</param> /// <param name="y">y</param>
/// <param name="z">z</param> /// <param name="z">z</param>
/// <param name="curveType">可取值为30种缓动曲线</param> /// <param name="curveType">缓动曲线</param>
[Convention.RScript.Variable.Attr.Method] [Convention.RScript.Variable.Attr.Method]
public void Add(string time, string x, string y, string z, string curveType) public void Add(float time, float x, float y, float z, MathExtension.EaseCurveType curveType)
{ {
ManualAddEntry(time, ManualAddEntry(time, new(x, y, z), curveType);
new(float.Parse(x), float.Parse(y), float.Parse(z)),
Enum.Parse<MathExtension.EaseCurveType>(curveType));
} }
} }
} }