加载性能优化, 暂时放弃异步加载
This commit is contained in:
Submodule Assets/Convention updated: 223df3fb91...a3483f23d8
@@ -1,2 +1,15 @@
|
|||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
[CustomEditor(typeof(Demo.Game.GameController), true)]
|
||||||
|
public class GameControllerEditor : Convention.AbstractCustomEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomEditor(typeof(Demo.Editor.EditorController), true)]
|
||||||
|
public class EditorControllerEditor : Convention.AbstractCustomEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace Demo.Game
|
|||||||
Datas.Dispose();
|
Datas.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region MyRegion
|
#region Serialize
|
||||||
|
|
||||||
protected override bool IsImptSerialize => true;
|
protected override bool IsImptSerialize => true;
|
||||||
protected override IEnumerator CreateAndLoadingImptCacheFile(ToolFile scriptFile, ToolFile cacheFile)
|
protected override IEnumerator CreateAndLoadingImptCacheFile(ToolFile scriptFile, ToolFile cacheFile)
|
||||||
@@ -69,10 +69,10 @@ namespace Demo.Game
|
|||||||
yield return this.ParseScript2Expr(scriptFile.LoadAsText());
|
yield return this.ParseScript2Expr(scriptFile.LoadAsText());
|
||||||
using var stream = File.OpenWrite(cacheFile.GetFullPath());
|
using var stream = File.OpenWrite(cacheFile.GetFullPath());
|
||||||
using var writer = new BinaryWriter(stream);
|
using var writer = new BinaryWriter(stream);
|
||||||
writer.Write(Datas.Length);
|
writer.Write(Count);
|
||||||
foreach (var i in Datas)
|
for (int i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
writer.Write(i);
|
writer.Write(Datas[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected override IEnumerator LoadFromImptCacheFile(ToolFile cacheFile)
|
protected override IEnumerator LoadFromImptCacheFile(ToolFile cacheFile)
|
||||||
@@ -80,7 +80,7 @@ namespace Demo.Game
|
|||||||
using var stream = File.OpenRead(cacheFile.GetFullPath());
|
using var stream = File.OpenRead(cacheFile.GetFullPath());
|
||||||
using var reader = new BinaryReader(stream);
|
using var reader = new BinaryReader(stream);
|
||||||
Count = reader.ReadInt32();
|
Count = reader.ReadInt32();
|
||||||
Datas = new NativeArray<float>(Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
|
Datas.ResizeArray(Mathf.Max(128, Count));
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
Datas[i] = reader.ReadSingle();
|
Datas[i] = reader.ReadSingle();
|
||||||
@@ -89,5 +89,16 @@ namespace Demo.Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[Setting, SerializeField] private List<float> d_Datas = new();
|
||||||
|
protected override IEnumerator DoSomethingDuringApplyScript()
|
||||||
|
{
|
||||||
|
yield return base.DoSomethingDuringApplyScript();
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
d_Datas.Add(Datas[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ namespace Demo.Game
|
|||||||
{
|
{
|
||||||
public partial class GameController : MonoBehaviour
|
public partial class GameController : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[Resources]
|
||||||
|
public void DebugGetScriptCounter()
|
||||||
|
{
|
||||||
|
Debug.Log(ScriptableObject.s_DebugContainer.Count, this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[Resources, SerializeField] public BasicAudioSystem MainAudio;
|
[Resources, SerializeField] public BasicAudioSystem MainAudio;
|
||||||
[Resources, SerializeField] private CinemachineVirtualCameraBase MainCamera;
|
[Resources, SerializeField] private CinemachineVirtualCameraBase MainCamera;
|
||||||
[Resources, SerializeField] public GlobalConfig MainConfig;
|
[Resources, SerializeField] public GlobalConfig MainConfig;
|
||||||
@@ -201,46 +209,37 @@ namespace Demo.Game
|
|||||||
rootGameObject.SetContent(nameof(SongOffset), SongOffset);
|
rootGameObject.SetContent(nameof(SongOffset), SongOffset);
|
||||||
rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0);
|
rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0);
|
||||||
rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length);
|
rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length);
|
||||||
Stack<IEnumerator> loadingTask = new();
|
static IEnumerator Foo(IEnumerator ir)
|
||||||
loadingTask.Push(rootGameObject.ParseFromScriptFile2Expr(rootObject));
|
|
||||||
float waitClock = Time.realtimeSinceStartup;
|
|
||||||
Dictionary<Type, int> DebugCounter = new();
|
|
||||||
while (loadingTask.Count > 0)
|
|
||||||
{
|
{
|
||||||
// 防止大量无延迟函数如NewSubObject的使用导致的假死机
|
Stack<IEnumerator> loadingTask = new();
|
||||||
if (Time.realtimeSinceStartup - waitClock > 0.1f)
|
loadingTask.Push(ir);
|
||||||
|
while (loadingTask.Count > 0)
|
||||||
{
|
{
|
||||||
yield return null;
|
if (loadingTask.Peek().MoveNext())
|
||||||
waitClock = Time.realtimeSinceStartup;
|
{
|
||||||
|
if (loadingTask.Peek().Current is IEnumerator next)
|
||||||
|
loadingTask.Push(next);
|
||||||
|
else if (loadingTask.Peek().Current is ScriptableObject)
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadingTask.Pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (loadingTask.Peek().MoveNext())
|
yield break;
|
||||||
{
|
|
||||||
if (loadingTask.Peek().Current is IEnumerator next)
|
|
||||||
loadingTask.Push(next);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
loadingTask.Pop();
|
|
||||||
}
|
|
||||||
yield return null;
|
|
||||||
}
|
}
|
||||||
int NDFSCount = 0;
|
yield return Foo(rootGameObject.ParseFromScriptFile2Expr(rootObject));//ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));
|
||||||
IEnumerator NDFS(ScriptableObject current)
|
static void NDFS(ScriptableObject current)
|
||||||
{
|
{
|
||||||
foreach (var child in current.Childs)
|
foreach (var child in current.Childs)
|
||||||
{
|
{
|
||||||
ConventionUtility.StartCoroutine(NDFS(child));
|
NDFS(child);
|
||||||
NDFSCount++;
|
|
||||||
if(NDFSCount % 100 == 0)
|
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (current.IsScriptApply == false)
|
if (current.IsScriptApply == false)
|
||||||
ConventionUtility.StartCoroutine(current.ApplyScript());
|
ConventionUtility.StartCoroutine(current.ApplyScript());
|
||||||
}
|
}
|
||||||
//yield return
|
NDFS(rootGameObject);
|
||||||
ConventionUtility.StartCoroutine(NDFS(rootGameObject));
|
|
||||||
float loadRootObjectEndTime = Time.realtimeSinceStartup;
|
float loadRootObjectEndTime = Time.realtimeSinceStartup;
|
||||||
float loadRootObjectElapsed = (loadRootObjectEndTime - loadRootObjectStartTime) * 1000f;
|
float loadRootObjectElapsed = (loadRootObjectEndTime - loadRootObjectStartTime) * 1000f;
|
||||||
Debug.Log($"[GameInit] Load Root Object 耗时: {loadRootObjectElapsed:F2} ms", this);
|
Debug.Log($"[GameInit] Load Root Object 耗时: {loadRootObjectElapsed:F2} ms", this);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace Demo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ScriptableObject
|
public partial class ScriptableObject
|
||||||
{
|
{
|
||||||
public Dictionary<string, float> ScriptableObjectContents = new();
|
public readonly Dictionary<string, float> ScriptableObjectContents = new();
|
||||||
|
|
||||||
[Convention.RScript.Variable.Attr.Method]
|
[Convention.RScript.Variable.Attr.Method]
|
||||||
public float GetContent(string key)
|
public float GetContent(string key)
|
||||||
@@ -120,10 +120,6 @@ namespace Demo
|
|||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (Parent != null)
|
|
||||||
{
|
|
||||||
return Parent.GetContent(key);
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException($"Key {key} is not find in contnet");
|
throw new InvalidOperationException($"Key {key} is not find in contnet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +250,8 @@ namespace Demo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.Parent = parent;
|
this.Parent = parent;
|
||||||
|
if (parent != null)
|
||||||
|
this.ScriptableObjectContents.AddRange(parent.ScriptableObjectContents);
|
||||||
|
|
||||||
this.name = ScriptName;
|
this.name = ScriptName;
|
||||||
|
|
||||||
@@ -470,9 +468,21 @@ namespace Demo
|
|||||||
#endif
|
#endif
|
||||||
IHierarchyItemClickEventListener
|
IHierarchyItemClickEventListener
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
internal static readonly HashSet<ScriptableObject> s_DebugContainer = new();
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
s_DebugContainer.Add(this);
|
||||||
|
}
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
s_DebugContainer.Remove(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected virtual IEnumerator DoSomethingDuringApplyScript()
|
protected virtual IEnumerator DoSomethingDuringApplyScript()
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
@@ -497,16 +507,18 @@ namespace Demo
|
|||||||
{
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
if (IsScriptApply)
|
||||||
|
yield break;
|
||||||
// 等待自身脚本解析完毕
|
// 等待自身脚本解析完毕
|
||||||
while (this.IsParseScript2Expr)
|
while (this.IsParseScript2Expr)
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return this;
|
||||||
while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0)
|
}
|
||||||
{
|
while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0)
|
||||||
LoadingTaskCoroutineCount++;
|
{
|
||||||
ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value);
|
LoadingTaskCoroutineCount++;
|
||||||
WaitingTaskForLoadingCoroutine.RemoveFirst();
|
ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value);
|
||||||
}
|
WaitingTaskForLoadingCoroutine.RemoveFirst();
|
||||||
}
|
}
|
||||||
yield return DoSomethingDuringApplyScript();
|
yield return DoSomethingDuringApplyScript();
|
||||||
// 增数
|
// 增数
|
||||||
@@ -525,36 +537,37 @@ namespace Demo
|
|||||||
GetRoot().UpdateChilds[type] = new() { this };
|
GetRoot().UpdateChilds[type] = new() { this };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 释放资源
|
||||||
|
{
|
||||||
|
this.ScriptableObjectContents.Clear();
|
||||||
|
}
|
||||||
IsScriptApply = true;
|
IsScriptApply = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerator UnloadScript()
|
public virtual IEnumerator UnloadScript()
|
||||||
{
|
{
|
||||||
if (EnsureEnableScript())
|
if (IsScriptApply)
|
||||||
{
|
{
|
||||||
this.name = "<Unloading>";
|
this.name = "<Unloading>";
|
||||||
foreach (var child in Childs)
|
foreach (var child in Childs)
|
||||||
{
|
{
|
||||||
ConventionUtility.StartCoroutine(child.UnloadScript());
|
ConventionUtility.StartCoroutine(child.UnloadScript());
|
||||||
}
|
}
|
||||||
if (IsScriptApply)
|
yield return new WaitUntil(() => Childs.Any(x => x.isEnableScript == false) == false);
|
||||||
{
|
// 清理各种状态
|
||||||
// 清理各种状态
|
IsScriptApply = false;
|
||||||
IsScriptApply = false;
|
// 清理Cache
|
||||||
// 清理Cache
|
//
|
||||||
//
|
// 减数
|
||||||
// 减数
|
ApplyScriptableObjectCounter--;
|
||||||
ApplyScriptableObjectCounter--;
|
EnableScriptableObjectCounter--;
|
||||||
EnableScriptableObjectCounter++;
|
AllScriptableObjectCounterHierarchyItem.GetHierarchyItem().text = $"SOC: {ApplyScriptableObjectCounter}/{EnableScriptableObjectCounter}";
|
||||||
AllScriptableObjectCounterHierarchyItem.GetHierarchyItem().text = $"SOC: {ApplyScriptableObjectCounter}/{EnableScriptableObjectCounter}";
|
|
||||||
}
|
|
||||||
if (MyHierarchyItem != null)
|
if (MyHierarchyItem != null)
|
||||||
{
|
{
|
||||||
// 卸载UI
|
// 卸载UI
|
||||||
MyHierarchyItem.Release();
|
MyHierarchyItem.Release();
|
||||||
MyHierarchyItem = null;
|
MyHierarchyItem = null;
|
||||||
}
|
}
|
||||||
yield return new WaitUntil(() => Childs.Any(x => x.isEnableScript == false) == false);
|
|
||||||
this.isEnableScript = false;
|
this.isEnableScript = false;
|
||||||
this.Parent = null;
|
this.Parent = null;
|
||||||
this.name = "<Unload>";
|
this.name = "<Unload>";
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ namespace Demo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<string, object> s_FileLocker = new();
|
private static readonly Dictionary<string, object> s_FileLocker = new();
|
||||||
private static readonly Dictionary<string, RScriptEngine> s_RScriptEngineCache = new();
|
|
||||||
|
|
||||||
public IEnumerator ParseFromScriptFile2Expr(ToolFile file)
|
public IEnumerator ParseFromScriptFile2Expr(ToolFile file)
|
||||||
{
|
{
|
||||||
@@ -263,79 +262,59 @@ namespace Demo
|
|||||||
{
|
{
|
||||||
lastHashFile.MustExistsPath();
|
lastHashFile.MustExistsPath();
|
||||||
lastHashFile.SaveAsText(hash);
|
lastHashFile.SaveAsText(hash);
|
||||||
yield return CreateAndLoadingImptCacheFile(file, bin);
|
yield return ConventionUtility.AvoidFakeStop(CreateAndLoadingImptCacheFile(file, bin));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yield return LoadFromImptCacheFile(bin);
|
yield return ConventionUtility.AvoidFakeStop(LoadFromImptCacheFile(bin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool is_engine_cached = false;
|
|
||||||
IEnumerator step = null;
|
IEnumerator step = null;
|
||||||
lock (s_RScriptEngineCache)
|
RScriptEngine engine = new();
|
||||||
is_engine_cached = s_RScriptEngineCache.ContainsKey(file.GetFullPath());
|
RScriptImportClass importClass = GenerateImport();
|
||||||
if (is_engine_cached == false)
|
RScriptVariables variables = GenerateVariables(this);
|
||||||
|
object locker;
|
||||||
|
if (lastHashFile.Exists() == false || lastHashFile.LoadAsText() != hash)
|
||||||
{
|
{
|
||||||
lock (s_RScriptEngineCache)
|
lastHashFile.MustExistsPath();
|
||||||
|
bin.MustExistsPath();
|
||||||
|
lastHashFile.SaveAsText(hash);
|
||||||
|
var script = file.LoadAsText();
|
||||||
|
|
||||||
|
var structBin = engine.Compile(script, importClass, variables);
|
||||||
|
lock (s_FileLocker)
|
||||||
{
|
{
|
||||||
RScriptEngine engine = new();
|
if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false)
|
||||||
RScriptImportClass importClass = GenerateImport();
|
|
||||||
RScriptVariables variables = GenerateVariables(this);
|
|
||||||
object locker;
|
|
||||||
if (lastHashFile.Exists() == false || lastHashFile.LoadAsText() != hash)
|
|
||||||
{
|
{
|
||||||
lastHashFile.MustExistsPath();
|
s_FileLocker.Add(file.GetFullPath(), locker = new object());
|
||||||
bin.MustExistsPath();
|
|
||||||
lastHashFile.SaveAsText(hash);
|
|
||||||
var script = file.LoadAsText();
|
|
||||||
|
|
||||||
var structBin = engine.Compile(script, importClass, variables);
|
|
||||||
lock (s_FileLocker)
|
|
||||||
{
|
|
||||||
if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false)
|
|
||||||
{
|
|
||||||
s_FileLocker.Add(file.GetFullPath(), locker = new object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lock (locker)
|
|
||||||
{
|
|
||||||
bin.SaveAsBinary(RScriptSerializer.SerializeClass(structBin));
|
|
||||||
}
|
|
||||||
step = engine.RunAsync(script, importClass, variables);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
RScriptContext.SerializableClass structBin;
|
|
||||||
lock (s_FileLocker)
|
|
||||||
{
|
|
||||||
if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false)
|
|
||||||
{
|
|
||||||
s_FileLocker.Add(file.GetFullPath(), locker = new object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lock (locker)
|
|
||||||
{
|
|
||||||
structBin = RScriptSerializer.DeserializeClass(bin.LoadAsBinary());
|
|
||||||
}
|
|
||||||
step = engine.RunAsync(structBin, importClass, variables);
|
|
||||||
|
|
||||||
}
|
|
||||||
s_RScriptEngineCache.Add(file.GetFullPath(), engine);
|
|
||||||
}
|
}
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
bin.SaveAsBinary(RScriptSerializer.SerializeClass(structBin));
|
||||||
|
}
|
||||||
|
step = engine.RunAsync(script, importClass, variables);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var engine = s_RScriptEngineCache[file.GetFullPath()];
|
RScriptContext.SerializableClass structBin;
|
||||||
lock (engine)
|
lock (s_FileLocker)
|
||||||
{
|
{
|
||||||
engine.context.Variables["this"] = new() { data = this, type = this.GetType() };
|
if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false)
|
||||||
engine.context.Variables["self"] = new() { data = this, type = this.GetType() };
|
{
|
||||||
step = engine.ReRunAsync();
|
s_FileLocker.Add(file.GetFullPath(), locker = new object());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
structBin = RScriptSerializer.DeserializeClass(bin.LoadAsBinary());
|
||||||
|
}
|
||||||
|
step = engine.RunAsync(structBin, importClass, variables);
|
||||||
|
|
||||||
}
|
}
|
||||||
yield return step;
|
yield return step;// ConventionUtility.AvoidFakeStop(step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -354,7 +333,7 @@ namespace Demo
|
|||||||
RScriptVariables variables = GenerateVariables(this);
|
RScriptVariables variables = GenerateVariables(this);
|
||||||
|
|
||||||
var step = engine.RunAsync(script, importClass, variables);
|
var step = engine.RunAsync(script, importClass, variables);
|
||||||
yield return step;
|
yield return step;//ConventionUtility.AvoidFakeStop(step);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
Submodule Assets/Scripts/Framework/[RScript] updated: e4b7dc0f55...0a7f6eb362
@@ -50,31 +50,33 @@ namespace Demo.Game
|
|||||||
|
|
||||||
public class SplineCore : ScriptableObject
|
public class SplineCore : ScriptableObject
|
||||||
{
|
{
|
||||||
|
protected override bool IsSelfEnableUpdate => false;
|
||||||
public static SplineCore Make()
|
public static SplineCore Make()
|
||||||
{
|
{
|
||||||
SplineCore result = new GameObject("").AddComponent<SplineCore>();
|
SplineCore result = new GameObject("").AddComponent<SplineCore>();
|
||||||
var core = result.GetOrAddComponent<SplineComputer>();
|
var core = result.GetOrAddComponent<SplineComputer>();
|
||||||
|
result.m_MySplineComputer = core;
|
||||||
core.multithreaded = true;
|
core.multithreaded = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Content] private SplineComputer m_MySplineComputer;
|
[Content] private SplineComputer m_MySplineComputer;
|
||||||
[Content] public int NodeContent = 0;
|
[Content] public int NodeContent = 0;
|
||||||
[Content] public readonly List<SplineNode> MySplineNodes = new();
|
[Content] public 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 SplineComputer MySplineComputer
|
public SplineComputer MySplineComputer => m_MySplineComputer;
|
||||||
{
|
//{
|
||||||
get
|
// get
|
||||||
{
|
// {
|
||||||
if(m_MySplineComputer==null)
|
// if (m_MySplineComputer == null)
|
||||||
m_MySplineComputer= GetComponent<SplineComputer>();
|
// m_MySplineComputer = this.GetComponent<SplineComputer>();
|
||||||
return m_MySplineComputer;
|
// return m_MySplineComputer;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="SplineCore"/>需要在子<see cref="SplineNode"/>都添加后再应用脚本才能使得节点生效
|
/// <see cref="SplineCore"/>需要在子<see cref="SplineNode"/>都添加后再应用脚本才能使得节点生效
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using Convention;
|
||||||
using Dreamteck.Splines;
|
using Dreamteck.Splines;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -10,7 +11,9 @@ namespace Demo.Game
|
|||||||
|
|
||||||
public static SplineNode Make()
|
public static SplineNode Make()
|
||||||
{
|
{
|
||||||
return new GameObject("", typeof(Node)).AddComponent<SplineNode>();
|
var node = new GameObject("", typeof(Node)).AddComponent<SplineNode>();
|
||||||
|
node.m_MyNode = node.GetOrAddComponent<Node>();
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node m_MyNode;
|
private Node m_MyNode;
|
||||||
@@ -21,15 +24,7 @@ namespace Demo.Game
|
|||||||
public int MyNodeContent = 0;
|
public int MyNodeContent = 0;
|
||||||
|
|
||||||
|
|
||||||
public Node MyNode
|
public Node MyNode => m_MyNode;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_MyNode == null)
|
|
||||||
m_MyNode = GetComponent<Node>();
|
|
||||||
return m_MyNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTo(SplineCore core)
|
public void AddTo(SplineCore core)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user