This commit is contained in:
2025-09-23 18:28:06 +08:00
parent 987e89b3fc
commit 4486e7dd82
11 changed files with 273 additions and 325 deletions

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Sirenix.OdinInspector;
using UnityEditor;
using UnityEngine;
namespace Stary.Evo.Editor
{
[Serializable]
public class CreatPointCloudEntity
{
private CreatPointCloudWindow window;
[HideInInspector]
public string id;
[HorizontalGroup("identifier")] [ReadOnly] public string sceneName;
[HorizontalGroup("identifier")][ReadOnly]
public string identifier;
[ReadOnly]
public string sceneDesc;
[HorizontalGroup("button")]
public bool isActive;
public CreatPointCloudEntity(CreatPointCloudWindow window)
{
this.window = window;
}
[HorizontalGroup("button")]
[Button("", Icon = SdfIconType.XCircle, IconAlignment = IconAlignment.RightEdge)]
public async void DeletePointCloud()
{
string ip = EditorPrefs.GetString("ip");
if (string.IsNullOrEmpty(ip))
{
EditorUtility.DisplayDialog("提示", "ip不能为空", "确定");
return;
}
ResultMessageEntity entity = await WebRequestSystem.Delete(ip,$"/SceneWork/DeleteScenebyId/{id}");
if (entity.code ==200)
{
window.SceneWorkEntities.Remove(this);
EditorUtility.DisplayDialog("提示", "删除成功", "确定");
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 98be6e863c2d42afa5636cddebe6275e
timeCreated: 1758614591

View File

@@ -2,341 +2,114 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
#if HotUpdate
using HybridCLR.Editor;
using HybridCLR.Editor.Settings;
#endif
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Stary.Evo.Editor.Entity;
using Unity.Plastic.Newtonsoft.Json;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace Stary.Evo.Editor
{
public class CreatAssetWindow : OdinEditorWindow
public class CreatPointCloudWindow : OdinEditorWindow
{
[MenuItem("Evo/创建Domain作用域")]
static void Init()
[MenuItem("Evo/创建PointCloud场景")]
static async void Init()
{
// Get existing open window or if none, make a new one:
CreatAssetWindow window = (CreatAssetWindow)EditorWindow.GetWindow(typeof(CreatAssetWindow));
CreatPointCloudWindow window = (CreatPointCloudWindow)EditorWindow.GetWindow(typeof(CreatPointCloudWindow));
window.Show();
window.identifier = Application.identifier;
}
[TitleGroup("创建Domain作用域")] public string domain;
[TitleGroup("创建")][InfoBox("场景名称")] public string sceneName;
[TitleGroup("创建")][InfoBox("场景描述")] public string sceneDesc;
[TitleGroup("创建"),ReadOnly] public string identifier;
[TitleGroup("创建Domain作用域")]
[Button("创建Domain", ButtonSizes.Large)]
[TitleGroup("创建")]
[Button("创建场景", ButtonSizes.Large)]
public async void CreatDomain()
{
// if (GetCreatDomainAll().Count>0)
// {
// EditorUtility.DisplayDialog("错误!", "Domain仅可以创建一个请在下方删除存在的Domain", "确定");
// return;
// }
if (string.IsNullOrEmpty(domain))
if (string.IsNullOrEmpty(sceneName)||string.IsNullOrEmpty(sceneDesc))
{
EditorUtility.DisplayDialog("错误!", "请输入将要创建Domain的编号", "确定");
EditorUtility.DisplayDialog("提示", "sceneName和sceneDesc不能为空", "确定");
return;
}
string artDomainPath = $"{Application.dataPath}/Art/{domain}";
if (!Directory.Exists(artDomainPath))
string ip = EditorPrefs.GetString("ip");
if (string.IsNullOrEmpty(ip))
{
Directory.CreateDirectory(artDomainPath);
if (!Directory.Exists(artDomainPath))
//创建Animation文件夹
CreatDirectory(artDomainPath + "/Animation");
//创建Effects文件夹
CreatDirectory(artDomainPath + "/Effects");
//创建Fbx文件夹
CreatDirectory(artDomainPath + "/Fbx");
//创建Font文件夹
CreatDirectory(artDomainPath + "/Font");
//创建Materials文件夹
CreatDirectory(artDomainPath + "/Materials");
//创建Prefabs文件夹
CreatDirectory(artDomainPath + "/Prefabs");
//创建Scenes文件夹
CreatDirectory(artDomainPath + "/Scenes");
//创建/Scenes/Test文件夹
CreatDirectory(artDomainPath + "/Scenes/Test");
//创建Shader文件夹
CreatDirectory(artDomainPath + "/Shader");
//创建Textures文件夹
CreatDirectory(artDomainPath + "/Textures");
File.WriteAllTextAsync(
$"{artDomainPath}/这里放所有美术的资源,因涉及打包依赖等原因,不建议在上一层节点新增文件夹,如涉及文件夹规范等问题请@张铮.hint", "");
}
string domainPath = $"{Application.dataPath}/Domain/{domain}";
if (Directory.Exists(domainPath + "/AddressableRes/Config/DomainConfig.asset"))
{
EditorUtility.DisplayDialog("错误!", $"\"{domain}\"已经存在,无法创建", "确定");
EditorUtility.DisplayDialog("提示", "ip不能为空", "确定");
return;
}
CreatDirectory(domainPath);
//程序资源存放文件夹
string resPath = $"{domainPath}/AddressableRes";
CreatDirectory(resPath);
//创建音频文件夹
CreatDirectory(resPath + "/Audios");
//创建Config文件夹
CreatDirectory(resPath + "/Config");
//创建Dll文件夹
CreatDirectory(resPath + "/Dll");
//创建Prefabs文件夹
CreatDirectory(resPath + "/Prefabs");
//创建Scenes文件夹
CreatDirectory(resPath + "/Scenes");
//创建SpriteAtlas文件夹
CreatDirectory(resPath + "/SpriteAtlas");
//创建Sprites文件夹
CreatDirectory(resPath + "/Sprites");
//创建Video文件夹
CreatDirectory(resPath + "/Video");
File.WriteAllTextAsync($"{resPath}/这里放所有参与热更的资源.hint", "");
//主入口预制件
GameObject gameObj = new GameObject(domain);
gameObj.transform.position = Vector3.zero;
gameObj.transform.rotation = Quaternion.identity;
gameObj.name = domain;
CreatDirectory($"{resPath}/Prefabs");
string rootPfbFilePath = $"Assets/Domain/{domain}/AddressableRes/Prefabs/{domain}.prefab";
var localPath = AssetDatabase.GenerateUniqueAssetPath(rootPfbFilePath);
PrefabUtility.SaveAsPrefabAsset(gameObj, localPath);
//存放脚本文件夹
string scriptsPath = $"{domainPath}/HotUpdate";
CreatDirectory(scriptsPath);
File.WriteAllTextAsync($"{scriptsPath}/这里放所有参与热更的脚本文件.hint", "该文件夹中的程序集定义文件,请勿删除,非常重要。");
//创建配置文件夹
string confPath = $"{domainPath}/Conf";
CreatDirectory(confPath);
//程序集配置资源
string hotfixDomain = $"HotUpdate_{domain}";
string hotfixDomainAsmdef = $"{scriptsPath}/{hotfixDomain}.asmdef";
await using (var writer = new StreamWriter(hotfixDomainAsmdef))
var sceneWorkEntity = new SceneWorkEntity
{
string body = Resources.Load<TextAsset>("AssemblyDefinitionTemplate").text;
body = body.Replace("MODULE_IDENT", hotfixDomain);
body = body.Replace("ROOT_NAMESPACE", hotfixDomain);
await writer.WriteAsync(body);
}
//模块化脚本生成配置
string domainClassName = $"{domain}Domain";
string architectureClassName = $"{domain}Architecture";
#if HotUpdate
//模块配置资源
DomainConfig moduleConfig = CreateInstance<DomainConfig>();
moduleConfig.domain = domain;
moduleConfig.className = domainClassName;
moduleConfig.mainPrefab = "Prefabs_" + gameObj.name;
moduleConfig.@namespace = domain;
AssetDatabase.CreateAsset(moduleConfig, $"Assets/Domain/{domain}/AddressableRes/Config/DomainConfig.asset");
//
//编辑器配置资源
BuildAssetDataSetting buildAssetDataSetting = CreateInstance<BuildAssetDataSetting>();
buildAssetDataSetting.packageName = domain;
AssetDatabase.CreateAsset(buildAssetDataSetting,
$"Assets/Domain/{domain}/Conf/BuildAssetDataSetting.asset");
AssetDatabase.Refresh();
string configPath = $"Assets/Domain/{domain}/HotUpdate/{hotfixDomain}.asmdef";
AssemblyDefinitionAsset assemblyDefinitionAsset =
AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(configPath);
if (domain != "Main")
sceneName = sceneName,
identifier = identifier,
sceneDesc = sceneDesc,
};
string postData = JsonConvert.SerializeObject(sceneWorkEntity);
ResultMessageEntity entity = await WebRequestSystem.Post($"{ip}/SceneWork/AddScene",postData);
if (entity.code ==200)
{
// 将程序集定义添加到 HybridCLR 热更列表
var settings = SettingsUtil.HybridCLRSettings;
if (!settings.hotUpdateAssemblyDefinitions.Contains(assemblyDefinitionAsset))
var sceneWorkResponse = JsonConvert.DeserializeObject<SceneWorkResponses>(entity.data.ToString());
SceneWorkEntities.Add(new CreatPointCloudEntity(this)
{
var assemblyList = settings.hotUpdateAssemblyDefinitions.ToList();
assemblyList.Add(assemblyDefinitionAsset);
SettingsUtil.HybridCLRSettings.hotUpdateAssemblyDefinitions = assemblyList.ToArray();
}
List<AssemblyDefinitionAsset> assemblies = new List<AssemblyDefinitionAsset>();
for (int i = 0; i < settings.hotUpdateAssemblyDefinitions.Length; i++)
{
if (settings.hotUpdateAssemblyDefinitions[i] != null)
{
assemblies.Add(settings.hotUpdateAssemblyDefinitions[i]);
}
}
HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions = assemblies.ToArray();
HybridCLRSettings.Save();
}
#endif
AssetDatabase.SaveAssets();
string domainClassPath = $"{scriptsPath}/{domainClassName}.cs";
//await File.WriteAllTextAsync($"{scriptsPath}/{domainClassName}.cs", domainTemplate);
await using (var writer = new StreamWriter(domainClassPath))
{
string domainTemplate = Resources.Load<TextAsset>("DomainTemplate").text;
domainTemplate = domainTemplate.Replace("ClassNameXX", domainClassName)
.Replace("ReturnArchitecture", architectureClassName)
.Replace("ArchitectureX", architectureClassName)
.Replace("NamespaceX", domain)
.Replace("DomainNameXX", domain);
await writer.WriteAsync(domainTemplate);
sceneName = sceneWorkResponse.sceneName,
identifier = sceneWorkResponse.identifier,
sceneDesc = sceneWorkResponse.sceneDesc,
isActive = sceneWorkResponse.isActivate=="true",
id = sceneWorkResponse.id,
});
EditorUtility.DisplayDialog("提示", "创建成功", "确定");
}
}
[TitleGroup("预览Domain作用域")] public List<CreatDomainEntity> domainList;
protected override void Initialize()
[TitleGroup("预览场景")] public List<CreatPointCloudEntity> SceneWorkEntities;
protected override async void Initialize()
{
base.Initialize();
domainList = GetCreatDomainAll();
}
/// <summary>
/// 获取全部作用域
/// </summary>
public static string[] GetCreatDomainAllName()
{
string domainPath = $"{Application.dataPath}/Domain";
string[] domains;
// 新增目录获取代码
if (Directory.Exists(domainPath))
string ip = EditorPrefs.GetString("ip");
if (string.IsNullOrEmpty(ip))
{
var dirInfo = new DirectoryInfo(domainPath);
// 获取直接子目录(不递归)
domains = dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly)
.Select(d => d.Name)
.ToArray();
EditorUtility.DisplayDialog("提示", "ip不能为空", "确定");
return;
}
else
ResultMessageEntity entity = await WebRequestSystem.Get(ip,"/SceneWork/GetScenebyAll");
if (entity.code ==200)
{
domains = Array.Empty<string>();
}
return domains;
}
/// <summary>
/// 获取全部作用域
/// </summary>
public static List<CreatDomainEntity> GetCreatDomainAll()
{
string domainPath = $"{Application.dataPath}/Domain";
string[] domains;
// 新增目录获取代码
if (Directory.Exists(domainPath))
{
var dirInfo = new DirectoryInfo(domainPath);
// 获取直接子目录(不递归)
domains = dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly)
.Select(d => d.Name)
.ToArray();
}
else
{
domains = Array.Empty<string>();
}
List<CreatDomainEntity> domainList = new List<CreatDomainEntity>();
foreach (var item in domains)
{
if (File.Exists($"{domainPath}/{item}/AddressableRes/Config/DomainConfig.asset"))
var sceneWorkResponses = JsonConvert.DeserializeObject<List<SceneWorkResponses>>(entity.data.ToString());
SceneWorkEntities = sceneWorkResponses.Select(x => new CreatPointCloudEntity(this)
{
CreatDomainEntity domainEntity = new CreatDomainEntity(domainList)
{
DomainName = item,
domainPath = $"{domainPath}/{item}"
};
domainList.Add(domainEntity);
}
sceneName = x.sceneName,
identifier = x.identifier,
sceneDesc = x.sceneDesc,
isActive = x.isActivate=="true",
id = x.id,
}).ToList();
}
return domainList;
}
private static void CreatDirectory(string artDomainPath)
{
if (!Directory.Exists(artDomainPath))
{
//创建Animation文件夹
Directory.CreateDirectory(artDomainPath);
}
}
public static void CreateDomainDirectory(string domain)
{
string artDomainPath = $"{Application.dataPath}/Art/{domain}";
//创建Animation文件夹
CreatDirectory(artDomainPath + "/Animation");
//创建Effects文件夹
CreatDirectory(artDomainPath + "/Effects");
//创建Fbx文件夹
CreatDirectory(artDomainPath + "/Fbx");
//创建Font文件夹
CreatDirectory(artDomainPath + "/Font");
//创建Materials文件夹
CreatDirectory(artDomainPath + "/Materials");
//创建Prefabs文件夹
CreatDirectory(artDomainPath + "/Prefabs");
//创建Scenes文件夹
CreatDirectory(artDomainPath + "/Scenes");
//创建/Scenes/Test文件夹
CreatDirectory(artDomainPath + "/Scenes/Test");
//创建Shader文件夹
CreatDirectory(artDomainPath + "/Shader");
//创建Textures文件夹
CreatDirectory(artDomainPath + "/Textures");
string domainPath = $"{Application.dataPath}/Domain/{domain}";
//程序资源存放文件夹
string resPath = $"{domainPath}/AddressableRes";
CreatDirectory(resPath);
//创建音频文件夹
CreatDirectory(resPath + "/Audios");
//创建Config文件夹
CreatDirectory(resPath + "/Config");
//创建Dll文件夹
CreatDirectory(resPath + "/Dll");
//创建Prefabs文件夹
CreatDirectory(resPath + "/Prefabs");
//创建Scenes文件夹
CreatDirectory(resPath + "/Scenes");
//创建SpriteAtlas文件夹
CreatDirectory(resPath + "/SpriteAtlas");
//创建Sprites文件夹
CreatDirectory(resPath + "/Sprites");
//创建Video文件夹
CreatDirectory(resPath + "/Video");
AssetDatabase.Refresh();
}
}
[Serializable]
public class SceneWorkEntity
{
/// <summary>
/// 场景名称
/// </summary>
public string sceneName { get; set; }
/// <summary>
/// 场景识别码
/// </summary>
public string identifier { get; set; }
/// <summary>
/// 场景描述
/// </summary>
public string sceneDesc { get; set; }
public bool isActivate { get; set; }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7bb9b6b27377443b8fe03d499261f74c
timeCreated: 1758621402

View File

@@ -0,0 +1,30 @@
namespace Stary.Evo.Editor.Entity
{
public class SceneWorkResponses
{
/// <summary>
/// 场景名称
/// </summary>
public string sceneName { get; set; }
/// <summary>
/// 场景标识符
/// </summary>
public string identifier { get; set; }
/// <summary>
/// 场景描述
/// </summary>
public string sceneDesc { get; set; }
/// <summary>
/// 场景是否激活
/// </summary>
public string isActivate { get; set; }
/// <summary>
/// 场景ID
/// </summary>
public string id { get; set; }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 067c00bef4b34da2bf2bb988228a3bdd
timeCreated: 1758621434

View File

@@ -1,13 +1,12 @@
{
"name": "com.pointcloud.runtime",
"name": "com.pointcloud.reditor",
"rootNamespace": "",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:f3fa071c399c4383a9ff8115e53dfefc",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:d1a793c2b6959e04ea45b972eaa369c8"
],
"includePlatforms": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,