NLDClient-yudde/ProjectNLD/Assets/Art/temp/Editor/AnimationTools/AnimationToolWindow.cs

470 lines
19 KiB
C#
Raw Normal View History

2025-01-22 15:13:44 +08:00
using System.Collections.Generic;
2024-12-23 10:19:53 +08:00
using System.IO;
using System.Linq;
2026-01-16 19:26:53 +08:00
using Framework;
2025-07-14 14:45:42 +08:00
using Gameplay.Character;
2024-12-23 10:19:53 +08:00
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
2026-01-16 19:41:39 +08:00
namespace Art.temp.Editor.AnimationTools
2024-12-23 10:19:53 +08:00
{
2024-12-25 13:18:39 +08:00
public class AnimationTool : EditorWindow
{
2026-01-16 20:07:41 +08:00
[MenuItem("Test/Animation 工具/Animation")]
2025-01-22 15:13:44 +08:00
public static void ShowWindow()
{
GetWindow<AnimationTool>("Animation Tools");
}
2024-12-25 13:18:39 +08:00
public void CreateGUI()
{
2025-01-23 14:09:35 +08:00
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Art/temp/Editor/CommonUSSFile.uss");
rootVisualElement.styleSheets.Add(styleSheet);
2024-12-25 13:18:39 +08:00
Box box1 = new();
box1.Add(new Label("Anim file tool"));
2025-01-15 13:56:35 +08:00
box1.Add(new Button() { name = "meta_btn", text = "重新生成 meta 文件并设置 avatar" });
2024-12-25 13:18:39 +08:00
box1.Add(new Button() { name = "renameClip_btn", text = "rename animationClip" });
box1.Add(new Button() { name = "copyAnim_btn", text = "提取 anim to compressedShow" });
2025-01-15 13:56:35 +08:00
box1.Add(new Button() { name = "copyTempAnim_btn", text = "提取 anim to compressed" });
box1.Add(new Button() { name = "find something", text = "Find Fire" });
2024-12-25 13:18:39 +08:00
rootVisualElement.Add(box1);
box1.Q<Button>("meta_btn").RegisterCallback<ClickEvent>(DeleteMeta);
box1.Q<Button>("renameClip_btn").RegisterCallback<ClickEvent>(RenameAnim);
box1.Q<Button>("copyAnim_btn").RegisterCallback<ClickEvent>(CopySelectedToCompressedShow);
2025-01-06 15:09:23 +08:00
box1.Q<Button>("copyTempAnim_btn").RegisterCallback<ClickEvent>(CopySelectedToTemp);
2025-01-15 13:56:35 +08:00
box1.Q<Button>("find something").RegisterCallback<ClickEvent>(FindSomething);
2024-12-25 13:18:39 +08:00
Box box2 = new();
2025-01-22 15:13:44 +08:00
rootVisualElement.Add(box2);
2024-12-25 13:18:39 +08:00
box2.Add(new Label("other files tool"));
2026-01-16 19:26:53 +08:00
2025-01-22 15:13:44 +08:00
box2.Add(new Button() { name = "renameAssets_btn", text = "rename assets" });
2024-12-25 13:18:39 +08:00
box2.Q<Button>("renameAssets_btn").RegisterCallback<ClickEvent>(RenameAssets);
2026-01-16 19:26:53 +08:00
2026-01-13 13:35:32 +08:00
box2.Add(new Button() { name = "test", text = "test" });
2025-01-08 16:55:29 +08:00
box2.Q<Button>("test").RegisterCallback<ClickEvent>(Test);
2025-05-09 19:45:04 +08:00
2025-06-26 13:27:36 +08:00
box2.Add(new Button() { name = "MeshSimplify_btn", text = "character mesh simplify" });
box2.Q<Button>("MeshSimplify_btn").RegisterCallback<ClickEvent>(SimplifyCharacterMesh);
2025-06-05 16:07:48 +08:00
box2.Add(new Button() { name = "vehicleShader_btn", text = "vehicleShader" });
box2.Q<Button>("vehicleShader_btn").RegisterCallback<ClickEvent>(SetVehicleShader);
2025-07-14 14:45:42 +08:00
2025-08-01 18:31:43 +08:00
box2.Add(new Button() { name = "AddPoint_btn", text = "添加 hit Points" });
box2.Q<Button>("AddPoint_btn").RegisterCallback<ClickEvent>(AddHitPoints);
2026-01-06 17:30:34 +08:00
}
2025-08-01 18:31:43 +08:00
2026-01-06 17:30:34 +08:00
private static bool HasCombined(GameObject go)
{
Transform[] children = go.GetComponentsInChildren<Transform>();
bool hasCombined = children.Any(c => c.gameObject.name.StartsWith("Default_NLD"));
if (hasCombined) Debug.LogWarning("有合并mesh需要重命名");
return hasCombined;
2025-07-14 14:45:42 +08:00
}
2026-01-06 17:30:34 +08:00
private static bool HasHitPoints(GameObject go)
{
Transform[] children = go.GetComponentsInChildren<Transform>();
bool hasHitPoints = children.Any(c => c.gameObject.name.StartsWith("hit"));
if (hasHitPoints) Debug.LogWarning("已有hit points");
return hasHitPoints;
}
private static void RenameDuplicateBones(GameObject go)
{
var groups = go.GetComponentsInChildren<Transform>()
.GroupBy(p => p.name)
.Where(g => g.Count() > 1)
.ToArray();
if (!groups.Any()) return;
foreach (var group in groups)
{
for (int i = 0; i < group.Count(); i++)
{
group.ElementAt(i).name = group.ElementAt(i).name + "_" + (i + 1);
}
2026-01-16 19:26:53 +08:00
2026-01-06 17:30:34 +08:00
Debug.Log("重命名重复骨骼:" + group.Key);
}
}
2025-09-23 15:53:11 +08:00
2025-08-01 18:31:43 +08:00
private static void AddHitPoints(ClickEvent evt)
2025-07-14 14:45:42 +08:00
{
GameObject[] gameObjects = Selection.gameObjects;
foreach (GameObject go in gameObjects)
{
2025-07-29 13:00:17 +08:00
GameObject instance = PrefabUtility.InstantiatePrefab(go) as GameObject;
if (instance == null) return;
2026-01-06 17:30:34 +08:00
bool hasCombined = HasCombined(instance);
bool hasHitPoints = HasHitPoints(instance);
RenameDuplicateBones(instance);
if (hasCombined || hasHitPoints) continue;
2025-07-29 13:00:17 +08:00
if (instance.name.EndsWith("_b")) continue;
2026-01-06 17:30:34 +08:00
// 添加 hit points
2025-07-14 14:45:42 +08:00
var pointEffect = instance.AddComponent<CmpCharacterEffectPoints>();
List<GameObject> points = new List<GameObject>();
for (int i = 0; i < 4; i++)
{
var hit = new GameObject($"hit00{i + 1}");
2025-07-14 14:45:42 +08:00
hit.transform.SetParent(instance.transform);
points.Add(hit);
}
pointEffect.m_CriticalPoints = new[] { points[0].transform };
pointEffect.m_OtherPoints = new[] { points[1].transform, points[2].transform, points[3].transform };
}
2025-06-05 16:07:48 +08:00
}
2025-08-01 18:31:43 +08:00
2025-06-05 16:07:48 +08:00
private static void SetVehicleShader(ClickEvent evt)
{
string[] paths = { "Assets/Art/Character/Models/Battery", "Assets/Art/Character/Models/Vehicle" };
List<Object> objects = AnimHelper.FindAssetsByFolders<Object>(filter: "t:material", paths).ToList();
foreach (Object obj in objects)
{
if (obj is Material mat)
{
2025-09-15 16:11:18 +08:00
if (mat.shader == Shader.Find("NLD_URP/NLD_Vehicle")) continue;
2025-06-05 16:07:48 +08:00
mat.shader = Shader.Find("NLD_URP/NLD_Vehicle");
// mat.SetFloat("_Factor", 0.2f);
Debug.Log(mat.name);
}
}
2025-06-26 13:27:36 +08:00
2025-06-05 16:07:48 +08:00
AssetDatabase.SaveAssets();
2025-05-09 19:45:04 +08:00
}
2025-06-26 13:27:36 +08:00
private static void SimplifyMesh(GameObject instance, float vertexAmount)
2025-05-09 19:45:04 +08:00
{
2025-05-14 16:16:21 +08:00
Debug.Log(instance.transform.childCount);
for (int i = 0; i < instance.transform.childCount; i++)
{
GameObject meshGameObject = instance.transform.GetChild(i).gameObject;
SkinnedMeshRenderer skin = meshGameObject.GetComponent<SkinnedMeshRenderer>();
if (skin == null) continue;
if (skin.sharedMesh == null) break;
string dir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(skin.sharedMesh));
if (!Directory.Exists(dir)) break;
var simplify = meshGameObject.GetComponent<MeshSimplify>();
if (simplify == null) simplify = meshGameObject.AddComponent<MeshSimplify>();
2025-06-26 13:27:36 +08:00
simplify.m_fVertexAmount = vertexAmount;
2025-05-14 16:16:21 +08:00
simplify.m_bEnablePrefabUsage = true;
2025-06-26 13:27:36 +08:00
simplify.m_strAssetPath = Path.Combine(dir, skin.sharedMesh.name + "_simplyMesh.asset");
2025-05-14 16:16:21 +08:00
MeshSimplyTool.Create(simplify);
2025-06-26 13:27:36 +08:00
PrefabUtility.ApplyPrefabInstance(instance, InteractionMode.UserAction);
Debug.Log(Path.Combine(dir, skin.sharedMesh.name));
2025-05-14 16:16:21 +08:00
}
2025-05-09 19:45:04 +08:00
}
2025-06-26 13:27:36 +08:00
private static void SimplifyCharacterMesh(ClickEvent evt)
2025-05-09 19:45:04 +08:00
{
Object[] folders = Selection.objects;
string[] folderPaths = folders.Select(AssetDatabase.GetAssetPath).ToArray();
IEnumerable<Object> characters = AnimHelper.FindAssetsByFolders<GameObject>("character_", folderPaths);
int i = -1;
foreach (Object obj in characters)
{
if (obj is not GameObject character) continue;
GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(character);
instance.transform.localPosition = new Vector3(i, 0, 0);
i--;
2025-05-14 16:16:21 +08:00
2025-06-26 13:27:36 +08:00
if (instance.name.StartsWith("character_A")) SimplifyMesh(instance, 0.6f);
if (instance.name.StartsWith("character_E")) SimplifyMesh(instance, 0.4f);
2025-05-09 19:45:04 +08:00
}
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
private static void RenameAnim(ClickEvent evt)
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
var gos = Selection.gameObjects;
if (!gos.Any()) return;
2024-12-25 13:18:39 +08:00
foreach (var go in gos)
{
string goPath = AssetDatabase.GetAssetPath(go);
ModelImporter importer = AssetImporter.GetAtPath(goPath) as ModelImporter;
2025-01-22 15:13:44 +08:00
if (!importer) continue;
2025-01-15 19:01:09 +08:00
importer.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel;
2024-12-25 13:18:39 +08:00
2025-01-22 15:13:44 +08:00
ModelImporterClipAnimation clip = importer.defaultClipAnimations[0];
2024-12-25 13:18:39 +08:00
clip.name = go.name;
2025-01-22 15:13:44 +08:00
importer.clipAnimations = new[] { clip };
2024-12-25 13:18:39 +08:00
importer.SaveAndReimport();
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
2025-01-15 13:56:35 +08:00
// 删除 meta 文件, 设置 avatar
2025-01-22 15:13:44 +08:00
private static void DeleteMeta(ClickEvent evt)
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
var objs = Selection.gameObjects;
2024-12-25 13:18:39 +08:00
if (objs.Length == 0)
{
Debug.LogWarning("请先选择至少一个Fbx文件");
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
foreach (GameObject obj in objs)
{
string objPath = AssetDatabase.GetAssetPath(obj);
string metaPath = objPath + ".meta";
File.Delete(metaPath);
AssetDatabase.Refresh();
2025-01-15 13:56:35 +08:00
var modelImporter = AssetImporter.GetAtPath(objPath) as ModelImporter;
2025-01-22 15:13:44 +08:00
if (!modelImporter) continue;
2025-01-15 13:56:35 +08:00
modelImporter.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel;
modelImporter.SaveAndReimport();
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
2025-01-22 15:13:44 +08:00
private static void FindSomething(ClickEvent evt)
2024-12-25 13:18:39 +08:00
{
2025-03-12 14:05:02 +08:00
Object[] folders = Selection.objects;
2025-03-11 20:39:16 +08:00
string[] folderPaths = folders.Select(AssetDatabase.GetAssetPath).ToArray();
var objects = AnimHelper.FindAssetsByFolders<GameObject>("ani_", folderPaths);
2025-01-15 13:56:35 +08:00
foreach (var obj in objects)
2024-12-25 13:18:39 +08:00
{
2025-01-15 13:56:35 +08:00
string fbxPath = AssetDatabase.GetAssetPath(obj);
var assets = AssetDatabase.LoadAllAssetRepresentationsAtPath(fbxPath);
var clips = assets.OfType<AnimationClip>();
2025-01-22 15:13:44 +08:00
var curves = clips.SelectMany(AnimationUtility.GetCurveBindings);
2025-01-15 13:56:35 +08:00
if (curves.Any(c => Path.GetFileName(c.path).StartsWith("Fire")))
Debug.LogWarning("f:" + obj.name);
2024-12-25 13:18:39 +08:00
}
}
private static void AnimOptimize(AnimationClip clip)
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
var curveBindings = AnimationUtility.GetCurveBindings(clip);
2025-01-15 17:36:36 +08:00
for (int ii = 0; ii < curveBindings.Length; ++ii)
2024-12-25 13:18:39 +08:00
{
2025-01-15 17:36:36 +08:00
AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, curveBindings[ii]);
2024-12-25 13:18:39 +08:00
// 删除移动帧(除了Bip001)和缩放帧
2025-01-15 17:36:36 +08:00
string propName = curveBindings[ii].propertyName.ToLower();
string nodeName = Path.GetFileName(curveBindings[ii].path);
/*if (propName.Contains("position") && nodeName.StartsWith("Bip001 "))
2024-12-25 13:18:39 +08:00
{
curve = null; //有空格排除了“Bip001”
2025-01-15 17:36:36 +08:00
}*/
if (propName.Contains("scale") && !nodeName.Contains("Grip_point01"))
2024-12-25 13:18:39 +08:00
{
curve = null;
}
2025-01-22 15:13:44 +08:00
2025-01-15 13:56:35 +08:00
if (nodeName.StartsWith("Fire"))
{
curve = null;
}
2024-12-25 13:18:39 +08:00
// 压缩浮点数
2025-01-22 15:13:44 +08:00
if (curve is { keys: not null })
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
var keyFrames = curve.keys;
2024-12-25 13:18:39 +08:00
for (int i = 0; i < keyFrames.Length; i++)
{
Keyframe key = keyFrames[i];
key.value = float.Parse(key.value.ToString("f4"));
key.inTangent = float.Parse(key.inTangent.ToString("f4"));
key.outTangent = float.Parse(key.outTangent.ToString("f4"));
keyFrames[i] = key;
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
curve.keys = keyFrames;
}
2025-01-15 13:56:35 +08:00
// curve 为 null, 则删除曲线
2025-01-15 17:36:36 +08:00
AnimationUtility.SetEditorCurve(clip, curveBindings[ii], curve);
2024-12-25 13:18:39 +08:00
}
}
// copy fbx 中一个或多个 anim 到 new path
private static string[] CopyAnim(GameObject fbx, string destFolder, bool toCompressed = false)
2024-12-25 13:18:39 +08:00
{
string fbxPath = AssetDatabase.GetAssetPath(fbx);
var assets = AssetDatabase.LoadAllAssetRepresentationsAtPath(fbxPath);
2025-01-22 15:13:44 +08:00
var animPaths = new List<string>();
foreach (Object asset in assets)
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
if (asset is not AnimationClip clip) continue;
AnimOptimize(clip);
AnimationClip newClip = new();
EditorUtility.CopySerialized(clip, newClip);
string str = clip.name + ".anim";
string compressed = toCompressed ? "compressed_" + str : str;
string newPath = Path.Combine(destFolder, compressed);
AssetDatabase.CreateAsset(newClip, newPath);
Debug.Log(newPath);
animPaths.Add(newPath);
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
2025-01-15 12:56:29 +08:00
return animPaths.ToArray();
2024-12-25 13:18:39 +08:00
}
public void CopyToVictory(ClickEvent evt)
{
2025-01-22 15:13:44 +08:00
var objs = Selection.gameObjects;
2024-12-25 13:18:39 +08:00
2025-01-22 15:13:44 +08:00
const string folder = "Assets/Art/Animations/animVictory";
2024-12-25 13:18:39 +08:00
if (objs.Length == 0)
{
Debug.LogWarning("请先选择至少一个Fbx文件");
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
foreach (GameObject obj in objs)
{
CopyAnim(obj, folder);
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
public void CopyToCompressedInShow(ClickEvent evt)
{
2025-01-22 15:13:44 +08:00
string[] guids = AssetDatabase.FindAssets("t:GameObject", new[]
{
"Assets/Art/Animations/Show/Battle",
"Assets/Art/Animations/Show/Ready",
"Assets/Art/Animations/Show/Story",
2024-12-25 13:18:39 +08:00
});
2025-01-22 15:13:44 +08:00
var paths = guids.Select(AssetDatabase.GUIDToAssetPath);
var objs = paths.Select(AssetDatabase.LoadAssetAtPath<GameObject>).ToArray();
2024-12-25 13:18:39 +08:00
2025-01-22 15:13:44 +08:00
const string folder = "Assets/Art/Animations/compressedShow";
2024-12-25 13:18:39 +08:00
foreach (GameObject obj in objs)
{
CopyAnim(obj, folder, true);
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
private static void CopySelectedToCompressedShow(ClickEvent evt)
2024-12-25 13:18:39 +08:00
{
2025-02-12 12:35:39 +08:00
// const string folder = "Assets/Art/Animations/compressedShow";
var objects = Selection.gameObjects;
2024-12-25 13:18:39 +08:00
2025-02-12 12:35:39 +08:00
const string tempFolder = "Assets/Art/temp/Animation";
const string destFilePath = "Assets/Art/Animations/compressedShow/{0}";
2024-12-25 13:18:39 +08:00
2025-02-12 12:35:39 +08:00
foreach (GameObject obj in objects)
2024-12-25 13:18:39 +08:00
{
2025-02-12 12:35:39 +08:00
AnimHelper.PreSetModel(obj);
string[] fileNames = CopyAnim(obj, tempFolder, true);
foreach (string f in fileNames)
{
string destFile = string.Format(destFilePath, Path.GetFileName(f));
File.Copy(f, destFile, true);
Debug.Log(destFile);
}
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
2025-01-22 15:13:44 +08:00
private static void CopySelectedToTemp(ClickEvent evt)
2025-01-06 15:09:23 +08:00
{
2025-01-22 15:13:44 +08:00
var objects = Selection.gameObjects;
2025-01-06 15:09:23 +08:00
2025-01-22 15:13:44 +08:00
const string tempFolder = "Assets/Art/temp/Animation";
const string destFilePath = "Assets/Art/Animations/compressed/{0}";
2025-01-06 15:09:23 +08:00
2025-01-15 13:56:35 +08:00
foreach (GameObject obj in objects)
2025-01-15 12:56:29 +08:00
{
AnimHelper.PreSetModel(obj);
2025-01-15 13:56:35 +08:00
string[] fileNames = CopyAnim(obj, tempFolder, true);
foreach (string f in fileNames)
{
string destFile = string.Format(destFilePath, Path.GetFileName(f));
File.Copy(f, destFile, true);
Debug.Log(destFile);
}
2025-01-06 15:09:23 +08:00
}
2025-01-22 15:13:44 +08:00
2025-01-06 15:09:23 +08:00
AssetDatabase.Refresh();
}
2024-12-25 13:18:39 +08:00
2025-01-22 15:13:44 +08:00
// rename assets
private static void RenameAssets(ClickEvent evt)
2024-12-25 13:18:39 +08:00
{
2025-01-22 15:13:44 +08:00
// 选择的文件中的 GameObject
2025-09-23 15:53:11 +08:00
// Object[] folders = Selection.objects;
// string[] folderPath = folders.Select(AssetDatabase.GetAssetPath).ToArray();
// var objects = AnimHelper.FindAssetsByFolders<GameObject>("t:GameObject", folderPath);
2025-01-22 15:13:44 +08:00
// 选择的 gameObject
2025-09-23 15:53:11 +08:00
var objects = Selection.gameObjects.Where(g => g.name.EndsWith("_01"));
2025-01-22 15:13:44 +08:00
// 选择的 文件夹
// var objects = Selection.GetFiltered<Object>(SelectionMode.Assets);
2025-09-23 15:53:11 +08:00
foreach (GameObject obj in objects)
2024-12-25 13:18:39 +08:00
{
2025-09-23 15:53:11 +08:00
string name = obj.name.Split("_")[2];
string newName = "3" + name[1..];
2024-12-25 13:18:39 +08:00
string path = AssetDatabase.GetAssetPath(obj);
AssetDatabase.RenameAsset(path, newName);
}
AssetDatabase.Refresh();
}
2025-01-06 15:09:23 +08:00
2024-12-25 13:18:39 +08:00
public void MoveFiles(ClickEvent evt)
{
2025-01-22 15:13:44 +08:00
var objs = Selection.objects;
2024-12-25 13:18:39 +08:00
string folder = $"Assets/Art_Out/Manual/VictoryAnim";
foreach (Object obj in objs)
{
string oldPath = AssetDatabase.GetAssetPath(obj);
string fileName = Path.GetFileName(oldPath);
string newPath = Path.Combine(folder, fileName);
AssetDatabase.MoveAsset(oldPath, newPath);
Debug.Log(newPath);
}
2025-01-22 15:13:44 +08:00
2024-12-25 13:18:39 +08:00
AssetDatabase.Refresh();
}
2025-01-08 16:55:29 +08:00
2025-01-22 15:13:44 +08:00
private static void Test(ClickEvent evt)
2025-01-08 16:55:29 +08:00
{
2026-01-16 19:26:53 +08:00
var personDataList = ArtTableManager.instance.tables.PersonConfig.DataList;
foreach (var i in personDataList)
{
2026-01-16 19:26:53 +08:00
Debug.Log(i.Name);
}
2026-01-16 19:26:53 +08:00
Debug.Log(personDataList.Count);
2025-01-08 16:55:29 +08:00
}
2025-03-07 13:34:36 +08:00
2025-03-05 13:51:07 +08:00
private static void Combine()
{
GameObject obj = Selection.activeGameObject;
AnimHelper.PreSetAll(obj);
var go = Object.Instantiate(obj);
var nameId = obj.name.Split('_')[2];
var texNames = new[] { "_MainTex", "_MaskTex" };
var parentPath = $"Assets/Art/temp/Prefab/character_{nameId}";
if (!Directory.Exists(parentPath))
{
Directory.CreateDirectory(parentPath);
}
AnimHelper.CombineSkinSaveAssets(go, texNames, parentPath);
// save prefab
string path = $"{parentPath}/character_{nameId}.prefab";
PrefabUtility.SaveAsPrefabAssetAndConnect(go, path, InteractionMode.AutomatedAction);
}
2024-12-25 13:18:39 +08:00
}
2025-01-22 15:13:44 +08:00
}