Files
Studio/Assets/Editor/WI/TwinObjectPreprocessingHelper.cs

274 lines
9.7 KiB
C#
Raw Normal View History

2025-02-19 17:24:26 +09:00
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
2025-02-21 11:57:09 +09:00
using XRLib;
using XRLib.Util;
2025-02-19 17:24:26 +09:00
using System.Threading.Tasks;
#if UNITY_EDITOR
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets;
#endif
namespace XED
{
public class TwinObjectPreprocessingHelper
{
#if UNITY_EDITOR
static List<TwinContainer> twinContainerList = new();
2025-03-24 20:03:17 +09:00
//[MenuItem("Tools/TwinObjectsSetting")]
//public static void TwinObjectsSetting()
//{
// AutomateTwinObjectSetup();
//}
2025-02-19 17:24:26 +09:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static void CreateFolder(string folderPath)
{
if (Directory.Exists(folderPath))
return;
Directory.CreateDirectory(folderPath);
}
//TODO : <20><><EFBFBD>θ<EFBFBD> <20>ϵ<EFBFBD><CFB5>ڵ<EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> Ȱ<><C8B0>, Prefab <20><> <20≯<EFBFBD> <20>Ľ<EFBFBD><C4BD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> <20><><EFBFBD><EFBFBD> Ȱ<><C8B0>(PRF_Robot01_Robot)
static void AutomateTwinObjectSetup()
{
var mainPath = "Assets/Models/";
var beforePath = string.Concat(mainPath, "TwinObject_BeforeProcessing");
var afterPath = string.Concat(mainPath, "TwinObject_AfterProcessing/");
string etcPath = string.Concat(mainPath, "$etc");
CreateFolder(etcPath);
CreateAddressableAssets(beforePath, etcPath, afterPath);
TwinContainerAddressableSetting(twinContainerList);
}
static void CreateAddressableAssets(string beforePath, string etcPath, string afterPath)
{
//beforPath <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Asset<65><74> guid<69><64> <20><><EFBFBD><EFBFBD> ã<><C3A3><EFBFBD>ϴ<EFBFBD>.
string[] guids = AssetDatabase.FindAssets("t:Prefab", new string[] { beforePath });
foreach (var guid in guids)
{
//guid <20><> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> Asset <20><> <20><><EFBFBD>θ<EFBFBD> ã<><C3A3><EFBFBD>ϴ<EFBFBD>.
string filePath = AssetDatabase.GUIDToAssetPath(guid);
if (filePath.StartsWith(etcPath))
{
continue;
}
//<2F><><EFBFBD>ο<EFBFBD> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> Asset <20><> ã<><C3A3><EFBFBD>ϴ<EFBFBD>.
var loadAsset = AssetDatabase.LoadAssetAtPath<GameObject>(filePath);
var twinObject = loadAsset.GetComponent<TwinObject>();
string fileName = Path.GetFileName(filePath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
string folderPath = string.Concat(afterPath, fileNameWithoutExtension);
string fullPath = string.Concat(folderPath, "/", fileName);
//<2F><>ó<EFBFBD><C3B3> <20>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
CreateFolder(folderPath);
//TwinContainer <20><> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
var twinContainer = CreateTwinContainer(folderPath, twinObject);
//TwinObject <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
var texture = CreateTwinObjectPortrait(folderPath, twinObject);
//TwinObject <20><> <20>𵨸<EFBFBD> <20><>ġ, <20>ݶ<EFBFBD><DDB6>̴<EFBFBD><CCB4><EFBFBD> <20>ʱ<EFBFBD>ȭ <20><> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
SetTwinObject(loadAsset);
var moveFilePath = MoveFiles(fileName, filePath, fullPath, etcPath);
AssetDatabase.Refresh();
//TwinContainer <20><> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>Ҵ<EFBFBD><D2B4>մϴ<D5B4>.
TwinContainerSetData(twinContainer, texture, moveFilePath);
twinContainerList.Add(twinContainer);
}
}
static TwinContainer CreateTwinContainer(string folderPath, TwinObject twinObject)
{
var twinContainer = ScriptableObject.CreateInstance<TwinContainer>();
var path = string.Concat(folderPath, "/", twinObject.name, ".asset");
AssetDatabase.CreateAsset(twinContainer, path);
return twinContainer;
}
static Texture2D CreateTwinObjectPortrait(string folderPath, TwinObject twinObject)
{
Texture2D thumbnailTexture = null;
//<2F≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>ó <20><><EFBFBD><EFBFBD>
while (thumbnailTexture == null)
{
thumbnailTexture = AssetPreview.GetAssetPreview(twinObject.gameObject);
System.Threading.Thread.Sleep(5);
}
var transparentTexture = BackgroundTransparencyProcess(thumbnailTexture);
//<2F>ؽ<EFBFBD>ó <20><><EFBFBD><EFBFBD>
transparentTexture.name = string.Concat("Texture_", twinObject.name);
byte[] bytes = transparentTexture.EncodeToPNG();
string filePath = string.Concat(folderPath, "/", transparentTexture.name, ".png");
File.WriteAllBytes(filePath, bytes);
AssetDatabase.Refresh();
//<2F>ؽ<EFBFBD>ó <20>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD>
var texture = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
return texture;
}
static Texture2D BackgroundTransparencyProcess(Texture2D texture)
{
var transparentTexture = new Texture2D(texture.width, texture.height);
transparentTexture.SetPixels(texture.GetPixels());
for (int h = 0; h < texture.height; h++)
{
for (int w = 0; w < texture.width; w++)
{
transparentTexture.SetPixel(w, h, Color.clear);
if (texture.GetPixel(w, h) != texture.GetPixel(w + 1, h))
break;
}
for (int w = texture.width; w > 0; w--)
{
transparentTexture.SetPixel(w, h, Color.clear);
if (texture.GetPixel(w, h) != texture.GetPixel(w - 1, h))
break;
}
}
transparentTexture.Apply();
return transparentTexture;
}
//<2F>۾<EFBFBD><DBBE><EFBFBD> <20>Ϸ<EFBFBD><CFB7><EFBFBD> <20>𵨸<EFBFBD><F0B5A8B8><EFBFBD> <20><>ó<EFBFBD><C3B3> <20>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD>Ű<EFBFBD><C5B0> <20>޼<EFBFBD><DEBC><EFBFBD>
static string MoveFiles(string fileName, string filePath, string fullPath, string etcPath)
{
if (File.Exists(fullPath) && (filePath != fullPath))
{
int filenum = 0;
string EtcFileName = string.Concat(etcPath, "/", fileName);
while (File.Exists(EtcFileName))
{
filenum++;
EtcFileName = string.Concat(etcPath, "/", filenum.ToString(), "_", fileName);
}
fullPath = EtcFileName;
}
File.Move(filePath, fullPath);
return fullPath;
}
static void TwinContainerSetData(TwinContainer twinContainer, Texture2D texture, string filePath)
{
var moveAsset = AssetDatabase.LoadAssetAtPath<GameObject>(filePath);
var moveTwinObject = moveAsset.GetComponent<TwinObject>();
twinContainer.twinObject = moveTwinObject;
twinContainer.twinObjectPortrait = texture;
}
#region TwinObject Modeling <EFBFBD><EFBFBD> Collider <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <EFBFBD>޼<EFBFBD><EFBFBD><EFBFBD>
//TwinObject <20><> Modeling <20><> <20><>ġ<EFBFBD><C4A1> Collider <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static void SetTwinObject(GameObject twinObject)
{
var bounds = CalculateBounds(twinObject.transform);
SetModelPosition(twinObject.transform, bounds);
SetBoxCollider(twinObject.transform, bounds);
}
//TwinObject <20><> Bounds <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static Bounds CalculateBounds(Transform twinObject)
{
var childRenderers = twinObject.GetComponentsInChildren<Renderer>();
var combinedBounds = childRenderers[0].bounds;
foreach (var childRenderer in childRenderers)
{
combinedBounds.Encapsulate(childRenderer.bounds);
}
return combinedBounds;
}
//TwinObject <20><> <20>ݶ<EFBFBD><DDB6>̴<EFBFBD><CCB4><EFBFBD> ũ<><20>°<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static void SetBoxCollider(Transform twinObject, Bounds bounds)
{
var boxCollider = twinObject.GetOrAddComponent<BoxCollider>();
boxCollider.size = bounds.size;
boxCollider.center = Vector3.zero;
}
//TwinObject <20><> <20>𵨸<EFBFBD> <20><>ü<EFBFBD><C3BC> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static void SetModelPosition(Transform twinObject, Bounds bounds)
{
var twinObjectChild = twinObject.GetChild(0);
twinObjectChild.position -= bounds.center;
}
#endregion
#region TwinContainer <EFBFBD><EFBFBD> Addressable Asset <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <EFBFBD>޼<EFBFBD><EFBFBD><EFBFBD>
private static void TwinContainerAddressableSetting(List<TwinContainer> twinContainers)
{
foreach (var twinContainer in twinContainers)
{
AddressableSetting(twinContainer);
}
}
//TwinContainer <20><> Addressable(Group, Label)<29><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
private static void AddressableSetting(TwinContainer twinContainer)
{
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
var path = AssetDatabase.GetAssetPath(twinContainer);
var guid = AssetDatabase.AssetPathToGUID(path);
var entry = settings.FindAssetEntry(guid);
var label = twinContainer.twinObject.assetLabel.ToString();
var group = CreateOrFindGroup(settings, label);
if (entry == null)
{
entry = settings.CreateOrMoveEntry(guid, group);
}
else
{
entry.address = path;
}
settings.MoveEntry(entry, group);
entry.SetLabel(label, true);
}
//Addressable Group <20><> ã<><C3A3>, ã<><C3A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> Group <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><>ȯ<EFBFBD>ϴ<EFBFBD> <20>޼<EFBFBD><DEBC><EFBFBD>
static AddressableAssetGroup CreateOrFindGroup(AddressableAssetSettings settings, string groupName)
{
var group = settings.FindGroup(groupName);
if (group == null)
group = settings.CreateGroup(groupName, false, false, true, null);
return group;
}
#endregion
#endif
}
}