144 lines
4.7 KiB
C#
144 lines
4.7 KiB
C#
using System.Linq;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.EditorTools
|
|
{
|
|
/// <summary>
|
|
/// PP2 通用动画 aseprite 重导入后,PeipeiFixScene 里 UF_face(垂手)若仍指向旧子资源 ID 会丢图。
|
|
/// 本工具改绑到「佩佩像素版-默认」aseprite 的 Frame_0。
|
|
/// </summary>
|
|
public static class FixPeipeiUfFaceSprite
|
|
{
|
|
private const string ScenePath = "Assets/Scenes/PeipeiFixScene.unity";
|
|
// 垂手姿态用「默认」aseprite,避免依赖被 PP2 重导过的通用动画子资源 ID。
|
|
private const string AsepritePath =
|
|
"Assets/RawResources/Actor/\u4f69\u4f69/\u4f69\u4f69\u50cf\u7d20\u7248-\u9ed8\u8ba4.aseprite";
|
|
private const string FaceObjectName = "\u5782\u624b (1)"; // 垂手 (1)
|
|
|
|
[MenuItem("AIBIS/Fix/Rebind Peipei UF Face Sprite")]
|
|
public static void RebindFromMenu()
|
|
{
|
|
if (!Rebind(out var message))
|
|
{
|
|
EditorUtility.DisplayDialog("Rebind UF Face", message, "OK");
|
|
return;
|
|
}
|
|
|
|
EditorUtility.DisplayDialog("Rebind UF Face", message, "OK");
|
|
}
|
|
|
|
/// <summary>Unity batchmode: -executeMethod AibisDream.EditorTools.FixPeipeiUfFaceSprite.RebindBatch</summary>
|
|
public static void RebindBatch()
|
|
{
|
|
if (!Rebind(out var message))
|
|
{
|
|
Debug.LogError("[FixPeipeiUfFaceSprite] " + message);
|
|
EditorApplication.Exit(1);
|
|
return;
|
|
}
|
|
|
|
Debug.Log("[FixPeipeiUfFaceSprite] " + message);
|
|
EditorApplication.Exit(0);
|
|
}
|
|
|
|
private static bool Rebind(out string message)
|
|
{
|
|
var sprites = AssetDatabase.LoadAllAssetsAtPath(AsepritePath)
|
|
.OfType<Sprite>()
|
|
.ToArray();
|
|
if (sprites.Length == 0)
|
|
{
|
|
message = "No sprites found in: " + AsepritePath;
|
|
return false;
|
|
}
|
|
|
|
var sprite = sprites.FirstOrDefault(s => s != null && s.name.Contains("Frame_0"))
|
|
?? sprites.FirstOrDefault(s => s != null);
|
|
if (sprite == null)
|
|
{
|
|
message = "Could not pick a sprite from aseprite.";
|
|
return false;
|
|
}
|
|
|
|
var sceneAlreadyOpen = false;
|
|
for (var i = 0; i < EditorSceneManager.sceneCount; i++)
|
|
{
|
|
if (EditorSceneManager.GetSceneAt(i).path == ScenePath)
|
|
{
|
|
sceneAlreadyOpen = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
var scene = sceneAlreadyOpen
|
|
? EditorSceneManager.GetSceneByPath(ScenePath)
|
|
: EditorSceneManager.OpenScene(ScenePath, OpenSceneMode.Additive);
|
|
|
|
GameObject faceGo = null;
|
|
foreach (var root in scene.GetRootGameObjects())
|
|
{
|
|
foreach (var t in root.GetComponentsInChildren<Transform>(true))
|
|
{
|
|
if (t.gameObject.name == FaceObjectName)
|
|
{
|
|
faceGo = t.gameObject;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (faceGo != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (faceGo == null)
|
|
{
|
|
if (!sceneAlreadyOpen)
|
|
{
|
|
EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
|
|
message = "Face object not found: " + FaceObjectName;
|
|
return false;
|
|
}
|
|
|
|
var renderer = faceGo.GetComponent<SpriteRenderer>();
|
|
if (renderer == null)
|
|
{
|
|
if (!sceneAlreadyOpen)
|
|
{
|
|
EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
|
|
message = "SpriteRenderer missing on " + FaceObjectName;
|
|
return false;
|
|
}
|
|
|
|
Undo.RecordObject(renderer, "Rebind UF Face Sprite");
|
|
renderer.sprite = sprite;
|
|
EditorUtility.SetDirty(renderer);
|
|
EditorSceneManager.MarkSceneDirty(scene);
|
|
EditorSceneManager.SaveScene(scene);
|
|
|
|
if (!sceneAlreadyOpen)
|
|
{
|
|
EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
|
|
AssetDatabase.TryGetGUIDAndLocalFileIdentifier(
|
|
(Object)sprite, out var guid, out long localId);
|
|
|
|
message = string.Format(
|
|
"Rebound {0} -> {1} (guid={2} fileID={3})",
|
|
FaceObjectName,
|
|
sprite.name,
|
|
guid,
|
|
localId);
|
|
return true;
|
|
}
|
|
}
|
|
}
|