推进同化RScript
This commit is contained in:
@@ -30,11 +30,6 @@ namespace Demo.Game
|
||||
VirtualCamera = GetComponent<CinemachineVirtualCamera>();
|
||||
}
|
||||
|
||||
public override IEnumerator LoadScript(string script)
|
||||
{
|
||||
yield return base.LoadScript(script);
|
||||
}
|
||||
|
||||
public override IEnumerator UnloadScript()
|
||||
{
|
||||
yield return base.UnloadScript();
|
||||
@@ -44,89 +39,73 @@ namespace Demo.Game
|
||||
/// <summary>
|
||||
/// 设置是否为正交相机
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[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>
|
||||
/// <param name="arg"></param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetFieldOfView(string arg)
|
||||
public void SetFieldOfView(float fieldOfView)
|
||||
{
|
||||
MainCamera.fieldOfView = Parse(arg);
|
||||
MainCamera.fieldOfView = fieldOfView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置正交相机的尺寸
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetOrthographicSize(string arg)
|
||||
public void SetOrthographicSize(float orthographicSize)
|
||||
{
|
||||
MainCamera.orthographicSize = Parse(arg);
|
||||
MainCamera.orthographicSize = orthographicSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置近裁剪面距离
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetNearClipPlane(string arg)
|
||||
public void SetNearClipPlane(float nearClipPlane)
|
||||
{
|
||||
MainCamera.nearClipPlane = Parse(arg);
|
||||
MainCamera.nearClipPlane = nearClipPlane;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置远裁剪面距离
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetFarClipPlane(string arg)
|
||||
public void SetFarClipPlane(float farClipPlane)
|
||||
{
|
||||
MainCamera.farClipPlane = Parse(arg);
|
||||
MainCamera.farClipPlane = farClipPlane;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置相机深度
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetDepth(string arg)
|
||||
public void SetDepth(float depth)
|
||||
{
|
||||
MainCamera.depth = Parse(arg);
|
||||
MainCamera.depth = depth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置虚拟相机跟随目标
|
||||
/// </summary>
|
||||
/// <param name="targetName">对象相对路径</param>
|
||||
[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>
|
||||
/// <param name="targetName">对象相对路径</param>
|
||||
[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>
|
||||
@@ -136,16 +115,12 @@ namespace Demo.Game
|
||||
/// <param name="y">Y轴偏移</param>
|
||||
/// <param name="z">Z轴偏移</param>
|
||||
[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>();
|
||||
if (body != null)
|
||||
{
|
||||
body.m_FollowOffset = new Vector3(
|
||||
Parse(x),
|
||||
Parse(y),
|
||||
Parse(z)
|
||||
);
|
||||
body.m_FollowOffset = new Vector3(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,14 +131,14 @@ namespace Demo.Game
|
||||
/// <param name="y">Y轴阻尼</param>
|
||||
/// <param name="z">Z轴阻尼</param>
|
||||
[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>();
|
||||
if (body != null)
|
||||
{
|
||||
body.m_XDamping = Parse(x);
|
||||
body.m_YDamping = Parse(y);
|
||||
body.m_ZDamping = Parse(z);
|
||||
body.m_XDamping = x;
|
||||
body.m_YDamping = y;
|
||||
body.m_ZDamping = z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,13 +149,13 @@ namespace Demo.Game
|
||||
/// <param name="y">Y轴阻尼</param>
|
||||
/// <param name="z">Z轴阻尼</param>
|
||||
[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>();
|
||||
if (aim != null)
|
||||
{
|
||||
aim.m_HorizontalDamping = Parse(x);
|
||||
aim.m_VerticalDamping = Parse(y);
|
||||
aim.m_HorizontalDamping = x;
|
||||
aim.m_VerticalDamping = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace Demo.Game
|
||||
{
|
||||
public class DDT : ScriptableObject
|
||||
{
|
||||
public string BindingDataJson => $"{ScriptPath}.json";
|
||||
|
||||
public static DDT Make()
|
||||
{
|
||||
return new GameObject().AddComponent<DDT>();
|
||||
@@ -15,12 +13,6 @@ namespace Demo.Game
|
||||
|
||||
public List<float> Datas = new();
|
||||
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void Add(string value)
|
||||
{
|
||||
Datas.Add(Parse(value));
|
||||
}
|
||||
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void Add(float value)
|
||||
{
|
||||
@@ -32,28 +24,5 @@ namespace Demo.Game
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,10 +205,11 @@ namespace Demo.Game
|
||||
rootGameObject.transform.SetParent(transform);
|
||||
rootGameObject.ScriptName = rootObject.GetName(true);
|
||||
rootGameObject.audioSystem = MainAudio;
|
||||
rootGameObject.EnableScript(content.RootSourceDir, rootObject.GetFullPath(), this);
|
||||
rootGameObject.EnableScript(content.RootSourceDir, this);
|
||||
try
|
||||
{
|
||||
yield return rootGameObject.LoadScript(rootObject.LoadAsText());
|
||||
yield return rootGameObject.ParseScript2Expr(rootObject.LoadAsText());
|
||||
yield return rootGameObject.ApplyScript();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Convention;
|
||||
using Convention.WindowsUI.Variant;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Convention;
|
||||
using Convention.VFX;
|
||||
using Convention.WindowsUI.Variant;
|
||||
using Demo.Editor.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
@@ -16,19 +14,15 @@ namespace Demo.Game
|
||||
|
||||
[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);
|
||||
if (RootGameController.IsMain)
|
||||
{
|
||||
yield return base.LoadScript(script);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Start);
|
||||
if (RootGameController.IsMain)
|
||||
{
|
||||
Keyboard.current.onTextInput += InputCatchChar;
|
||||
}
|
||||
Keyboard.current.onTextInput += InputCatchChar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,14 +35,15 @@ namespace Demo.Game
|
||||
yield return base.UnloadScript();
|
||||
}
|
||||
|
||||
public void EnableScript(string sourcePath, string scriptPath, GameController parent)
|
||||
public void EnableScript(string sourcePath, GameController parent)
|
||||
{
|
||||
AllScriptableObjectCounter = 0;
|
||||
if (AllScriptableObjectCounterHierarchyItem == null)
|
||||
{
|
||||
AllScriptableObjectCounterHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(typeof(ScriptableObject))[0];
|
||||
}
|
||||
base.EnableScript(sourcePath, scriptPath, nameof(RootObject), null);
|
||||
SourcePath = sourcePath;
|
||||
base.EnableScript(null);
|
||||
RootGameController = parent;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
using Convention;
|
||||
using Convention.RScript;
|
||||
using Convention.WindowsUI.Variant;
|
||||
using Demo.Game;
|
||||
using Flee.PublicTypes;
|
||||
using Sirenix.OdinInspector;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,35 +12,11 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Convention;
|
||||
using Convention.RScript;
|
||||
using Convention.WindowsUI.Variant;
|
||||
using Demo.Game;
|
||||
using Flee.PublicTypes;
|
||||
using Sirenix.OdinInspector;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Demo
|
||||
{
|
||||
public static class ScriptUtility
|
||||
{
|
||||
public static void OpenScriptFile(ScriptableObject so)
|
||||
{
|
||||
string path = so.ScriptPath;
|
||||
var ScriptEditor = so.GetRoot().RootGameController.WhichOpenScript;
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process.Start(string.Format($"{ScriptEditor}", $"\"{path}\""));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Cannt open {path}: {string.Format($"{ScriptEditor}", $"\"{path}\"")}", so);
|
||||
Debug.LogException(ex, so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IScriptableObject
|
||||
{
|
||||
ScriptableObject SharedInterfaceScriptObject { get; }
|
||||
@@ -50,191 +32,8 @@ namespace Demo
|
||||
public ScriptableObject SharedInterfaceScriptObject => this;
|
||||
}
|
||||
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
// 时间点系统
|
||||
|
||||
public static Dictionary<string, float> TimePointDelta = new();
|
||||
public static Dictionary<string, float> TimePoints = new();
|
||||
|
||||
/// <summary>
|
||||
/// 重设指定时间线
|
||||
/// </summary>
|
||||
/// <param name="id">时间线ID,若不存在则创建</param>
|
||||
/// <param name="delta">当每次调用NextTimePoint函数时使用的单位值</param>
|
||||
/// <param name="value">初始化时间</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void ResetTimePoint(string id, float delta, float value)
|
||||
{
|
||||
TimePointDelta[id] = delta;
|
||||
TimePoints[id] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推动时间线前进
|
||||
/// </summary>
|
||||
/// <param name="id">时间线ID</param>
|
||||
/// <param name="times">前进次数,最终时间的增量为前进次数乘该时间线的单位值</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void NextTimePoint(string id, float times)
|
||||
{
|
||||
TimePoints[id] += TimePointDelta[id] * times;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置时间线的值
|
||||
/// </summary>
|
||||
/// <param name="id">时间线ID</param>
|
||||
/// <param name="value">次数,时间线的值将被设置为次数乘该时间线的单位值</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetTimePoint(string id, float value)
|
||||
{
|
||||
TimePoints[id] = TimePointDelta[id] * value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上下文系统
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
[Content] public Dictionary<string, float> ScriptContextSpace = new();
|
||||
|
||||
public bool GetCompleteScriptContext(string key, out float value)
|
||||
{
|
||||
if (ScriptContextSpace.TryGetValue(key, out value) == false)
|
||||
{
|
||||
if (Parent == null)
|
||||
return false;
|
||||
return Parent.GetCompleteScriptContext(key, out value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GetCompleteScriptContext(ref Dictionary<string, float> context)
|
||||
{
|
||||
var current = this;
|
||||
while (current != null)
|
||||
{
|
||||
foreach (var key in current.ScriptContextSpace.Keys)
|
||||
{
|
||||
context[key] = current.ScriptContextSpace[key];
|
||||
}
|
||||
current = current.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置局部上下文变量,将会传递给子物体使用
|
||||
/// </summary>
|
||||
/// <param name="name">字符串</param>
|
||||
/// <param name="value">浮点数</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetContext(string name, float value)
|
||||
{
|
||||
ScriptContextSpace[name] = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数值解析工具
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
private ExpressionContext ExpressionParserCreater()
|
||||
{
|
||||
ExpressionContext context = new();
|
||||
context.Imports.AddType(typeof(Mathf));
|
||||
Dictionary<string, float> vars = new();
|
||||
GetCompleteScriptContext(ref vars);
|
||||
foreach (var item in vars)
|
||||
{
|
||||
context.Variables[item.Key] = item.Value;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
public static float OneBarTime = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 从字符串解析为浮点数
|
||||
/// <list type="bullet">从时间点列表<see cref="TimePoints"/>中获取</list>
|
||||
/// <list type="bullet">或是从上下文变量<see cref="GetCompleteScriptContext"/>中获取</list>
|
||||
/// <list type="bullet">或是从数据驱动对象<see cref="DDT"/>中获取</list>
|
||||
/// <list type="bullet">或是通过计算表达式值获取</list>
|
||||
/// <list type="bullet">或是直接调用<see cref="float.Parse(string)"/></list>
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public float Parse(string value)
|
||||
{
|
||||
value = value.Trim();
|
||||
if(value.StartsWith("\"")&&value.EndsWith("\""))
|
||||
{
|
||||
value = value[1..^1];
|
||||
}
|
||||
if (TimePoints.TryGetValue(value, out var result))
|
||||
return result;
|
||||
if (GetCompleteScriptContext(value, out result))
|
||||
return result;
|
||||
if(value.EndsWith(']'))
|
||||
{
|
||||
{
|
||||
Regex regex = new(@"^(.+)\[(.+)\]$");
|
||||
var match = regex.Match(value);
|
||||
if (match.Success)
|
||||
{
|
||||
return (FindWithPath(match.Groups[1].Value) as DDT).Datas[(int)this.Parse(match.Groups[2].Value)];
|
||||
}
|
||||
}
|
||||
{
|
||||
Regex regex = new(@"^(.+)\[\]$");
|
||||
var match = regex.Match(value);
|
||||
if (match.Success)
|
||||
{
|
||||
return (FindWithPath(match.Groups[1].Value) as DDT).Datas.Count;
|
||||
}
|
||||
}
|
||||
throw new ArgumentException("value is end by ']' but not match on any invlid parse");
|
||||
}
|
||||
if (value.EndsWith('}'))
|
||||
{
|
||||
{
|
||||
Regex regex = new(@"^\{\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\}$");
|
||||
var match = regex.Match(value);
|
||||
if (match.Success)
|
||||
{
|
||||
int barSplitTimes = int.Parse(match.Groups[1].Value);
|
||||
int barCount = int.Parse(match.Groups[2].Value);
|
||||
int tickCount = int.Parse(match.Groups[3].Value);
|
||||
return (barCount + tickCount / (float)barSplitTimes) * OneBarTime;
|
||||
}
|
||||
}
|
||||
throw new ArgumentException("value is end by '}' but not match on any invlid parse");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (float.TryParse(value, out var _result))
|
||||
return _result;
|
||||
else
|
||||
return ExpressionParserCreater().CompileGeneric<float>(value).Evaluate();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new FormatException($"{value} is not support any Parser", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected T ConvertValue<T>(string str)
|
||||
{
|
||||
return ConventionUtility.convert_xvalue<T>(str);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 先天支持的工具函数
|
||||
/// 初始化与对象设置
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
@@ -243,6 +42,7 @@ namespace Demo
|
||||
EnterGameEulerAngles = Vector3.zero,
|
||||
EnterGameLocalScaling = Vector3.one;
|
||||
[Content, SerializeField] private bool IsSetObjectDisable = false;
|
||||
[Content] public int UpdatePerFrame = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 设置坐标
|
||||
@@ -288,25 +88,6 @@ namespace Demo
|
||||
IsSetObjectDisable = true;
|
||||
}
|
||||
|
||||
private void ResetScriptableObjectEnterGameStatus()
|
||||
{
|
||||
transform.localPosition = EnterGameLocalPosition;
|
||||
transform.localEulerAngles = EnterGameEulerAngles;
|
||||
transform.localScale = EnterGameLocalScaling;
|
||||
if (IsSetObjectDisable)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UpdatePerFrame相关
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
[Content] public int UpdatePerFrame = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 指定多少个<see cref="TickType.Update"/>状态的<see cref="UpdateTicks(float, float, TickType)"/>执行一次更新,不会影响到子物体
|
||||
/// 属于性能优化的高级选项
|
||||
@@ -317,26 +98,144 @@ namespace Demo
|
||||
{
|
||||
UpdatePerFrame = Mathf.Max(1, frame);
|
||||
}
|
||||
|
||||
private void ScriptableObjectDoReset()
|
||||
{
|
||||
transform.localPosition = EnterGameLocalPosition;
|
||||
transform.localEulerAngles = EnterGameEulerAngles;
|
||||
transform.localScale = EnterGameLocalScaling;
|
||||
gameObject.SetActive(IsSetObjectDisable == false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EnableScript相关
|
||||
/// 跨脚本上下文变量
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
public Dictionary<string, object> ScriptableObjectContents = new();
|
||||
|
||||
public object GetContent(string key)
|
||||
{
|
||||
if (ScriptableObjectContents.TryGetValue(key, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (Parent != null)
|
||||
{
|
||||
return Parent.GetContent(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetContent(string key, object value)
|
||||
{
|
||||
ScriptableObjectContents[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基础信息, 父子关系与EnableScript
|
||||
/// </summary>
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
public static bool IsAutoPlay = false;
|
||||
public static float OneBarTime = 60;
|
||||
|
||||
private bool isEnableScript = false;
|
||||
|
||||
public string SourcePath = "";
|
||||
public string ScriptName = "";
|
||||
public string ScriptPath;
|
||||
public string ScriptTypename;
|
||||
|
||||
// Hierarchy
|
||||
public ScriptableObject Parent;
|
||||
public List<ScriptableObject> Childs = new();
|
||||
|
||||
public PropertiesWindow.ItemEntry MyHierarchyItem;
|
||||
public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem;
|
||||
/// <summary>
|
||||
/// 获取根脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public RootObject GetRoot()
|
||||
{
|
||||
if (Parent == null)
|
||||
return this as RootObject;
|
||||
if (Parent is RootObject result)
|
||||
return result;
|
||||
else
|
||||
return Parent.GetRoot();
|
||||
}
|
||||
|
||||
public void EnableScript(string sourcePath, string scriptPath, string scriptType, ScriptableObject parent)
|
||||
|
||||
public const string RootObjectQuickPath = "project/";
|
||||
|
||||
public ScriptableObject FindWithPath(string path, bool isMustExist = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (isMustExist)
|
||||
throw new Exception("path is null or empty");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// GetParent
|
||||
ScriptableObject result = Parent;
|
||||
if (path.Replace('\\', '/').ToLower().StartsWith(RootObjectQuickPath))
|
||||
{
|
||||
result = GetRoot();
|
||||
path = path[RootObjectQuickPath.Length..];
|
||||
}
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Root is nosupport to {nameof(FindWithPath)}");
|
||||
}
|
||||
|
||||
// Find
|
||||
var components = path.Split('/', '\\');
|
||||
components[^1] = new ToolFile(components[^1]).GetFilename(true);
|
||||
foreach (var component in components)
|
||||
{
|
||||
if (component == "..")
|
||||
result = result.Parent;
|
||||
else if (component == "." || string.IsNullOrEmpty(component))
|
||||
continue;
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
string targetScriptObjectPath = component;
|
||||
Regex regex = new(@"^(.*)\[(\d*)\]$");
|
||||
var match = regex.Match(component);
|
||||
if (match.Success)
|
||||
{
|
||||
targetScriptObjectPath = match.Groups[1].Value;
|
||||
index = int.Parse(match.Groups[2].Value);
|
||||
}
|
||||
var target = result.Childs.FirstOrDefault(x =>
|
||||
{
|
||||
bool stats = x.ScriptName == targetScriptObjectPath;
|
||||
if (index == 0)
|
||||
return stats;
|
||||
else if (stats)
|
||||
index--;
|
||||
return false;
|
||||
});
|
||||
if (target != null)
|
||||
result = target;
|
||||
else
|
||||
{
|
||||
if (isMustExist)
|
||||
throw new Exception($"{component} in {path} is not found");
|
||||
else
|
||||
{
|
||||
Debug.Log($"{component} in {path} is not found", this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void EnableScript(ScriptableObject parent)
|
||||
{
|
||||
#if UNITY_EDITOR||Using_ProfilerMarker
|
||||
s_PreparePerfMarker = new(ScriptName);
|
||||
@@ -346,9 +245,6 @@ namespace Demo
|
||||
Debug.LogError($"ScriptableObject is currently enableScript, start coroutine {nameof(UnloadScript)} to disable", this);
|
||||
return;
|
||||
}
|
||||
this.SourcePath = sourcePath;
|
||||
this.ScriptPath = scriptPath;
|
||||
this.ScriptTypename = scriptType;
|
||||
this.Parent = parent;
|
||||
|
||||
this.name = ScriptName;
|
||||
@@ -363,14 +259,16 @@ namespace Demo
|
||||
{
|
||||
MyHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(1)[0];
|
||||
}
|
||||
MyHierarchyItem.GetHierarchyItem().title = this.ScriptName + $"<{scriptType}>";
|
||||
MyHierarchyItem.GetHierarchyItem().title = this.ScriptName + $"<{this.GetType()}>";
|
||||
MyHierarchyItem.GetHierarchyItem().target = this;
|
||||
MyHierarchyItem.GetHierarchyItem().ButtonGameObject.GetComponent<Editor.UI.RightClick>().ScriptObjectMenu = OnHierarchyItemRightClick;
|
||||
//var parentHierarchyItem = MyHierarchyItem.GetParent();
|
||||
//if (parentHierarchyItem != null)
|
||||
// parentHierarchyItem.GetPropertyListItem().RefreshChilds();
|
||||
}
|
||||
|
||||
#region Hierarchy
|
||||
|
||||
public PropertiesWindow.ItemEntry MyHierarchyItem;
|
||||
public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem;
|
||||
|
||||
public bool EnsureEnableScript()
|
||||
{
|
||||
if (isEnableScript == false)
|
||||
@@ -379,6 +277,8 @@ namespace Demo
|
||||
}
|
||||
return isEnableScript;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -396,115 +296,55 @@ namespace Demo
|
||||
|
||||
#region LoadSubScript
|
||||
|
||||
private static ScriptableObject LastLoadedScriptableObject;
|
||||
|
||||
public IEnumerator DoLoadSubScriptAsync([In] string type, [In] string path, [Opt] Action<ScriptableObject> callback)
|
||||
{
|
||||
// 判断类型是否合法
|
||||
if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false)
|
||||
{
|
||||
Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this);
|
||||
callback?.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
// 生成对象
|
||||
var child = creater();
|
||||
// 路径预处理
|
||||
if (path.Replace('\\', '/').ToLower().StartsWith(RootObjectQuickPath))
|
||||
path = $"{new ToolFile(GetRoot().SourcePath) | path[RootObjectQuickPath.Length..]}";
|
||||
// 获取文件
|
||||
ToolFile file;
|
||||
if (File.Exists(path))
|
||||
file = new(path);
|
||||
else
|
||||
file = new ToolFile(SourcePath) | path;
|
||||
// 找不到脚本
|
||||
if (file.Exists() == false)
|
||||
{
|
||||
Debug.LogError($"{file}<{path}> is not found", this);
|
||||
callback?.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
child.ScriptName = file.GetName(true);
|
||||
child.transform.SetParent(this.transform);
|
||||
child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
child.transform.localScale = Vector3.one;
|
||||
child.EnableScript(file.GetCurrentDirName(), Path.Combine(file.GetCurrentDirName(), file.GetName(false)), type, this);
|
||||
|
||||
// Add Child
|
||||
Childs.Add(child);
|
||||
|
||||
// Load Child Script
|
||||
yield return child.LoadScript(file.LoadAsText());
|
||||
|
||||
LastLoadedScriptableObject = child;
|
||||
callback?.Invoke(child);
|
||||
}
|
||||
|
||||
public IEnumerator DoGenerateSubScriptAsync([In] string type, string name, [Opt] Action<ScriptableObject> callback)
|
||||
{
|
||||
// 判断类型是否合法
|
||||
if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false)
|
||||
{
|
||||
Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this);
|
||||
callback?.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
// 生成对象
|
||||
var child = creater();
|
||||
child.ScriptName = name;
|
||||
child.transform.SetParent(this.transform);
|
||||
child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
child.transform.localScale = Vector3.one;
|
||||
child.EnableScript("", "", type, this);
|
||||
|
||||
// Add Child
|
||||
Childs.Add(child);
|
||||
|
||||
// Load Child Script
|
||||
yield return child.LoadScript("");
|
||||
|
||||
LastLoadedScriptableObject = child;
|
||||
callback?.Invoke(child);
|
||||
}
|
||||
|
||||
public ScriptableObject DoGenerateSubScript([In] string type, string name, [Opt] Action<ScriptableObject> callback)
|
||||
{
|
||||
// 判断类型是否合法
|
||||
if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false)
|
||||
{
|
||||
Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this);
|
||||
callback?.Invoke(null);
|
||||
return null;
|
||||
}
|
||||
// 生成对象
|
||||
var child = creater();
|
||||
child.ScriptName = name;
|
||||
child.transform.SetParent(this.transform);
|
||||
child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
child.transform.localScale = Vector3.one;
|
||||
child.EnableScript("", "", type, this);
|
||||
|
||||
// Add Child
|
||||
Childs.Add(child);
|
||||
|
||||
// Load Child Script
|
||||
ConventionUtility.StartCoroutine(child.LoadScript(""));
|
||||
|
||||
LastLoadedScriptableObject = child;
|
||||
callback?.Invoke(child);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建无初始化脚本且无启动的子脚本对象
|
||||
/// 创建基于子脚本的实例对象
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject NewSubScriptWithoutInit([In] string type, [In]string name)
|
||||
public ScriptableObject NewSubScript([In] string type, [In] string name, [In] string path)
|
||||
{
|
||||
// 判断类型是否合法
|
||||
if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false)
|
||||
{
|
||||
Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this);
|
||||
return null;
|
||||
}
|
||||
// 生成对象
|
||||
var child = creater();
|
||||
// 获取文件
|
||||
var file = new ToolFile(GetRoot().SourcePath);
|
||||
file = file | path;
|
||||
// 找不到脚本
|
||||
if (file.Exists() == false)
|
||||
{
|
||||
Debug.LogError($"{file}<{path}> is not found", this);
|
||||
return null;
|
||||
}
|
||||
child.ScriptName = name;
|
||||
child.transform.SetParent(this.transform);
|
||||
child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
child.transform.localScale = Vector3.one;
|
||||
child.EnableScript(this);
|
||||
|
||||
// Add Child
|
||||
Childs.Add(child);
|
||||
|
||||
// Load Child Script
|
||||
ConventionUtility.StartCoroutine(child.ParseScript2Expr(file.LoadAsText()));
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建不基于子脚本的实例对象
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject NewSubScript([In] string type, string name)
|
||||
{
|
||||
// 判断类型是否合法
|
||||
if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false)
|
||||
@@ -518,58 +358,14 @@ namespace Demo
|
||||
child.transform.SetParent(this.transform);
|
||||
child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
child.transform.localScale = Vector3.one;
|
||||
child.EnableScript("", "", type, this);
|
||||
child.EnableScript(this);
|
||||
|
||||
// Add Child
|
||||
Childs.Add(child);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将无初始化创建的脚本对象确认完全加载并设置为最后添加的脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject ApplyLoad()
|
||||
{
|
||||
// Load Child Script
|
||||
ConventionUtility.StartCoroutine(this.LoadScript(""));
|
||||
|
||||
LastLoadedScriptableObject = this;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建不需要脚本语句的子脚本对象
|
||||
/// </summary>
|
||||
/// <param name="type">指定类型</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject NewSubScript([In] string type, [In] string name)
|
||||
{
|
||||
return DoGenerateSubScript(type, name, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建不需要脚本语句的子脚本对象
|
||||
/// </summary>
|
||||
/// <param name="type">指定类型</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject NewSubScript([In] string type)
|
||||
{
|
||||
return NewSubScript(type, $"New {type}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载子脚本
|
||||
/// </summary>
|
||||
/// <param name="type">指定类型</param>
|
||||
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public IEnumerator LoadSubScript([In] string type, [In] string path)
|
||||
{
|
||||
return DoLoadSubScriptAsync(type, path, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取已加载的脚本对象
|
||||
/// </summary>
|
||||
@@ -590,19 +386,9 @@ namespace Demo
|
||||
return Parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取上一个加载的脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject GetLastLoadedScriptableObject()
|
||||
{
|
||||
return LastLoadedScriptableObject;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerator ParseScript2Expr(string script)
|
||||
public IEnumerator ParseScript2Expr(string script)
|
||||
{
|
||||
RScriptEngine engine = new();
|
||||
RScriptImportClass importClass = new()
|
||||
@@ -674,123 +460,26 @@ namespace Demo
|
||||
/// </summary>
|
||||
public partial class ScriptableObject : SerializedMonoBehaviour, IHierarchyItemClickEventListener
|
||||
{
|
||||
|
||||
public static bool IsAutoPlay = false;
|
||||
|
||||
public ScriptableObject Parent;
|
||||
|
||||
/// <summary>
|
||||
/// 获取根脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public RootObject GetRoot()
|
||||
protected virtual IEnumerator DoSomethingDuringApplyScript()
|
||||
{
|
||||
if (Parent == null)
|
||||
return this as RootObject;
|
||||
if (Parent is RootObject result)
|
||||
return result;
|
||||
else
|
||||
return Parent.GetRoot();
|
||||
yield break;
|
||||
}
|
||||
|
||||
public List<ScriptableObject> Childs = new();
|
||||
|
||||
|
||||
// Cache
|
||||
|
||||
public const string RootObjectQuickPath = "project/";
|
||||
|
||||
public ScriptableObject FindWithPath(string path, bool isMustExist = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (isMustExist)
|
||||
throw new Exception("path is null or empty");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// GetParent
|
||||
ScriptableObject result = Parent;
|
||||
if (path.Replace('\\','/').ToLower().StartsWith(RootObjectQuickPath))
|
||||
{
|
||||
result = GetRoot();
|
||||
path = path[RootObjectQuickPath.Length..];
|
||||
}
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Root is nosupport to {nameof(FindWithPath)}");
|
||||
}
|
||||
|
||||
// Find
|
||||
var components = path.Split('/', '\\');
|
||||
components[^1] = new ToolFile(components[^1]).GetFilename(true);
|
||||
foreach (var component in components)
|
||||
{
|
||||
if (component == "..")
|
||||
result = result.Parent;
|
||||
else if (component == "." || string.IsNullOrEmpty(component))
|
||||
continue;
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
string targetScriptObjectPath = component;
|
||||
Regex regex = new(@"^(.*)\[(\d*)\]$");
|
||||
var match = regex.Match(component);
|
||||
if (match.Success)
|
||||
{
|
||||
targetScriptObjectPath = match.Groups[1].Value;
|
||||
index = int.Parse(match.Groups[2].Value);
|
||||
}
|
||||
var target = result.Childs.FirstOrDefault(x =>
|
||||
{
|
||||
bool stats = x.ScriptName == targetScriptObjectPath;
|
||||
if (index == 0)
|
||||
return stats;
|
||||
else if (stats)
|
||||
index--;
|
||||
return false;
|
||||
});
|
||||
if (target != null)
|
||||
result = target;
|
||||
else
|
||||
{
|
||||
if (isMustExist)
|
||||
throw new Exception($"{component} in {path} is not found");
|
||||
else
|
||||
{
|
||||
Debug.Log($"{component} in {path} is not found", this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public virtual IEnumerator LoadScript(string script)
|
||||
public IEnumerator ApplyScript()
|
||||
{
|
||||
if (EnsureEnableScript() == false)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
yield return DoSomethingDuringApplyScript();
|
||||
// 增数
|
||||
{
|
||||
AllScriptableObjectCounter++;
|
||||
AllScriptableObjectCounterHierarchyItem.GetHierarchyItem().text = $"ScriptableObjectCount: {AllScriptableObjectCounter}";
|
||||
}
|
||||
yield return ParseScript2Expr(script);
|
||||
IsEnableUpdate = true;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
StartCoroutine(UnloadScript());
|
||||
}
|
||||
|
||||
public virtual IEnumerator UnloadScript()
|
||||
{
|
||||
if (EnsureEnableScript())
|
||||
@@ -827,7 +516,7 @@ namespace Demo
|
||||
|
||||
public virtual void ResetEnterGameStatus()
|
||||
{
|
||||
ResetScriptableObjectEnterGameStatus();
|
||||
ScriptableObjectDoReset();
|
||||
}
|
||||
|
||||
public virtual void OnHierarchyItemRightClick(RectTransform item)
|
||||
@@ -956,14 +645,18 @@ namespace Demo
|
||||
|
||||
private static UnityEngine.UI.Image CacheLastFocusImage;
|
||||
private static Color CacheLastFocusImageOriginColor = new(1, 1, 1, 0.01f);
|
||||
private static Color FocusImageColor = new Color(1f, 47f / 51f, 0.0156862754f, 0.1f);
|
||||
private static Color FocusImageColor = new(1f, 47f / 51f, 0.0156862754f, 0.1f);
|
||||
|
||||
public override IEnumerator LoadScript(string script)
|
||||
protected override IEnumerator DoSomethingDuringApplyScript()
|
||||
{
|
||||
MyTimelineEntry = TimelineWindow.CreateRootItemEntries(1)[0];
|
||||
MyTimelineItem = MyTimelineEntry.ref_value.GetComponent<Editor.UI.TimelineItem>();
|
||||
yield return base.LoadScript(script);
|
||||
yield return base.DoSomethingDuringApplyScript();
|
||||
if(MyTimelineEntry==null)
|
||||
{
|
||||
MyTimelineEntry = TimelineWindow.CreateRootItemEntries(1)[0];
|
||||
MyTimelineItem = MyTimelineEntry.ref_value.GetComponent<Editor.UI.TimelineItem>();
|
||||
}
|
||||
MyTimelineItem.title = ScriptName;
|
||||
MyTimelineItem.RawButton.onClick.RemoveAllListeners();
|
||||
MyTimelineItem.AddListener(() =>
|
||||
{
|
||||
HierarchyWindow.instance.MakeFocusOn(MyHierarchyItem.GetHierarchyItem());
|
||||
@@ -979,28 +672,20 @@ namespace Demo
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerator UnloadScript()
|
||||
{
|
||||
yield return base.UnloadScript();
|
||||
MyTimelineItem.RawButton.onClick.RemoveAllListeners();
|
||||
MyTimelineEntry.Release();
|
||||
MyTimelineEntry = null;
|
||||
MyTimelineItem = null;
|
||||
}
|
||||
|
||||
public override void OnHierarchyItemClick(HierarchyItem item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//protected virtual void ShowTimelineItemWithChilds()
|
||||
//{
|
||||
// ScriptableObject parent = this;
|
||||
// List<ScriptableObject> childs = this.Childs;
|
||||
// if (parent is TimelineScriptObject ptso)
|
||||
// {
|
||||
// ptso.IsTimelineItemShow = true;
|
||||
// }
|
||||
// foreach (var child in childs)
|
||||
// {
|
||||
// if (child is TimelineScriptObject tso)
|
||||
// {
|
||||
// tso.IsTimelineItemShow = true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
|
||||
{
|
||||
base.UpdateTicks(currentTime, deltaTime, tickType);
|
||||
@@ -1025,14 +710,5 @@ namespace Demo
|
||||
var color = new Vector3(Foo(a1), Foo(a2), Foo(a3)).normalized;
|
||||
return new(color.x, color.y, color.z);
|
||||
}
|
||||
|
||||
public override IEnumerator UnloadScript()
|
||||
{
|
||||
yield return base.UnloadScript();
|
||||
MyTimelineItem.RawButton.onClick.RemoveAllListeners();
|
||||
MyTimelineEntry.Release();
|
||||
MyTimelineEntry = null;
|
||||
MyTimelineItem = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,46 +17,17 @@ namespace Demo.Game
|
||||
[Content, SerializeField] private string project;
|
||||
[Content, SerializeField] private GameController SubWorldGameController;
|
||||
|
||||
public override IEnumerator LoadScript(string script)
|
||||
protected override IEnumerator DoSomethingDuringApplyScript()
|
||||
{
|
||||
yield return base.LoadScript(script);
|
||||
/*
|
||||
// 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 => { };
|
||||
yield return base.DoSomethingDuringApplyScript();
|
||||
var ir = SceneManager.LoadSceneAsync(Editor.EditorController.SceneName, LoadSceneMode.Additive);
|
||||
ir.completed += x =>
|
||||
{
|
||||
SubWorldGameController = (from controller in FindObjectsOfType<GameController>()
|
||||
where controller.RootSourcePath == project
|
||||
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()
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Demo.Game
|
||||
}
|
||||
|
||||
public int Content = 0;
|
||||
public List<UpdatementEntry> Entries = new();
|
||||
public readonly List<UpdatementEntry> Entries = new();
|
||||
protected abstract void UpdateData(DataType data);
|
||||
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)
|
||||
{
|
||||
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)));
|
||||
}
|
||||
|
||||
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));
|
||||
if (UpdateTarget == null)
|
||||
{
|
||||
@@ -76,9 +65,10 @@ namespace Demo.Game
|
||||
public override IEnumerator UnloadScript()
|
||||
{
|
||||
Content = 0;
|
||||
Entries = new();
|
||||
Entries.Clear();
|
||||
yield return base.UnloadScript();
|
||||
}
|
||||
|
||||
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
|
||||
{
|
||||
base.UpdateTicks(currentTime, deltaTime, tickType);
|
||||
@@ -140,16 +130,12 @@ namespace Demo.Game
|
||||
/// <summary>
|
||||
/// 设置更新对象
|
||||
/// </summary>
|
||||
/// <param name="path">脚本的相对路径</param>
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetUpdateTarget(string path)
|
||||
public void SetUpdateTarget(ScriptableObject target)
|
||||
{
|
||||
var temp = FindWithPath(path);
|
||||
if (temp != null)
|
||||
UpdateTarget = temp.gameObject;
|
||||
else
|
||||
Debug.LogWarning($"{path}' is not found", this);
|
||||
UpdateTarget = target.gameObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -165,7 +151,6 @@ namespace Demo.Game
|
||||
|
||||
public interface ILocalUpdatement<DataType>: IScriptableObject
|
||||
{
|
||||
|
||||
int Content { get; set; }
|
||||
public List<ILocalUpdatementExtension.UpdatementEntry<DataType>> Entries { get; set; }
|
||||
void UpdateData(DataType data);
|
||||
@@ -182,11 +167,11 @@ namespace Demo.Game
|
||||
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()
|
||||
{
|
||||
TimePoint = self.SharedInterfaceScriptObject.Parse(time),
|
||||
TimePoint = time,
|
||||
Position = position,
|
||||
easeCurveType = curveType
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user