异步加载已修复, Config更新正推动

This commit is contained in:
2025-12-18 15:11:33 +08:00
parent 1436080fd6
commit ab60b35be2
20 changed files with 190 additions and 132 deletions

View File

@@ -250,7 +250,7 @@ namespace Demo.Game
}
yield break;
}
yield return Foo(rootGameObject.ParseFromScriptFile2Expr(rootObject));//ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));
yield return ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));//Foo(rootGameObject.ParseFromScriptFile2Expr(rootObject));
int applyDownCount = 0;
void NDFS(ScriptableObject current)
{
@@ -264,6 +264,7 @@ namespace Demo.Game
IEnumerator NDFSFoo()
{
yield return current.ApplyScript();
current.ResetEnterGameStatus();
applyDownCount--;
}
ConventionUtility.StartCoroutine(NDFSFoo());
@@ -291,6 +292,27 @@ namespace Demo.Game
using var stream = new FileInfo(projectBinaryFile).OpenRead();
using var reader = new BinaryReader(stream);
rootGameObject.Config.Deserialize(reader);
int applyDownCount = 0;
void NDFS(ScriptableObject current)
{
foreach (var child in current.Childs)
{
NDFS(child);
}
if (current.IsScriptApply == false)
{
applyDownCount++;
IEnumerator NDFSFoo()
{
yield return current.ApplyScript();
current.ResetEnterGameStatus();
applyDownCount--;
}
ConventionUtility.StartCoroutine(NDFSFoo());
}
}
NDFS(rootGameObject);
yield return new WaitUntil(() => applyDownCount == 0);
}
float loadRootObjectEndTime = Time.realtimeSinceStartup;
float loadRootObjectElapsed = (loadRootObjectEndTime - loadRootObjectStartTime) * 1000f;

View File

@@ -38,12 +38,12 @@ namespace Demo.Game
public class ScriptLoadableConfig
{
[Content] public int UID = -1;
[Content] public Vector3 EnterGameLocalPosition = Vector3.zero, EnterGameEulerAngles = Vector3.zero, EnterGameLocalScaling = Vector3.zero;
[Content] public Vector3 EnterGameLocalPosition = Vector3.zero, EnterGameEulerAngles = Vector3.zero, EnterGameLocalScaling = Vector3.one;
[Content] public bool IsSetObjectDisable = false;
[Content] public int UpdatePerFrame = 1;
[Setting] public string ScriptName = "";
private string[] ChildTypes = null;
private int[] ChildTypes = null;
private ScriptLoadableConfig[] childs = null;
[Setting] public ScriptableObject target;
@@ -57,12 +57,12 @@ namespace Demo.Game
IsSetObjectDisable = BinarySerializeUtility.ReadBool(reader);
UpdatePerFrame = BinarySerializeUtility.ReadInt(reader);
ScriptName = BinarySerializeUtility.ReadString(reader);
ChildTypes = BinarySerializeUtility.DeserializeStringArray(reader);
ChildTypes = BinarySerializeUtility.DeserializeIntArray(reader);
int childCount = ChildTypes.Length;
childs = new ScriptLoadableConfig[childCount];
for (int i = 0; i < childCount; i++)
{
var scriptObject = DefaultInstantiate.GetScriptableObjectInstantiate()[ChildTypes[i]].Invoke();
var scriptObject = DefaultInstantiate.GetScriptableObjectInstantiate()[DefaultInstantiate.ScriptableObjectID2Typename[ChildTypes[i]]].Invoke();
scriptObject.EnableScript(target);
childs[i] = scriptObject.Config;
childs[i].Deserialize(reader);
@@ -78,7 +78,7 @@ namespace Demo.Game
BinarySerializeUtility.WriteInt(writer, UpdatePerFrame);
BinarySerializeUtility.WriteString(writer, ScriptName);
childs = (from child in target.Childs select child.Config).ToArray();
ChildTypes = (from child in childs select child.GetType().Name).ToArray();
ChildTypes = (from child in childs select DefaultInstantiate.ScriptableObjectTypename2ID[child.target.GetType().Name]).ToArray();
BinarySerializeUtility.SerializeArray(writer, ChildTypes);
foreach (var child in childs)
{
@@ -133,7 +133,7 @@ namespace Demo.Game
[Convention.RScript.Variable.Attr.Method]
public void SetLocalPosition(float x, float y, float z)
{
Config.EnterGameLocalPosition = new(x, y, z);
Config.EnterGameLocalPosition = transform.localPosition = new(x, y, z);
}
/// <summary>
/// 设置欧拉角
@@ -144,7 +144,7 @@ namespace Demo.Game
[Convention.RScript.Variable.Attr.Method]
public void SetLocalEulerAngles(float x, float y, float z)
{
Config.EnterGameEulerAngles = new(x, y, z);
Config.EnterGameEulerAngles = transform.localEulerAngles = new(x, y, z);
}
/// <summary>
/// 设置缩放
@@ -155,7 +155,7 @@ namespace Demo.Game
[Convention.RScript.Variable.Attr.Method]
public void SetLocalScaling(float x, float y, float z)
{
Config.EnterGameLocalScaling = new(x, y, z);
Config.EnterGameLocalScaling = transform.localScale= new(x, y, z);
}
/// <summary>
@@ -166,6 +166,7 @@ namespace Demo.Game
public void SetObjectDisable()
{
Config.IsSetObjectDisable = true;
gameObject.SetActive(false);
}
/// <summary>
@@ -678,9 +679,12 @@ namespace Demo.Game
MyHierarchyItem.Release();
MyHierarchyItem = null;
}
this.isEnableScript = false;
this.Parent = null;
this.name = "<Unload>";
if (this /*防假空*/)
{
this.isEnableScript = false;
this.Parent = null;
this.name = "<Unload>";
}
}
}

View File

@@ -7,6 +7,7 @@ using Dreamteck.Splines;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
@@ -32,26 +33,33 @@ namespace Demo
SharedModule.instance.OpenCustomMenu(item, result.ToArray());
}
static DefaultInstantiate()
{
s_ScriptableObjectInstantiate = new();
ScriptableObjectTypename2ID = new();
ScriptableObjectID2Typename = new();
int cnt = 0;
foreach (var type in Utility.SeekType(x => x.IsSubclassOf(typeof(ScriptableObject)) && x.GetCustomAttribute<Attr.ScriptableAttribute>() != null))
{
var attr = type.GetCustomAttribute<Attr.ScriptableAttribute>();
s_ScriptableObjectInstantiate.Add(type.Name, () => (ScriptableObject)ConventionUtility.InvokeMember(type.GetMethod(attr.generaterName), null));
}
var typelist = s_ScriptableObjectInstantiate.Keys.ToList();
typelist.Sort();
foreach (var type in typelist)
{
ScriptableObjectTypename2ID.Add(type, cnt);
ScriptableObjectID2Typename.Add(cnt, type);
cnt++;
}
}
private static Dictionary<string, Func<ScriptableObject>> s_ScriptableObjectInstantiate;
public readonly static Dictionary<string, int> ScriptableObjectTypename2ID;
public readonly static Dictionary<int, string> ScriptableObjectID2Typename;
public static Dictionary<string, Func<ScriptableObject>> GetScriptableObjectInstantiate()
{
//return s_ScriptableObjectInstantiate ??= new Dictionary<string, Func<ScriptableObject>>(GameObjectInstantiate
// .Union(DDTInstantiate)
// .Union(TickUpdatementInstantiate)
// .Union(MaterialUpdatementInstantiate)
// .Union(SplineInstantiate)
// .Union(JudgementInstantiate)
// .Union(SingleVolumeInstantiate));
if (s_ScriptableObjectInstantiate == null)
{
s_ScriptableObjectInstantiate = new();
foreach (var type in Utility.SeekType(x => x.IsSubclassOf(typeof(ScriptableObject)) && x.GetCustomAttribute<Attr.ScriptableAttribute>() != null))
{
var attr = type.GetCustomAttribute<Attr.ScriptableAttribute>();
s_ScriptableObjectInstantiate.Add(type.Name, () => (ScriptableObject)ConventionUtility.InvokeMember(type.GetMethod(attr.generaterName), null));
}
}
return s_ScriptableObjectInstantiate;
}
}

View File

@@ -32,12 +32,15 @@ namespace Demo.Game
[Scriptable]
public class SubWorld : ScriptableObject
{
protected override ConfigType.ScriptLoadableConfig MakeConfig()
{
return new ConfigType.SubWorldConfig();
}
public static SubWorld Make()
{
return new GameObject().AddComponent<SubWorld>();
}
[Content, SerializeField] private string project;
[Content, SerializeField] private GameController SubWorldGameController;
protected override IEnumerator DoSomethingDuringApplyScript()
@@ -47,7 +50,7 @@ namespace Demo.Game
ir.completed += x =>
{
SubWorldGameController = (from controller in FindObjectsByType<GameController>(FindObjectsSortMode.None)
where controller.RootSourcePath == project
where controller.RootSourcePath == GetConfig<ConfigType.SubWorldConfig>().project
select controller).First();
ConventionUtility.StartCoroutine(SubWorldGameController.GameInitBySubWorld(GetRoot().InputCatch));
};
@@ -66,7 +69,7 @@ namespace Demo.Game
[Convention.RScript.Variable.Attr.Method]
public void Load(string project)
{
this.project = project;
GetConfig<ConfigType.SubWorldConfig>().project = project;
}
}
}

View File

@@ -1,5 +1,6 @@
using Convention;
using Demo.Editor.UI;
using Demo.Game.ConfigType;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -115,39 +116,9 @@ namespace Demo.Game
public DataType Position = default;
public MathExtension.EaseCurveType easeCurveType = MathExtension.EaseCurveType.Linear;
}
[Serializable]
public struct UpdatementCompiledEntries: IDisposable
{
public NativeArray<float> TimePoints;
public NativeArray<DataType> Positions;
public NativeArray<MathExtension.EaseCurveType> EaseCurveTypes;
public readonly int Count;
public UpdatementCompiledEntries(NativeArray<float> timePoints,
NativeArray<DataType> positions,
NativeArray<MathExtension.EaseCurveType> easeCurveTypes,
int count)
{
TimePoints = timePoints;
Positions = positions;
EaseCurveTypes = easeCurveTypes;
Count = count;
}
public void Dispose()
{
if (TimePoints.IsCreated)
TimePoints.Dispose();
if (Positions.IsCreated)
Positions.Dispose();
if (EaseCurveTypes.IsCreated)
EaseCurveTypes.Dispose();
}
}
public int Content = 0;
private readonly List<UpdatementEntry> Entries = new();
public UpdatementCompiledEntries CompiledEntries;
protected abstract void UpdateData(DataType data);
protected abstract DataType Lerp(DataType begin, DataType end, float t);
@@ -170,18 +141,15 @@ namespace Demo.Game
private void BuildupCompiledEntriesAndReleaseEntries()
{
Entries.Sort((x, y) => x.TimePoint.CompareTo(y.TimePoint));
CompiledEntries = new(
new NativeArray<float>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory),
new NativeArray<DataType>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory),
new NativeArray<MathExtension.EaseCurveType>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory),
Entries.Count
);
GetConfig<UpdatementConfig<DataType>>().TimePoints = new NativeArray<float>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
GetConfig<UpdatementConfig<DataType>>().Positions = new NativeArray<DataType>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes = new NativeArray<MathExtension.EaseCurveType>(Entries.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
int index = 0;
foreach (var item in Entries)
{
CompiledEntries.TimePoints[index] = item.TimePoint;
CompiledEntries.Positions[index] = item.Position;
CompiledEntries.EaseCurveTypes[index] = item.easeCurveType;
GetConfig<UpdatementConfig<DataType>>().TimePoints[index] = item.TimePoint;
GetConfig<UpdatementConfig<DataType>>().Positions[index] = item.Position;
GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes[index] = item.easeCurveType;
index++;
}
Entries.Clear();
@@ -190,10 +158,10 @@ namespace Demo.Game
private void UpdateEntry(int start, float percent)
{
int head = start;
int tail = Mathf.Min(start + 1, CompiledEntries.Count - 1);
UpdateData(Lerp(CompiledEntries.Positions[start],
CompiledEntries.Positions[tail],
MathExtension.Evaluate(Mathf.Clamp01(percent), CompiledEntries.EaseCurveTypes[head])));
int tail = Mathf.Min(start + 1, GetConfig<UpdatementConfig<DataType>>().TimePoints.Length - 1);
UpdateData(Lerp(GetConfig<UpdatementConfig<DataType>>().Positions[start],
GetConfig<UpdatementConfig<DataType>>().Positions[tail],
MathExtension.Evaluate(Mathf.Clamp01(percent), GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes[head])));
}
protected override IEnumerator DoSomethingDuringApplyScript()
@@ -209,7 +177,7 @@ namespace Demo.Game
public override void ResetEnterGameStatus()
{
base.ResetEnterGameStatus();
if (CompiledEntries.Count <= 1)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.Length <= 1)
return;
UpdateEntry(0, 0);
}
@@ -217,7 +185,9 @@ namespace Demo.Game
public override IEnumerator UnloadScript()
{
Content = 0;
CompiledEntries = default;
GetConfig<UpdatementConfig<DataType>>().TimePoints.Dispose();
GetConfig<UpdatementConfig<DataType>>().Positions.Dispose();
GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes.Dispose();
yield return base.UnloadScript();
}
@@ -227,12 +197,12 @@ namespace Demo.Game
float GetPercentValue()
{
if (Content + 1 == CompiledEntries.Count)
if (Content + 1 == GetConfig<UpdatementConfig<DataType>>().TimePoints.Length)
return 1;
return (currentTime - CompiledEntries.TimePoints[Content]) / (CompiledEntries.TimePoints[Content + 1] - CompiledEntries.TimePoints[Content]);
return (currentTime - GetConfig<UpdatementConfig<DataType>>().TimePoints[Content]) / (GetConfig<UpdatementConfig<DataType>>().TimePoints[Content + 1] - GetConfig<UpdatementConfig<DataType>>().TimePoints[Content]);
}
if (CompiledEntries.Count <= 1)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.Length <= 1)
return;
switch (tickType)
{
@@ -240,17 +210,17 @@ namespace Demo.Game
case TickType.Start:
{
Content = 0;
while (Content + 1 < CompiledEntries.Count && CompiledEntries.TimePoints[Content + 1] < currentTime)
while (Content + 1 < GetConfig<UpdatementConfig<DataType>>().TimePoints.Length && GetConfig<UpdatementConfig<DataType>>().TimePoints[Content + 1] < currentTime)
Content++;
UpdateEntry(Content, GetPercentValue());
}
break;
default:
if (CompiledEntries.TimePoints[0] > currentTime)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints[0] > currentTime)
return;
if (Content + 1 < CompiledEntries.Count && CompiledEntries.TimePoints[Content + 1] < currentTime)
if (Content + 1 < GetConfig<UpdatementConfig<DataType>>().TimePoints.Length && GetConfig<UpdatementConfig<DataType>>().TimePoints[Content + 1] < currentTime)
Content++;
if (Content + 1 > CompiledEntries.Count)
if (Content + 1 > GetConfig<UpdatementConfig<DataType>>().TimePoints.Length)
return;
UpdateEntry(Content, GetPercentValue());
break;
@@ -259,21 +229,22 @@ namespace Demo.Game
public DataType Evaluate(float time)
{
if (CompiledEntries.Count == 0)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.Length == 0)
return default;
if (CompiledEntries.Count == 1)
return CompiledEntries.Positions[0];
if (time < CompiledEntries.TimePoints[0])
return CompiledEntries.Positions[0];
for (int i = 1; i < CompiledEntries.Count; i++)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.Length == 1)
return GetConfig<UpdatementConfig<DataType>>().Positions[0];
if (time < GetConfig<UpdatementConfig<DataType>>().TimePoints[0])
return GetConfig<UpdatementConfig<DataType>>().Positions[0];
for (int i = 1; i < GetConfig<UpdatementConfig<DataType>>().TimePoints.Length; i++)
{
if (CompiledEntries.TimePoints[i - 1] <= time && CompiledEntries.TimePoints[i] > time)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints[i - 1] <= time && GetConfig<UpdatementConfig<DataType>>().TimePoints[i] > time)
{
return Lerp(CompiledEntries.Positions[i - 1], CompiledEntries.Positions[i],
(time - CompiledEntries.TimePoints[i - 1]) / (CompiledEntries.TimePoints[i] - CompiledEntries.TimePoints[i - 1]));
return Lerp(GetConfig<UpdatementConfig<DataType>>().Positions[i - 1], GetConfig<UpdatementConfig<DataType>>().Positions[i],
(time - GetConfig<UpdatementConfig<DataType>>().TimePoints[i - 1]) /
(GetConfig<UpdatementConfig<DataType>>().TimePoints[i] - GetConfig<UpdatementConfig<DataType>>().TimePoints[i - 1]));
}
}
return CompiledEntries.Positions[^1];
return GetConfig<UpdatementConfig<DataType>>().Positions[^1];
}
[Content] public GameObject UpdateTarget;
@@ -293,15 +264,20 @@ namespace Demo.Game
/// <param name="item">实例在父类中控制</param>
protected override void SetupTimelineItem(TimelineItem item)
{
if (CompiledEntries.Count == 0)
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.Length == 0)
return;
item.SetupDuration(new(CompiledEntries.TimePoints[0], CompiledEntries.TimePoints[^1]), GetTimelineItemColor());
item.SetupDuration(new(GetConfig<UpdatementConfig<DataType>>().TimePoints[0], GetConfig<UpdatementConfig<DataType>>().TimePoints[^1]), GetTimelineItemColor());
}
private void OnDestroy()
{
CompiledEntries.Dispose();
if (GetConfig<UpdatementConfig<DataType>>().TimePoints.IsCreated)
GetConfig<UpdatementConfig<DataType>>().TimePoints.Dispose();
if (GetConfig<UpdatementConfig<DataType>>().Positions.IsCreated)
GetConfig<UpdatementConfig<DataType>>().Positions.Dispose();
if (GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes.IsCreated)
GetConfig<UpdatementConfig<DataType>>().EaseCurveTypes.Dispose();
}
}
}