This commit is contained in:
2025-12-19 09:32:30 +08:00
5 changed files with 115 additions and 82 deletions

View File

@@ -1,10 +1,9 @@
using Convention;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Convention;
using Unity.Cinemachine;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
@@ -53,7 +52,97 @@ namespace Demo.Game
[Resources] public Transform GlobalLight;
private bool IsGameLoading = false;
private IEnumerator LoadWithRecompile(RootObject rootGameObject,
ToolFile rootObject,
Dictionary<string, string> projectHash,
ToolFile projectHashFile,
ToolFile cacheDir)
{
static IEnumerator Foo(IEnumerator ir)
{
Stack<IEnumerator> loadingTask = new();
loadingTask.Push(ir);
while (loadingTask.Count > 0)
{
if (loadingTask.Peek().MoveNext())
{
if (loadingTask.Peek().Current is IEnumerator next)
loadingTask.Push(next);
else if (loadingTask.Peek().Current is ScriptableObject)
yield return null;
}
else
{
loadingTask.Pop();
}
}
yield break;
}
yield return ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));
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);
projectHash.Clear();
foreach (var path in rootGameObject.LoadedScriptSet)
{
projectHash.Add(path, new ToolFile(path).CalculateHash());
}
// 哈希缓存
projectHashFile.SaveAsJson(projectHash);
// 编译结果
var projectBinaryFile = cacheDir | "project.dat";
using var stream = new FileInfo(projectBinaryFile).OpenWrite();
using var writer = new BinaryWriter(stream);
rootGameObject.Config.Serialize(writer);
}
private IEnumerator LoadFromCompiled(RootObject rootGameObject, ToolFile cacheDir)
{
// 加载
var projectBinaryFile = cacheDir | "project.dat";
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);
}
public IEnumerator GameInit()
{
IsGameLoading = true;
@@ -214,7 +303,8 @@ namespace Demo.Game
projectHash = projectHashFile.LoadAsJson<Dictionary<string, string>>();
foreach (var (file, md5) in projectHash)
{
if (new ToolFile(file).CalculateHash() != md5)
var scriptFile = new ToolFile(file);
if (scriptFile.Exists() == false || scriptFile.CalculateHash() != md5)
{
isRecompile = true;
break;
@@ -231,71 +321,13 @@ namespace Demo.Game
rootGameObject.SetContent(nameof(SongOffset), SongOffset);
rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0);
rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length);
if (isRecompile || true)
if (isRecompile)
{
yield return ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));
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);
projectHash.Clear();
foreach (var path in rootGameObject.LoadedScriptSet)
{
projectHash.Add(path, new ToolFile(path).CalculateHash());
}
// 哈希缓存
projectHashFile.SaveAsJson(projectHash);
// 编译结果
var projectBinaryFile = cacheDir | "project.dat";
using var stream = new FileInfo(projectBinaryFile).OpenWrite();
using var writer = new BinaryWriter(stream);
rootGameObject.Config.Serialize(writer);
yield return LoadWithRecompile(rootGameObject, rootObject, projectHash, projectHashFile, cacheDir);
}
else
{
// 加载
var projectBinaryFile = cacheDir | "project.dat";
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);
yield return LoadFromCompiled(rootGameObject, cacheDir);
}
float loadRootObjectEndTime = Time.realtimeSinceStartup;
float loadRootObjectElapsed = (loadRootObjectEndTime - loadRootObjectStartTime) * 1000f;

View File

@@ -42,10 +42,11 @@ namespace Demo.Game
[Content] public bool IsSetObjectDisable = false;
[Content] public int UpdatePerFrame = 1;
[Setting] public string ScriptName = "";
private int[] ChildTypes = null;
private string[] ChildNames = null;
private ScriptLoadableConfig[] childs = null;
[Setting] public ScriptableObject target;
public virtual void Deserialize(BinaryReader reader)
@@ -56,14 +57,13 @@ namespace Demo.Game
EnterGameLocalScaling = BinarySerializeUtility.ReadVec3(reader);
IsSetObjectDisable = BinarySerializeUtility.ReadBool(reader);
UpdatePerFrame = BinarySerializeUtility.ReadInt(reader);
ScriptName = BinarySerializeUtility.ReadString(reader);
ChildTypes = BinarySerializeUtility.DeserializeIntArray(reader);
ChildNames = BinarySerializeUtility.DeserializeStringArray(reader);
int childCount = ChildTypes.Length;
childs = new ScriptLoadableConfig[childCount];
for (int i = 0; i < childCount; i++)
{
var scriptObject = DefaultInstantiate.GetScriptableObjectInstantiate()[DefaultInstantiate.ScriptableObjectID2Typename[ChildTypes[i]]].Invoke();
scriptObject.EnableScript(target);
var scriptObject = target.NewSubScript(DefaultInstantiate.ScriptableObjectID2Typename[ChildTypes[i]], ChildNames[i]);
childs[i] = scriptObject.Config;
childs[i].Deserialize(reader);
}
@@ -76,10 +76,11 @@ namespace Demo.Game
BinarySerializeUtility.WriteVec3(writer, EnterGameLocalScaling);
BinarySerializeUtility.WriteBool(writer, IsSetObjectDisable);
BinarySerializeUtility.WriteInt(writer, UpdatePerFrame);
BinarySerializeUtility.WriteString(writer, ScriptName);
childs = (from child in target.Childs select child.Config).ToArray();
ChildTypes = (from child in childs select DefaultInstantiate.ScriptableObjectTypename2ID[child.target.GetType().Name]).ToArray();
ChildNames = (from child in childs select child.target.ScriptName).ToArray();
BinarySerializeUtility.SerializeArray(writer, ChildTypes);
BinarySerializeUtility.SerializeArray(writer, ChildNames);
foreach (var child in childs)
{
child.Serialize(writer);
@@ -227,11 +228,7 @@ namespace Demo.Game
public static float OneBarTime = 60;
private bool isEnableScript = false;
public string ScriptName
{
get => Config.ScriptName;
set => Config.ScriptName = value;
}
[Setting] public string ScriptName;
private string s_ScriptType = null;
public string m_ScriptType
{
@@ -338,7 +335,7 @@ namespace Demo.Game
return result;
}
public void EnableScript(ScriptableObject parent,int uid = -1)
public void EnableScript(ScriptableObject parent)
{
if (isEnableScript)
{
@@ -360,12 +357,13 @@ namespace Demo.Game
this.name = ScriptName;
isEnableScript = true;
// 只有RootObject的parent会是空的
if (uid < 0)
if (Config.UID < 0)
Config.UID = GetRoot().PushLoadedScriptObject(this);
else
GetRoot().PushLoadedScriptObject(this, uid);
GetRoot().PushLoadedScriptObject(this, Config.UID);
isEnableScript = true;
// 只有RootObject的parent会是空的
if (parent != null)
{
MyHierarchyItem = parent.MyHierarchyItem.GetHierarchyItem().CreateSubPropertyItem(1)[0];

View File

@@ -113,7 +113,10 @@ namespace Demo.Game
get
{
if (m_MyMeshRenderer == null)
{
m_MyMeshRenderer = this.GetOrAddComponent<MeshRenderer>();
m_MyMeshRenderer.material = StaticCacheDefaultMaterial;
}
return m_MyMeshRenderer;
}
}