正在为RScript更新内容(已通过编译)
This commit is contained in:
@@ -45,12 +45,7 @@ namespace Demo.Game
|
||||
/// 设置是否为正交相机
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置是否为正交相机
|
||||
</summary>
|
||||
<param name=""arg""></param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetOrthographic(string arg)
|
||||
{
|
||||
MainCamera.orthographic = ConvertValue<bool>(arg);
|
||||
@@ -60,12 +55,7 @@ namespace Demo.Game
|
||||
/// 设置相机视野角度
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置相机视野角度
|
||||
</summary>
|
||||
<param name=""arg"">视野角度值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetFieldOfView(string arg)
|
||||
{
|
||||
MainCamera.fieldOfView = Parse(arg);
|
||||
@@ -75,12 +65,7 @@ namespace Demo.Game
|
||||
/// 设置正交相机的尺寸
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置正交相机的尺寸
|
||||
</summary>
|
||||
<param name=""arg"">正交相机尺寸值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetOrthographicSize(string arg)
|
||||
{
|
||||
MainCamera.orthographicSize = Parse(arg);
|
||||
@@ -90,12 +75,7 @@ namespace Demo.Game
|
||||
/// 设置近裁剪面距离
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置近裁剪面距离
|
||||
</summary>
|
||||
<param name=""arg"">近裁剪面距离值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetNearClipPlane(string arg)
|
||||
{
|
||||
MainCamera.nearClipPlane = Parse(arg);
|
||||
@@ -105,12 +85,7 @@ namespace Demo.Game
|
||||
/// 设置远裁剪面距离
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置远裁剪面距离
|
||||
</summary>
|
||||
<param name=""arg"">远裁剪面距离值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetFarClipPlane(string arg)
|
||||
{
|
||||
MainCamera.farClipPlane = Parse(arg);
|
||||
@@ -120,12 +95,7 @@ namespace Demo.Game
|
||||
/// 设置相机深度
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置相机深度
|
||||
</summary>
|
||||
<param name=""arg"">相机深度值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetDepth(string arg)
|
||||
{
|
||||
MainCamera.depth = Parse(arg);
|
||||
@@ -135,12 +105,7 @@ namespace Demo.Game
|
||||
/// 设置虚拟相机跟随目标
|
||||
/// </summary>
|
||||
/// <param name="targetName">对象相对路径</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置虚拟相机跟随目标
|
||||
</summary>
|
||||
<param name=""targetName"">对象相对路径</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetVirtualCameraFollow(string targetName)
|
||||
{
|
||||
var target = FindWithPath(targetName, false);
|
||||
@@ -154,12 +119,7 @@ namespace Demo.Game
|
||||
/// 设置虚拟相机观察目标
|
||||
/// </summary>
|
||||
/// <param name="targetName">对象相对路径</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置虚拟相机观察目标
|
||||
</summary>
|
||||
<param name=""targetName"">对象相对路径</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetVirtualCameraLookAt(string targetName)
|
||||
{
|
||||
var target = FindWithPath(targetName, false);
|
||||
@@ -175,14 +135,7 @@ namespace Demo.Game
|
||||
/// <param name="x">X轴偏移</param>
|
||||
/// <param name="y">Y轴偏移</param>
|
||||
/// <param name="z">Z轴偏移</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置虚拟相机跟随偏移
|
||||
</summary>
|
||||
<param name=""x"">X轴偏移</param>
|
||||
<param name=""y"">Y轴偏移</param>
|
||||
<param name=""z"">Z轴偏移</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetVirtualCameraFollowOffset(string x, string y, string z)
|
||||
{
|
||||
var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>();
|
||||
@@ -202,14 +155,7 @@ namespace Demo.Game
|
||||
/// <param name="x">X轴阻尼</param>
|
||||
/// <param name="y">Y轴阻尼</param>
|
||||
/// <param name="z">Z轴阻尼</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置虚拟相机跟随阻尼
|
||||
</summary>
|
||||
<param name=""x"">X轴阻尼</param>
|
||||
<param name=""y"">Y轴阻尼</param>
|
||||
<param name=""z"">Z轴阻尼</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetVirtualCameraFollowDamping(string x, string y, string z)
|
||||
{
|
||||
var body = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineTransposer>();
|
||||
@@ -227,14 +173,7 @@ namespace Demo.Game
|
||||
/// <param name="x">X轴阻尼</param>
|
||||
/// <param name="y">Y轴阻尼</param>
|
||||
/// <param name="z">Z轴阻尼</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置虚拟相机观察阻尼
|
||||
</summary>
|
||||
<param name=""x"">X轴阻尼</param>
|
||||
<param name=""y"">Y轴阻尼</param>
|
||||
<param name=""z"">Z轴阻尼</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetVirtualCameraLookAtDamping(string x, string y, string z)
|
||||
{
|
||||
var aim = VirtualCamera.GetCinemachineComponent<Cinemachine.CinemachineComposer>();
|
||||
|
||||
@@ -15,10 +15,7 @@ namespace Demo.Game
|
||||
|
||||
public List<float> Datas = new();
|
||||
|
||||
[ScriptableCall(@"
|
||||
添加float数据(允许使用除本以外的表达式), 随后可以用对象路径+索引获取变量值,
|
||||
e.g: CameraObject/DDT[3], 获取CameraObject/DDT对象路径下DDT数据中的第四个值
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void Add(string value)
|
||||
{
|
||||
Datas.Add(Parse(value));
|
||||
@@ -27,7 +24,7 @@ e.g: CameraObject/DDT[3], 获取CameraObject/DDT对象路径下DDT数据中的
|
||||
/// <summary>
|
||||
/// 从特定的json中读取数据, 并调用<see cref="Add(string)"/>
|
||||
/// </summary>
|
||||
[ScriptableCall(@"从特定的json中读取数据, 并调用Add函数")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void Load()
|
||||
{
|
||||
var file = new ToolFile(BindingDataJson);
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace Demo.Editor
|
||||
[Resources] public Text CurrentTimeText;
|
||||
[Resources] public Text CurrentFPS;
|
||||
[Setting] public const string SceneName = "GameScene";
|
||||
[Setting] public ProjectDefaultFileStyle CurrentProjectDefaultFileStyle = default;
|
||||
[Setting] public bool IsLowPerformance = false;
|
||||
|
||||
[Content] public string LastLoadProjectName = "";
|
||||
@@ -330,7 +329,6 @@ namespace Demo.Editor
|
||||
};
|
||||
content.SetSongCurrentTime = InjectSetSongCurrentTime;
|
||||
content.SongLoadOverCallback = InjectSongLoadOverCallback;
|
||||
content.CurrentProjectDefaultFileStyle = CurrentProjectDefaultFileStyle;
|
||||
SceneManager.LoadSceneAsync(SceneName, LoadSceneMode.Additive).completed += x =>
|
||||
{
|
||||
LastLoadProjectName = ProjectName;
|
||||
@@ -382,7 +380,7 @@ namespace Demo.Editor
|
||||
ToolFile helperHeaderDir = new ToolFile(PersistentHelperPath);
|
||||
if (helperHeaderDir.Exists() == false)
|
||||
{
|
||||
ProjectCreateHelper.CreateHelperFiles(helperHeaderDir, CurrentProjectDefaultFileStyle);
|
||||
//ProjectCreateHelper.CreateHelperFiles(helperHeaderDir);
|
||||
}
|
||||
|
||||
// Reset
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Convention;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Demo.Editor
|
||||
{
|
||||
public static class ProjectCreateHelper
|
||||
{
|
||||
private static string GetTypename(Type type)
|
||||
{
|
||||
string result = type.Name;
|
||||
if (result.Contains('`'))
|
||||
return result[..result.LastIndexOf('`')];
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WritePythonStyleFunction(StreamWriter stream, string name, IEnumerable<string> paramList, string description)
|
||||
{
|
||||
stream.Write($"def {name}({string.Join(',', paramList)}):\n");
|
||||
stream.Write($"'''\n{description}\n'''\n...\n\n");
|
||||
}
|
||||
|
||||
private static void WriteCPPClassBase(StreamWriter stream, Type currentType)
|
||||
{
|
||||
string currentTypeName = GetTypename(currentType);
|
||||
string baseTypeName = GetTypename(currentType.BaseType);
|
||||
if (currentType == typeof(ScriptableObject))
|
||||
{
|
||||
// <20><><EFBFBD>ƹ<EFBFBD><C6B9>ߺ<EFBFBD>
|
||||
stream.WriteLine("#define __build_in_pragma #");
|
||||
stream.WriteLine("#define __build_in_to_text(x) #x");
|
||||
stream.WriteLine("#define this");
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ඨ<EFBFBD><E0B6A8><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in asm.GetTypes())
|
||||
{
|
||||
// Functions
|
||||
if (typeof(ScriptableObject).IsAssignableFrom(type))
|
||||
{
|
||||
string typeName = GetTypename(type);
|
||||
stream.WriteLine($"#define {typeName} \"{typeName}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>Mathf
|
||||
foreach (var method in typeof(Mathf).GetMethods())
|
||||
{
|
||||
stream.WriteLine($"#define {method.Name}({string.Join(',', from param in method.GetParameters() select param.Name)})");
|
||||
}
|
||||
foreach (var curveType in Enum.GetNames(typeof(MathExtension.EaseCurveType)))
|
||||
{
|
||||
stream.WriteLine($"#define {curveType}");
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>RScript<70>ؼ<EFBFBD><D8BC><EFBFBD>
|
||||
{
|
||||
stream.Write(@"
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ
|
||||
*/
|
||||
");
|
||||
stream.Write($"#define label(label_name) __build_in_pragma define label_name\n\n");
|
||||
}
|
||||
{
|
||||
stream.Write(@"
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>prΪ<72><CEAA>ʱ<EFBFBD><CAB1>ת<EFBFBD><D7AA>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>label<65><6C>
|
||||
*/
|
||||
");
|
||||
stream.Write($"#define goto(pr,label_name)\n\n");
|
||||
}
|
||||
{
|
||||
stream.Write(@"
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>prΪ<72><CEAA>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD>goto<74><6F>λ<EFBFBD><CEBB>, ջģʽ
|
||||
*/
|
||||
");
|
||||
stream.Write($"#define back(pr)\n\n");
|
||||
}
|
||||
{
|
||||
stream.Write(@"
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>prΪ<72><CEAA>ʱ<EFBFBD>˳<EFBFBD><CBB3><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
|
||||
*/
|
||||
");
|
||||
stream.Write($"#define break(pr)\n\n");
|
||||
}
|
||||
{
|
||||
stream.Write(@"
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ佫<D5BC><E4BDAB><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>, <20><>Ҫʹ<D2AA><CAB9>goto<74><6F><EFBFBD><EFBFBD>
|
||||
*/
|
||||
");
|
||||
stream.Write($"#define namespace(name)\n\n");
|
||||
}
|
||||
stream.WriteLine($"struct {currentTypeName}");
|
||||
stream.WriteLine("{");
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Write($"#include \"{baseTypeName}.helper.h\"\n\n");
|
||||
stream.WriteLine($"struct {currentTypeName}:public {baseTypeName}");
|
||||
stream.WriteLine("{");
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteCPPStyleFunction(StreamWriter stream, string name, IEnumerable<string> paramList, string description)
|
||||
{
|
||||
if (name == nameof(ScriptableObject.LoadSubScript))
|
||||
{
|
||||
stream.Write("/*\n" + description + "\n*/\n");
|
||||
stream.Write($"#define {name}({string.Join(',', paramList)}) __build_in_pragma include {paramList.ToArray()[1]}\n\n");
|
||||
//stream.Write($"#define {name}({string.Join(',', paramList)})\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Write("/*\n" + description + "\n*/\n");
|
||||
stream.Write($"#define {name}({string.Join(',', paramList)}) \n\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteCPPClassEnd(StreamWriter stream, Type currentType)
|
||||
{
|
||||
stream.WriteLine("};");
|
||||
}
|
||||
|
||||
|
||||
public static void CreateHelperFiles(string dir, ProjectDefaultFileStyle style = ProjectDefaultFileStyle.CPP)
|
||||
{
|
||||
var toolDir = new ToolFile(dir);
|
||||
if (toolDir.IsDir() == false)
|
||||
{
|
||||
throw new InvalidOperationException("Not a directory");
|
||||
}
|
||||
toolDir.MustExistsPath();
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in asm.GetTypes())
|
||||
{
|
||||
// Functions
|
||||
if (typeof(ScriptableObject).IsAssignableFrom(type))
|
||||
{
|
||||
var scriptCalls = (from info in type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
|
||||
where info is MethodInfo
|
||||
where info.GetCustomAttribute<ScriptableCallAttribute>(false) != null
|
||||
select info as MethodInfo).ToList();
|
||||
var typeName = GetTypename(type);
|
||||
string fileHeader = $"{typeName}.helper" + style switch
|
||||
{
|
||||
ProjectDefaultFileStyle.PY => ",py",
|
||||
_ => ".h"
|
||||
};
|
||||
using var fs = File.AppendText((toolDir | fileHeader).GetFullPath());
|
||||
switch (style)
|
||||
{
|
||||
case ProjectDefaultFileStyle.CPP:
|
||||
WriteCPPClassBase(fs, type);
|
||||
break;
|
||||
case ProjectDefaultFileStyle.PY:
|
||||
break;
|
||||
}
|
||||
foreach (var methodInfo in scriptCalls)
|
||||
{
|
||||
var data = methodInfo.GetCustomAttribute<ScriptableCallAttribute>(false);
|
||||
switch (style)
|
||||
{
|
||||
case ProjectDefaultFileStyle.PY:
|
||||
WritePythonStyleFunction(fs, methodInfo.Name, from param in methodInfo.GetParameters() select param.Name, data.Description);
|
||||
break;
|
||||
default:
|
||||
WriteCPPStyleFunction(fs, methodInfo.Name, from param in methodInfo.GetParameters() select param.Name, data.Description);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (style)
|
||||
{
|
||||
case ProjectDefaultFileStyle.CPP:
|
||||
WriteCPPClassEnd(fs, type);
|
||||
break;
|
||||
case ProjectDefaultFileStyle.PY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Enums
|
||||
if (typeof(Enum).IsAssignableFrom(type)&& type.GetCustomAttribute<ScriptableCallAttribute>(false) != null)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a9363d15f50a79438995f507e7662a5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,7 +13,6 @@ namespace Demo.Game
|
||||
public bool IsCreateNewProject = false;
|
||||
public Dictionary<string, Type> ScriptableObjectTypen = new();
|
||||
public bool IsAutoPlay = false;
|
||||
public ProjectDefaultFileStyle CurrentProjectDefaultFileStyle = default;
|
||||
[Header("Timeline")]
|
||||
public Action<float, float> SetupSongDuration;
|
||||
public Action<float> SetSongCurrentTime;
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace Demo.Game
|
||||
/// 值为null时不会在启动时打开
|
||||
/// </summary>
|
||||
public string WhichOpenProject { get; private set; } = null;
|
||||
public ProjectDefaultFileStyle CurrentProjectDefaultFileStyle = default;
|
||||
|
||||
public float SongOffset = 0;
|
||||
public float CurrentTime = 0;
|
||||
@@ -174,7 +173,6 @@ namespace Demo.Game
|
||||
Debug.LogException(ex, this);
|
||||
}
|
||||
}
|
||||
CurrentProjectDefaultFileStyle = content.CurrentProjectDefaultFileStyle;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,11 +184,7 @@ namespace Demo.Game
|
||||
{
|
||||
while (MainConfig.Contains("root") == false)
|
||||
{
|
||||
string defaultRootPath = "root" + CurrentProjectDefaultFileStyle switch
|
||||
{
|
||||
ProjectDefaultFileStyle.PY => ".py",
|
||||
_ => ".cpp"
|
||||
};
|
||||
string defaultRootPath = "root.cpp";
|
||||
if (content.IsCreateNewProject)
|
||||
{
|
||||
MainConfig["root"] = defaultRootPath;
|
||||
|
||||
@@ -17,257 +17,8 @@ using UnityEngine;
|
||||
|
||||
namespace Demo
|
||||
{
|
||||
public enum ProjectDefaultFileStyle
|
||||
public static class ScriptUtility
|
||||
{
|
||||
CPP,
|
||||
PY
|
||||
}
|
||||
|
||||
[System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class ScriptableCallAttribute : Attribute
|
||||
{
|
||||
public string Description;
|
||||
public ScriptableCallAttribute(string description)
|
||||
{
|
||||
this.Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
[System.AttributeUsage(AttributeTargets.Enum, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class ScriptableEnumAttribute : Attribute
|
||||
{
|
||||
public string Description;
|
||||
public ScriptableEnumAttribute(string description)
|
||||
{
|
||||
this.Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScriptCallUtility
|
||||
{
|
||||
// 解析函数调用的方法,支持 with 子句
|
||||
public static (string functionName, string[] arguments, Dictionary<string, string> withVariables) ParseFunctionCall(string input)
|
||||
{
|
||||
// 匹配函数名和参数部分,以及可选的 with 子句
|
||||
Match match = Regex.Match(input, @"^(\w+)\s*\(\s*(.*?)\s*\)\s*(?:\s+with\s*\(\s*(.*?)\s*\))?\s*;?$");
|
||||
|
||||
if (!match.Success)
|
||||
return (null, new string[0], new Dictionary<string, string>());
|
||||
|
||||
string functionName = match.Groups[1].Value;
|
||||
string argumentsString = match.Groups[2].Value;
|
||||
string withString = match.Groups[3].Value;
|
||||
|
||||
// 解析参数数组
|
||||
string[] arguments = ParseArguments(argumentsString);
|
||||
|
||||
// 解析 with 子句的变量
|
||||
Dictionary<string, string> withVariables = new Dictionary<string, string>();
|
||||
if (!string.IsNullOrWhiteSpace(withString))
|
||||
{
|
||||
withVariables = ParseWithClause(withString);
|
||||
}
|
||||
|
||||
return (functionName, arguments, withVariables);
|
||||
}
|
||||
|
||||
// 解析 with 子句的方法
|
||||
private static Dictionary<string, string> ParseWithClause(string withString)
|
||||
{
|
||||
var variables = new Dictionary<string, string>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(withString))
|
||||
return variables;
|
||||
|
||||
int i = 0;
|
||||
while (i < withString.Length)
|
||||
{
|
||||
// 跳过空白字符
|
||||
while (i < withString.Length && char.IsWhiteSpace(withString[i]))
|
||||
i++;
|
||||
|
||||
if (i >= withString.Length)
|
||||
break;
|
||||
|
||||
// 解析变量名
|
||||
int nameStart = i;
|
||||
while (i < withString.Length && (char.IsLetterOrDigit(withString[i]) || withString[i] == '_'))
|
||||
i++;
|
||||
|
||||
if (i == nameStart)
|
||||
break; // 没有找到有效的变量名
|
||||
|
||||
string varName = withString.Substring(nameStart, i - nameStart);
|
||||
|
||||
// 跳过空白字符
|
||||
while (i < withString.Length && char.IsWhiteSpace(withString[i]))
|
||||
i++;
|
||||
|
||||
// 检查等号
|
||||
if (i >= withString.Length || withString[i] != '=')
|
||||
break; // 没有找到等号
|
||||
i++; // 跳过等号
|
||||
|
||||
// 跳过空白字符
|
||||
while (i < withString.Length && char.IsWhiteSpace(withString[i]))
|
||||
i++;
|
||||
|
||||
// 解析变量值
|
||||
string varValue = ExtractArgument(withString, ref i);
|
||||
variables[varName] = varValue.Trim();
|
||||
|
||||
// 跳过空白字符
|
||||
while (i < withString.Length && char.IsWhiteSpace(withString[i]))
|
||||
i++;
|
||||
|
||||
// 检查逗号
|
||||
if (i < withString.Length && withString[i] == ',')
|
||||
{
|
||||
i++; // 跳过逗号
|
||||
}
|
||||
else if (i < withString.Length)
|
||||
{
|
||||
break; // 期望逗号但找到了其他字符
|
||||
}
|
||||
}
|
||||
|
||||
return variables;
|
||||
}
|
||||
|
||||
// 解析参数的方法
|
||||
private static string[] ParseArguments(string argumentsString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(argumentsString))
|
||||
return new string[0];
|
||||
|
||||
var arguments = new List<string>();
|
||||
int i = 0;
|
||||
|
||||
while (i < argumentsString.Length)
|
||||
{
|
||||
// 跳过空白字符
|
||||
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
|
||||
i++;
|
||||
|
||||
// 越界检查
|
||||
if (i >= argumentsString.Length)
|
||||
break;
|
||||
|
||||
string argument = ExtractArgument(argumentsString, ref i);
|
||||
if (!string.IsNullOrEmpty(argument))
|
||||
arguments.Add(argument.Trim());
|
||||
|
||||
// 跳过空白字符
|
||||
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
|
||||
i++;
|
||||
|
||||
// 越界检查
|
||||
if (i >= argumentsString.Length)
|
||||
break;
|
||||
|
||||
// 必定是逗号, 否则异常情况
|
||||
if (argumentsString[i] != ',')
|
||||
throw new InvalidOperationException("Parser is invalid logic");
|
||||
i++;
|
||||
}
|
||||
|
||||
return arguments.ToArray();
|
||||
}
|
||||
|
||||
// 提取单个参数的方法,支持花括号和字符串字面量
|
||||
private static string ExtractArgument(string input, ref int index)
|
||||
{
|
||||
int start = index;
|
||||
|
||||
if (input[index] == '"')
|
||||
{
|
||||
// 处理字符串字面量
|
||||
index++; // 跳过开始的引号
|
||||
while (index < input.Length)
|
||||
{
|
||||
if (input[index] == '"' && (index == 0 || input[index - 1] != '\\'))
|
||||
{
|
||||
index++; // 跳过结束的引号
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
else if (input[index] == '{')
|
||||
{
|
||||
// 处理花括号内的内容
|
||||
int braceCount = 0;
|
||||
while (index < input.Length)
|
||||
{
|
||||
if (input[index] == '{')
|
||||
braceCount++;
|
||||
else if (input[index] == '}')
|
||||
braceCount--;
|
||||
|
||||
index++;
|
||||
|
||||
if (braceCount == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 处理普通参数(直到遇到逗号)
|
||||
while (index < input.Length && input[index] != ',')
|
||||
index++;
|
||||
}
|
||||
|
||||
return input[start..index];
|
||||
}
|
||||
}
|
||||
|
||||
[System.AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class DefaultScriptAttribute : Attribute
|
||||
{
|
||||
public string DefaultScript;
|
||||
public DefaultScriptAttribute(string script)
|
||||
{
|
||||
this.DefaultScript = script;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DefaultScriptUtility
|
||||
{
|
||||
public static void WriteStyleMethodHelper(StreamWriter stream,MethodInfo methodInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static void WriteDefaultScript(StreamWriter fs, Type type)
|
||||
{
|
||||
if (typeof(ScriptableObject).IsAssignableFrom(type) == false)
|
||||
throw new InvalidOperationException($"{type.FullName} is not inherited from {typeof(ScriptableObject).FullName}");
|
||||
var attr = type.GetCustomAttribute<DefaultScriptAttribute>();
|
||||
var typeName = type.Name;
|
||||
if (typeName.Contains('`'))
|
||||
{
|
||||
typeName = typeName[..typeName.LastIndexOf('`')];
|
||||
}
|
||||
switch (Editor.EditorController.instance.MainGameController.CurrentProjectDefaultFileStyle)
|
||||
{
|
||||
case ProjectDefaultFileStyle.CPP:
|
||||
{
|
||||
fs.WriteLine($"#include \"{typeName}.helper.h\"");
|
||||
if (attr != null)
|
||||
{
|
||||
var text = attr.DefaultScript;
|
||||
fs.Write(text);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ProjectDefaultFileStyle.PY:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenScriptFile(ScriptableObject so)
|
||||
{
|
||||
string path = so.ScriptPath;
|
||||
@@ -312,14 +63,7 @@ namespace Demo
|
||||
/// <param name="id">时间线ID,若不存在则创建</param>
|
||||
/// <param name="delta">当每次调用NextTimePoint函数时使用的单位值</param>
|
||||
/// <param name="value">初始化时间</param>
|
||||
[ScriptableCall(@"
|
||||
<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, string delta, string value)
|
||||
{
|
||||
TimePointDelta[id] = float.Parse(delta);
|
||||
@@ -331,13 +75,7 @@ namespace Demo
|
||||
/// </summary>
|
||||
/// <param name="id">时间线ID</param>
|
||||
/// <param name="times">前进次数,最终时间的增量为前进次数乘该时间线的单位值</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
推动时间线前进
|
||||
</summary>
|
||||
<param name=""id"">时间线ID</param>
|
||||
<param name=""times"">前进次数,最终时间的增量为前进次数乘该时间线的单位值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void NextTimePoint(string id, string times)
|
||||
{
|
||||
TimePoints[id] += TimePointDelta[id] * float.Parse(times);
|
||||
@@ -348,13 +86,7 @@ namespace Demo
|
||||
/// </summary>
|
||||
/// <param name="id">时间线ID</param>
|
||||
/// <param name="value">次数,时间线的值将被设置为次数乘该时间线的单位值</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置时间线的值
|
||||
</summary>
|
||||
<param name=""id"">时间线ID</param>
|
||||
<param name=""value"">次数,时间线的值将被设置为次数乘该时间线的单位值</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetTimePoint(string id, string value)
|
||||
{
|
||||
TimePoints[id] = TimePointDelta[id] * float.Parse(value);
|
||||
@@ -397,13 +129,7 @@ namespace Demo
|
||||
/// </summary>
|
||||
/// <param name="name">字符串</param>
|
||||
/// <param name="value">浮点数</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置局部上下文变量,将会传递给子物体使用
|
||||
</summary>
|
||||
<param name=""name"">字符串</param>
|
||||
<param name=""value"">浮点数</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetContext(string name, string value)
|
||||
{
|
||||
ScriptContextSpace[name] = Parse(value);
|
||||
@@ -440,18 +166,7 @@ namespace Demo
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
从字符串解析为浮点数
|
||||
从时间点列表中获取
|
||||
或是从上下文变量中获取
|
||||
或是从数据驱动对象中获取
|
||||
或是通过计算表达式值获取
|
||||
或是直接调用float.Parse(string)
|
||||
</summary>
|
||||
<param name=""value""></param>
|
||||
<returns></returns>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public float Parse(string value)
|
||||
{
|
||||
value = value.Trim();
|
||||
@@ -535,14 +250,7 @@ namespace Demo
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="z"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置坐标
|
||||
</summary>
|
||||
<param name=""result""></param>
|
||||
<param name=""y""></param>
|
||||
<param name=""z""></param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetLocalPosition(string x, string y, string z)
|
||||
{
|
||||
EnterGameLocalPosition = new(Parse(x), Parse(y), Parse(z));
|
||||
@@ -553,14 +261,7 @@ namespace Demo
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="z"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置欧拉角
|
||||
</summary>
|
||||
<param name=""result""></param>
|
||||
<param name=""y""></param>
|
||||
<param name=""z""></param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetLocalEulerAngles(string x, string y, string z)
|
||||
{
|
||||
EnterGameEulerAngles = new(Parse(x), Parse(y), Parse(z));
|
||||
@@ -571,14 +272,7 @@ namespace Demo
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="z"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置缩放
|
||||
</summary>
|
||||
<param name=""result""></param>
|
||||
<param name=""y""></param>
|
||||
<param name=""z""></param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetLocalScaling(string x, string y, string z)
|
||||
{
|
||||
EnterGameLocalScaling = new(Parse(x), Parse(y), Parse(z));
|
||||
@@ -588,12 +282,7 @@ namespace Demo
|
||||
/// 关闭该物体,
|
||||
/// 在面对如多Game场景时关闭某些GameWorld中默认存在的全局灯光等场景时非常有用
|
||||
/// </summary>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
关闭该物体,
|
||||
在面对如多Game场景时关闭某些GameWorld中默认存在的全局灯光等场景时非常有用
|
||||
</summary>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetObjectDisable()
|
||||
{
|
||||
IsSetObjectDisable = true;
|
||||
@@ -623,13 +312,7 @@ namespace Demo
|
||||
/// 属于性能优化的高级选项
|
||||
/// </summary>
|
||||
/// <param name="frame">每frame帧更新一次, 等于0代表不会在<see cref="TickType.Update"/>状态运行</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
指定多少个Update状态的UpdateTicks执行一次更新,不会影响到子物体
|
||||
属于性能优化的高级选项
|
||||
</summary>
|
||||
<param name=""frame"">每frame帧更新一次, 等于0代表不会在Update状态运行</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetUpdatePerFrame(string frame)
|
||||
{
|
||||
UpdatePerFrame = Mathf.Max(1, int.Parse(frame));
|
||||
@@ -763,13 +446,7 @@ namespace Demo
|
||||
/// </summary>
|
||||
/// <param name="type">指定类型</param>
|
||||
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||
[ScriptableCall(@"
|
||||
<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);
|
||||
@@ -779,12 +456,7 @@ namespace Demo
|
||||
/// 获取已加载的脚本对象
|
||||
/// </summary>
|
||||
/// <returns>无法找到时将返回空</returns>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
获取已加载的脚本对象
|
||||
</summary>
|
||||
<returns>无法找到时将返回空</returns>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject GetLoadedObject(string path)
|
||||
{
|
||||
return FindWithPath(path, false);
|
||||
@@ -794,12 +466,7 @@ namespace Demo
|
||||
/// 获取父脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
获取父脚本对象
|
||||
</summary>
|
||||
<returns></returns>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject GetParentObject()
|
||||
{
|
||||
return Parent;
|
||||
@@ -809,36 +476,12 @@ namespace Demo
|
||||
/// 获取上一个加载的脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
获取上一个加载的脚本对象
|
||||
</summary>
|
||||
<returns></returns>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public ScriptableObject GetLastLoadedScriptableObject()
|
||||
{
|
||||
return LastLoadedScriptableObject;
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// 异步加载子脚本
|
||||
/// </summary>
|
||||
/// <param name="type">指定类型</param>
|
||||
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
异步加载子脚本
|
||||
</summary>
|
||||
<param name=""type"">指定类型</param>
|
||||
<param name=""path"">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||
")]
|
||||
public void LoadSubScriptAsync([In] string type, [In] string path)
|
||||
{
|
||||
StartCoroutine(DoLoadSubScriptAsync(type, path, null));
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerator ParseScript2Expr(string script)
|
||||
@@ -922,12 +565,7 @@ namespace Demo
|
||||
/// 获取根脚本对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
获取根脚本对象
|
||||
</summary>
|
||||
<returns></returns>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public RootObject GetRoot()
|
||||
{
|
||||
if (Parent == null)
|
||||
@@ -1220,19 +858,12 @@ namespace Demo
|
||||
// 暂时的逻辑是总是展示的
|
||||
{
|
||||
TimelineScriptObjectWhichOnShow.Add(this);
|
||||
//IsTimelineItemShow = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnHierarchyItemClick(HierarchyItem item)
|
||||
{
|
||||
//foreach (var tso in TimelineScriptObjectWhichOnShow)
|
||||
//{
|
||||
// tso.IsTimelineItemShow = false;
|
||||
// tso.MyTimelineItem.RawButton.gameObject.SetActive(false);
|
||||
//}
|
||||
//TimelineScriptObjectWhichOnShow.Clear();
|
||||
//ShowTimelineItemWithChilds();
|
||||
|
||||
}
|
||||
|
||||
//protected virtual void ShowTimelineItemWithChilds()
|
||||
@@ -1255,10 +886,9 @@ namespace Demo
|
||||
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
|
||||
{
|
||||
base.UpdateTicks(currentTime, deltaTime, tickType);
|
||||
//if (IsTimelineItemShow)
|
||||
//{
|
||||
{
|
||||
MyTimelineItem.ResizeOnTimeline();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void SetupTimelineItem(Editor.UI.TimelineItem item);
|
||||
|
||||
@@ -84,12 +84,7 @@ namespace Demo.Game
|
||||
var childName = type;
|
||||
int childIndex = 1;
|
||||
var childFullNameWithoutExtension = childName;
|
||||
var extension = so.GetRoot().RootGameController.CurrentProjectDefaultFileStyle switch
|
||||
{
|
||||
ProjectDefaultFileStyle.CPP => ".h",
|
||||
ProjectDefaultFileStyle.PY => ".py",
|
||||
_ => ""
|
||||
};
|
||||
var extension = ".h";
|
||||
if (childDir.Exists())
|
||||
{
|
||||
childFullNameWithoutExtension = $"{childName}{(childIndex == 1 ? "" : childIndex.ToString())}";
|
||||
@@ -125,7 +120,7 @@ namespace Demo.Game
|
||||
// 新建时添加模板内容
|
||||
using var childFileStream = File.AppendText(childFile);
|
||||
{
|
||||
DefaultScriptUtility.WriteDefaultScript(childFileStream, ScriptableObject.FastScriptableObjectTypen[type]);
|
||||
//ScriptUtility.WriteDefaultScript(childFileStream, ScriptableObject.FastScriptableObjectTypen[type]);
|
||||
childFileStream.Close();
|
||||
}
|
||||
//不刷新世界,直接加载
|
||||
@@ -134,7 +129,7 @@ namespace Demo.Game
|
||||
// 打开手动编辑
|
||||
try
|
||||
{
|
||||
DefaultScriptUtility.OpenScriptFile(targetChildSO);
|
||||
ScriptUtility.OpenScriptFile(targetChildSO);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -217,7 +212,7 @@ namespace Demo.Game
|
||||
// Open Script
|
||||
new("Open",_=>
|
||||
{
|
||||
DefaultScriptUtility.OpenScriptFile(self);
|
||||
ScriptUtility.OpenScriptFile(self);
|
||||
}),
|
||||
new("<color=red>----------</color>",_=>{ })
|
||||
};
|
||||
|
||||
@@ -69,12 +69,7 @@ namespace Demo.Game
|
||||
/// 加载附属场景
|
||||
/// </summary>
|
||||
/// <param name="project"></param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
加载附属场景
|
||||
</summary>
|
||||
<param name=""project""></param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void Load(string project)
|
||||
{
|
||||
this.project = project;
|
||||
|
||||
@@ -130,12 +130,7 @@ namespace Demo.Game
|
||||
/// 设置更新对象
|
||||
/// </summary>
|
||||
/// <param name="path">脚本的相对路径</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
设置更新对象
|
||||
</summary>
|
||||
<param name=""path"">脚本的相对路径</param>
|
||||
")]
|
||||
[Convention.RScript.Variable.Attr.Method]
|
||||
public void SetUpdateTarget(string path)
|
||||
{
|
||||
var temp = FindWithPath(path);
|
||||
|
||||
Submodule Assets/Scripts/Framework/[RScript] updated: 58f3d1067c...29dd4f5d96
Reference in New Issue
Block a user