Files
Convention-Unity-Demo/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs
2025-09-25 19:04:05 +08:00

234 lines
10 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Convention;
using Convention.WindowsUI.Variant;
using Dreamteck.Splines;
using UnityEngine;
namespace Demo.Game
{
public static class DefaultInstantiate
{
public static Dictionary<string, Func<ScriptableObject>> GameObjectInstantiate = new()
{
{ $"{nameof(Anchor)}",Anchor.Make},
// Camera
{ $"{nameof(CameraObject)}",CameraObject.MakeCameraObject},
// Global Env
{ $"{nameof(PrefabRootObject)}",PrefabRootObject.Make },
{ $"{nameof(SkyUpdatement)}",SkyUpdatement.Make},
// Sub World
{ $"{nameof(SubWorld)}",SubWorld.Make},
};
public static Dictionary<string, Func<ScriptableObject>> DDTInstantiate = new()
{
{ $"{nameof(DDT)}",DDT.Make}
};
public static Dictionary<string, Func<ScriptableObject>> TickUpdatementInstantiate = new ()
{
{ $"{nameof(LookAtAnchor)}",LookAtAnchor.Make},
{ $"{nameof(TickMovement)}",TickMovement.Make},
{ $"{nameof(TickRotation)}",TickRotation.Make},
{ $"{nameof(TickScaling)}",TickScaling.Make},
};
public static Dictionary<string, Func<ScriptableObject>> MaterialUpdatementInstantiate = new()
{
{ $"{nameof(MaterialUpdatement)}",MaterialUpdatement.Make},
{ $"{nameof(ColorUpdatement)}",ColorUpdatement.Make},
{ $"{nameof(EmissionColorUpdatement)}",EmissionColorUpdatement.Make},
};
public static Dictionary<string, Func<ScriptableObject>> SplineInstantiate = new()
{
{ $"{nameof(SplineCore)}",SplineCore.Make},
{ $"{nameof(SplineNode)}",SplineNode.Make},
{ $"{nameof(SplineAnchor)}",SplineAnchor.Make},
{ $"{nameof(SplineMovement)}",SplineMovement.Make},
{ $"{nameof(SplineRotation)}",SplineRotation.Make},
{ $"{nameof(SplineScaling)}",SplineScaling.Make},
{ $"{nameof(SplineHeadObject)}",SplineHeadObject.Make},
{ $"{nameof(SplineTrackRenderer)}",SplineTrackRenderer.Make},
{ $"{nameof(SplineTubeRenderer)}",SplineTubeRenderer.Make},
};
public static Dictionary<string, Func<ScriptableObject>> JudgementInstantiate = new()
{
// 可判定物只能有一个种类被使用,否则会引起输入检定冲突
{ $"{nameof(FullScreenInteraction)}",FullScreenInteraction.Make},
// Effect
{ $"{nameof(ParticleEffect)}",ParticleEffect.Make },
// JudgementEffect
{ $"{nameof(ParticleJudgement)}",ParticleJudgement.Make},
};
public static void GenerateLayerMenu(ScriptableObject so, RectTransform item, Dictionary<string, Func<ScriptableObject>> calls)
{
List<SharedModule.CallbackData> result = new();
foreach (var instantiaterPair in calls)
{
var type = instantiaterPair.Key;
var invoker = instantiaterPair.Value;
void LoadSubScriptWrapper(Vector3 _)
{
// 构建默认名称
var childDirName = Path.Combine(so.SourcePath, so.ScriptName);
var childDir = new ToolFile(childDirName);
var childName = type;
int childIndex = 1;
var childFullNameWithoutExtension = childName;
var extension = so.GetRoot().RootGameController.CurrentProjectDefaultFileStyle switch
{
ProjectDefaultFileStyle.CPP => ".h",
ProjectDefaultFileStyle.PY => ".py",
_ => ""
};
if (childDir.Exists())
{
childFullNameWithoutExtension = $"{childName}{(childIndex == 1 ? "" : childIndex.ToString())}";
while (childDir | $"{childFullNameWithoutExtension}{extension}")
{
childIndex++;
childFullNameWithoutExtension = $"{childName}{childIndex}";
}
}
var childFullName = childFullNameWithoutExtension + extension;
var chlidPath = Path.Combine(childDirName, childFullName);
SharedModule.instance.SingleEditString("Generate Sub Script", chlidPath, x =>
{
//用户不一定使用默认名称,用真实输入重新转换
ToolFile childFile = File.Exists(x) ? new(x) : new(Path.Combine(so.SourcePath, x));
if (childFile.MustExistsPath())
{
if (so is not RootObject && so.FindWithPath(x, false) != null)
{
Debug.LogError($"SubScript {x} is exists", so);
return;
}
else
{
using var fs = File.AppendText(so.ScriptPath);
var childFilePath = childFile.GetFullPath().Replace('\\', '/');
var path2 = so.SourcePath.TrimEnd('\\', '/').Replace('\\', '/');
if (childFilePath.StartsWith(path2))
{
x = childFilePath[path2.Length..].TrimStart('\\', '/');
}
fs.Write($"\n{nameof(so.LoadSubScript)}({type}, \"{x}\");");
// 新建时添加模板内容
using var childFileStream = File.AppendText(childFile);
{
DefaultScriptUtility.WriteDefaultScript(childFileStream, ScriptableObject.FastScriptableObjectTypen[type]);
childFileStream.Close();
}
//不刷新世界,直接加载
var targetChildSO = so.LoadSubScript(type, childFile);
// 打开手动编辑
try
{
DefaultScriptUtility.OpenScriptFile(targetChildSO);
}
catch (Exception ex)
{
Debug.LogError($"Cannt open {childFile}", so);
Debug.LogException(ex, so);
}
}
}
else
{
Debug.LogError($"SubScript {x} is failed to generate", so);
}
});
}
result.Add(new(type, LoadSubScriptWrapper));
}
SharedModule.instance.OpenCustomMenu(item, result.ToArray());
}
public static void GetGenerateData(ScriptableObject so, RectTransform item, List<SharedModule.CallbackData> result)
{
result.Add(new(nameof(GameObject), _ =>
{
GenerateLayerMenu(so, item, GameObjectInstantiate);
}));
result.Add(new(nameof(DDT), _ =>
{
GenerateLayerMenu(so, item, DDTInstantiate);
}));
result.Add(new(nameof(Transform), _ =>
{
GenerateLayerMenu(so, item, TickUpdatementInstantiate);
}));
result.Add(new(nameof(Material), _ =>
{
GenerateLayerMenu(so, item, MaterialUpdatementInstantiate);
}));
result.Add(new(nameof(Spline), _ =>
{
GenerateLayerMenu(so, item, SplineInstantiate);
}));
result.Add(new("Judge & Effect", _ =>
{
GenerateLayerMenu(so, item, JudgementInstantiate);
}));
}
public static void OpenInstantiateMenu(this ScriptableObject self, RectTransform item)
{
List<SharedModule.CallbackData> result = new()
{
// Show Name
new($"In {self.SourcePath}",_=>{ }),
new($"At {self.ScriptName}",_=>{ }),
new($"Is {self.ScriptTypename}",_=>{ }),
new("<color=red>----------</color>",_=>{ }),
// Load Operator
new("Reload", _ =>
{
IEnumerator Foo()
{
var sourcePath =self.SourcePath;
var scriptPath = self.ScriptPath;
var scriptType =self.ScriptTypename;
var parent = self.Parent;
yield return self.UnloadScript();
foreach (var child in self.Childs)
{
UnityEngine.Object.Destroy(child.gameObject);
}
self.Childs.Clear();
self.EnableScript(sourcePath,scriptPath,scriptType,parent);
yield return self.LoadScript(new ToolFile(self.ScriptPath).LoadAsText());
}
self.GetRoot().RootGameController.StartCoroutine(Foo());
}),
// Open Script
new("Open",_=>
{
DefaultScriptUtility.OpenScriptFile(self);
}),
new("<color=red>----------</color>",_=>{ })
};
GetGenerateData(self,item, result);
SharedModule.instance.OpenCustomMenu(item, result.ToArray());
}
public static Dictionary<string, Func<ScriptableObject>> GetScriptableObjectInstantiate()
{
return new Dictionary<string, Func<ScriptableObject>>(GameObjectInstantiate.Union(TickUpdatementInstantiate)
.Union(MaterialUpdatementInstantiate)
.Union(SplineInstantiate)
.Union(JudgementInstantiate));
}
}
}