Files
plugin-library/Assets/00.BuildOriginality/Editor/ArtBuild/ArtServerManageWindow.cs
2026-03-31 16:42:19 +08:00

515 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using UnityEngine;
using UnityEngine.Serialization;
namespace Stary.Evo.Editor
{
public class ArtServerManageWindow : OdinEditorWindow
{
[MenuItem("Evo/Art/服务器数据管理工具", false, 1)]
static void Init()
{
// Get existing open window or if none, make a new one:
ArtServerManageWindow window = (ArtServerManageWindow)EditorWindow.GetWindow(typeof(ArtServerManageWindow));
window.Show();
}
[BoxGroup("Selection")]
[EnumToggleButtons, HideLabel]
[OnValueChanged("SetUseTypeData")]
public UseType useType = UseType.Member;
private static DeviceMode _DeviceMode = DeviceMode.Evo_Rokid;
[BoxGroup("Selection")]
[ShowInInspector, ShowIf("@useType == UseType.Art")]
public DeviceMode deviceMode
{
get => _DeviceMode;
set { _DeviceMode = value; }
}
private string _titleGroupName;
[TitleGroup("@ _titleGroupName")] public string productName;
[TitleGroup("@ _titleGroupName")]
[Button("@ _titleGroupName", ButtonSizes.Large)]
public void CreatDomain()
{
if (useType == UseType.Member)
{
CreatMemberFiled();
}
else if (useType == UseType.Art)
{
CreatArtFiled();
}
}
/// <summary>
/// 创建项目目录
/// </summary>
private void CreatArtFiled()
{
if (string.IsNullOrEmpty(productName))
{
EditorUtility.DisplayDialog("错误!", "请输入将要创建Art的编号", "确定");
return;
}
string artDomainPath = $"{Application.dataPath}/Art/{productName}";
if (!Directory.Exists(artDomainPath))
{
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");
//创建Shader文件夹
CreatDirectory(artDomainPath + "/Shader");
//创建Textures文件夹
CreatDirectory(artDomainPath + "/Textures");
File.WriteAllTextAsync(
$"{artDomainPath}/这里放所有美术的资源,因涉及打包依赖等原因,不建议在上一层节点新增文件夹,如涉及文件夹规范等问题请@张铮.hint", "");
}
//创建Art 测试场景
/* 2. 再建 Scenes/Test */
string sceneDir = $"{artDomainPath}/Scenes";
if (!Directory.Exists(sceneDir))
{
Directory.CreateDirectory(sceneDir);
}
/* 3. 创建新场景 */
var newScene = UnityEditor.SceneManagement.EditorSceneManager.NewScene(
UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects,
UnityEditor.SceneManagement.NewSceneMode.Single);
/* 4. 删除默认相机(和灯光)*/
foreach (var go in newScene.GetRootGameObjects())
{
if (go.name == "Main Camera" || go.name == "Directional Light")
GameObject.DestroyImmediate(go);
}
/* 5. 载入并实例化 RKCameraRig.prefab */
if (deviceMode == DeviceMode.Evo_Rokid)
{
string prefabPath = "Prefabs/BaseSetting/RKCameraRig";
var prefab = Resources.Load<GameObject>(prefabPath);
var spawned = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
spawned.name = "RKCameraRigTest";
}
else
{
string prefabPath = "Prefabs/BaseSetting/RKCameraRig";
// 模糊搜索
GameObject prefab = LoadByFuzzy();
GameObject instance = null;
if (prefab != null)
{
instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
instance.transform.position = Vector3.zero;
Debug.Log($"✅ 已加载: {prefab.name}");
}
else
{
Debug.LogError($"无法加载 Prefab: {prefabPath}\n请检查路径是否正确或 XR Interaction Toolkit 样本是否已导入。");
return;
}
// 选中并聚焦
// Selection.activeGameObject = instance;
// EditorGUIUtility.PingObject(instance);
if (instance) Debug.Log($"成功加载: {instance.name}");
}
/* 6. 保存场景 */
string scenePath = Path.Combine("Assets/Art", productName, "Scenes", "TestScene.unity");
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(newScene, scenePath);
CreatArtDomainEntity creatArtDomainEntity = new CreatArtDomainEntity(artList);
creatArtDomainEntity.DomainName = productName;
creatArtDomainEntity.domainPath = artDomainPath;
artList.Add(creatArtDomainEntity);
}
GameObject LoadByFuzzy()
{
// 通过文件名模糊搜索,完全无视路径
var guids = AssetDatabase.FindAssets("XR Origin (XR Rig) t:Prefab");
if (guids.Length == 0)
{
Debug.LogError("未找到 XR Origin (XR Rig) Prefab");
return null;
}
// 如果找到多个,优先选择 XR Interaction Toolkit 路径下的
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
if (path.Contains("XR Interaction Toolkit"))
{
return AssetDatabase.LoadAssetAtPath<GameObject>(path);
}
}
// 默认返回第一个
return AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(guids[0]));
}
/// <summary>
/// 创建成员目录
/// </summary>
private void CreatMemberFiled()
{
if (string.IsNullOrEmpty(productName))
{
EditorUtility.DisplayDialog("错误!", "请输入将要创建成员的编号", "确定");
return;
}
//检测成员是否存在
bool isExit = false;
foreach (var domainEntity in domainMemberList)
{
if (domainEntity.DomainName == productName)
{
isExit = true;
break;
}
}
if (isExit)
{
EditorUtility.DisplayDialog("错误!", "当前成员已在服务器中存在,无需重复创建", "确定");
return;
}
string memberDomainPath = $"{Application.dataPath}/Member/{productName}";
if (!Directory.Exists(memberDomainPath))
{
Directory.CreateDirectory(memberDomainPath);
//创建Config文件夹
CreatDirectory(memberDomainPath + "/Config");
//创建Scenes文件夹
CreatDirectory(memberDomainPath + "/Scenes");
File.WriteAllTextAsync(
$"{memberDomainPath}/这里是成员打包目录,因涉及打包依赖等原因,不建议在上一层节点新增文件夹,如涉及文件夹规范等问题请@张铮.hint", "");
}
//创建Art 测试场景配置文件
string configDir = $"{memberDomainPath}/Config";
//模块配置资源
ArtSceneData artSceneData = CreateInstance<ArtSceneData>();
AssetDatabase.CreateAsset(artSceneData, $"Assets/Member/{productName}/Config/ArtSceneData.asset");
CreatMemberServerDomainEntity creatMemberServerDomainEntity =
new CreatMemberServerDomainEntity(domainMemberList);
creatMemberServerDomainEntity.DomainName = productName;
creatMemberServerDomainEntity.domainPath = memberDomainPath;
domainMemberList.Add(creatMemberServerDomainEntity);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
creatMemberServerDomainEntity.SetArtSceneData();
}
[ShowIf("IsMember")]
[ListDrawerSettings(DraggableItems = false, ShowFoldout = false, ShowPaging = false, ShowItemCount = false,
HideRemoveButton = true, HideAddButton = true)]
public List<CreatMemberServerDomainEntity> domainMemberList;
[ShowIf("IsProject")]
[ListDrawerSettings(DraggableItems = false, ShowFoldout = false, ShowPaging = false, ShowItemCount = false,
HideRemoveButton = true, HideAddButton = true)]
public List<CreatArtDomainEntity> artList;
protected override async void Initialize()
{
base.Initialize();
SetUseTypeData();
if (domainMemberList != null)
{
domainMemberList.Clear();
}
domainMemberList = new List<CreatMemberServerDomainEntity>();
var resDmainResponse = await ArtLoadAssetServer.GetServerDomainAll();
foreach (var response in resDmainResponse)
{
string domainPath = $"{Application.dataPath}/Member/{response.DomainName}";
var domainEntity = new CreatMemberServerDomainEntity(domainMemberList);
domainEntity.SetDomainData(response.DomainName, domainPath, response, ArtLoadAssetServer.ip);
domainMemberList.Add(domainEntity);
}
//添加本地Member
GetMemberLocalAll();
artList = GetCreatDomainAll();
}
private static void CreatDirectory(string artDomainPath)
{
if (!Directory.Exists(artDomainPath))
{
Directory.CreateDirectory(artDomainPath);
}
}
public void CreateDomainDirectory(string domain)
{
string artDomainPath = "";
if (useType == UseType.Member)
{
artDomainPath = $"{Application.dataPath}/Member/{domain}";
}
else if (useType == UseType.Art)
{
artDomainPath = $"{Application.dataPath}/Art/{domain}";
if (!Directory.Exists(artDomainPath))
{
EditorUtility.DisplayDialog("提示", $"不存在此Domain:{domain},无法创建", "确定");
return;
}
}
if (useType == UseType.Member)
{
//创建Config文件夹
CreatDirectory(artDomainPath + "/Config");
//创建Scenes文件夹
CreatDirectory(artDomainPath + "/Scenes");
//创建/Scenes/Test文件夹
CreatDirectory(artDomainPath + "/Scenes/Test");
//创建Art 测试场景配置文件
string configDir = $"{artDomainPath}/Config";
// 检测目标文件是否已存在
string assetPath = $"Assets/Member/{domain}/Config/ArtSceneData.asset";
if (File.Exists($"{Application.dataPath}/../{assetPath}"))
{
Debug.LogWarning($"ArtSceneData.asset 已存在: {assetPath}");
// 可选:询问是否覆盖
if (EditorUtility.DisplayDialog("文件已存在",
$"ArtSceneData.asset 已存在,是否覆盖?", "覆盖", "取消"))
{
// 删除现有文件
AssetDatabase.DeleteAsset(assetPath);
AssetDatabase.Refresh();
// 创建新的ArtSceneData
ArtSceneData artSceneData = CreateInstance<ArtSceneData>();
AssetDatabase.CreateAsset(artSceneData, assetPath);
Debug.Log($"已覆盖 ArtSceneData: {assetPath}");
}
else
{
Debug.Log("用户取消创建 ArtSceneData");
}
}
else
{
// 文件不存在,直接创建
ArtSceneData artSceneData = CreateInstance<ArtSceneData>();
AssetDatabase.CreateAsset(artSceneData, assetPath);
Debug.Log($"已创建 ArtSceneData: {assetPath}");
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
else if (useType == UseType.Art)
{
//创建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");
}
AssetDatabase.Refresh();
}
/// <summary>
/// 获取全部作用域
/// </summary>
private static List<CreatArtDomainEntity> GetCreatDomainAll()
{
string domainPath = $"{Application.dataPath}/Art";
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<CreatArtDomainEntity> domainList = new List<CreatArtDomainEntity>();
foreach (var item in domains)
{
if (Directory.Exists($"{domainPath}/{item}"))
{
CreatArtDomainEntity domainEntity = new CreatArtDomainEntity(domainList)
{
DomainName = item,
domainPath = $"{domainPath}/{item}"
};
domainList.Add(domainEntity);
}
}
return domainList;
}
/// <summary>
/// 获取全部作用域
/// </summary>
private void GetMemberLocalAll()
{
string domainPath = $"{Application.dataPath}/Member";
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<CreatMemberServerDomainEntity> domainList = new List<CreatMemberServerDomainEntity>();
foreach (var item in domains)
{
if (File.Exists($"{domainPath}/{item}/Config/ArtSceneData.asset"))
{
bool isExit = domainMemberList.Any(x => x.DomainName == item);
if (isExit)
{
continue;
}
CreatMemberServerDomainEntity entity = new CreatMemberServerDomainEntity(domainList)
{
DomainName = item,
domainPath = $"{domainPath}/{item}"
};
entity.SetArtSceneData();
domainList.Add(entity);
}
}
domainMemberList.AddRange(domainList);
}
private void SetUseTypeData()
{
if (useType == UseType.Member)
{
_titleGroupName = "创建成员";
}
else if (useType == UseType.Art)
{
_titleGroupName = "创建项目Art";
}
}
private bool IsMember()
{
return useType == UseType.Member;
}
private bool IsProject()
{
return useType == UseType.Art;
}
/// <summary>
/// 使用类型
/// </summary>
public enum UseType
{
/// <summary>
/// 成员使用
/// </summary>
Member,
/// <summary>
/// 项目使用
/// </summary>
Art
}
public enum DeviceMode
{
//Xreal,
Evo_Xreal,
//Rokid,
Evo_Rokid,
}
}
}