808 lines
25 KiB
C#
808 lines
25 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using RootMotion.FinalIK;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using Object = UnityEngine.Object;
|
||
|
||
namespace NBF
|
||
{
|
||
public class RF4FixPrefab : Editor
|
||
{
|
||
#region 圈
|
||
|
||
[MenuItem("Assets/Fix/修复圈", false, 1)]
|
||
private static void FixRings()
|
||
{
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixRing(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼圈失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixRing(GameObject prefab)
|
||
{
|
||
var rings = prefab.GetComponent<RodRingAsset>();
|
||
if (rings == null)
|
||
{
|
||
rings = prefab.AddComponent<RodRingAsset>();
|
||
}
|
||
|
||
List<Transform> list = new List<Transform>();
|
||
// 遍历所有直接子对象
|
||
for (int i = 0; i < prefab.transform.childCount; i++)
|
||
{
|
||
Transform child = prefab.transform.GetChild(i);
|
||
list.Add(child);
|
||
}
|
||
|
||
// rings.rings = list.ToArray();
|
||
|
||
List<Transform> points = new List<Transform>();
|
||
foreach (var tran in list)
|
||
{
|
||
for (int i = 0; i < tran.childCount; i++)
|
||
{
|
||
Transform c = tran.GetChild(i);
|
||
if (c.name.Contains("Collider"))
|
||
{
|
||
points.Add(c);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// rings.points = points.ToArray();
|
||
|
||
List<RodRingNode> saveList = new List<RodRingNode>();
|
||
|
||
foreach (var node in list)
|
||
{
|
||
RodRingNode ringNode = new RodRingNode
|
||
{
|
||
ring = node
|
||
};
|
||
foreach (var point in points)
|
||
{
|
||
if (point.parent != node) continue;
|
||
ringNode.point = point;
|
||
var rig = point.GetComponent<Rigidbody>();
|
||
if (rig == null)
|
||
{
|
||
rig = point.gameObject.AddComponent<Rigidbody>();
|
||
}
|
||
|
||
if (rig != null)
|
||
{
|
||
rig.useGravity = false;
|
||
rig.isKinematic = true;
|
||
rig.mass = 1;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
saveList.Add(ringNode);
|
||
}
|
||
|
||
rings.rings = saveList.ToArray();
|
||
EditorUtility.SetDirty(prefab);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 鱼竿
|
||
|
||
//joint_root
|
||
[MenuItem("Assets/Fix/修复鱼竿", false, 2)]
|
||
private static void FixRods()
|
||
{
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixRod(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼竿失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixRod(GameObject prefab)
|
||
{
|
||
RemoveMissingScriptsFrom(prefab);
|
||
|
||
|
||
var lineRenderer = prefab.GetComponent<LineRenderer>();
|
||
if (lineRenderer == null)
|
||
{
|
||
lineRenderer = prefab.AddComponent<LineRenderer>();
|
||
}
|
||
|
||
lineRenderer.startWidth = 0.001f;
|
||
lineRenderer.endWidth = 0.001f;
|
||
|
||
var rod = prefab.GetComponent<RodAsset>();
|
||
if (rod == null)
|
||
{
|
||
rod = prefab.AddComponent<RodAsset>();
|
||
}
|
||
|
||
rod.lineRenderer = lineRenderer;
|
||
rod.root = FindTransformsByNameContainsOnes(prefab.transform, "joint_root");
|
||
rod.LeftHandConnector = FindTransformsByNameContainsOnes(prefab.transform, "l_hand_connector");
|
||
rod.RightHandConnector = FindTransformsByNameContainsOnes(prefab.transform, "r_hand_connector");
|
||
rod.ReelConnector = FindTransformsByNameContainsOnes(prefab.transform, "reel_connector");
|
||
rod.gripEnd = FindTransformsByNameContainsOnes(prefab.transform, "grip_end");
|
||
|
||
var trans = prefab.GetComponentsInChildren<Transform>(true);
|
||
|
||
List<Transform> joints = new List<Transform>();
|
||
List<Transform> rings = new List<Transform>();
|
||
foreach (var tran in trans)
|
||
{
|
||
if (tran == null) continue;
|
||
if (tran == rod.root) continue;
|
||
if (tran.name.Contains("_RING_"))
|
||
{
|
||
rings.Add(tran);
|
||
}
|
||
else if (tran.name.Contains("_joint_"))
|
||
{
|
||
joints.Add(tran);
|
||
}
|
||
}
|
||
|
||
var blancEnd = FindTransformByName(prefab.transform, "blanc_end");
|
||
if (blancEnd == null)
|
||
{
|
||
Debug.LogError($"blanc_end 为空,name={prefab.name}");
|
||
}
|
||
else
|
||
{
|
||
joints.Add(blancEnd);
|
||
}
|
||
|
||
rod.rings = rings.ToArray();
|
||
rod.joints = joints.ToArray();
|
||
|
||
|
||
var ccdIK = prefab.GetComponent<CCDIK>();
|
||
if (ccdIK == null)
|
||
{
|
||
ccdIK = prefab.AddComponent<CCDIK>();
|
||
}
|
||
|
||
var solver = ccdIK.solver;
|
||
if (solver != null)
|
||
{
|
||
solver.maxIterations = 3;
|
||
|
||
|
||
var rootField = solver.GetType().GetField("root",
|
||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
if (rootField != null)
|
||
{
|
||
rootField.SetValue(solver, prefab.transform);
|
||
}
|
||
|
||
solver.bones = Array.Empty<IKSolver.Bone>();
|
||
for (var i = 1; i < rod.joints.Length; i++)
|
||
{
|
||
solver.AddBone(rod.joints[i]);
|
||
}
|
||
}
|
||
|
||
EditorUtility.SetDirty(rod);
|
||
EditorUtility.SetDirty(ccdIK);
|
||
EditorUtility.SetDirty(prefab);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 线轴
|
||
|
||
private static List<AnimationClip> _animationClips;
|
||
|
||
[MenuItem("Assets/Fix/修复线轴", false, 3)]
|
||
private static void FixReels()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixReel(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复线轴失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixReel(GameObject prefab)
|
||
{
|
||
RemoveMissingScriptsFrom(prefab);
|
||
var reel = prefab.GetComponent<ReelAsset>();
|
||
if (reel == null)
|
||
{
|
||
reel = prefab.AddComponent<ReelAsset>();
|
||
}
|
||
|
||
reel.rootConnector = FindTransformsByNameContainsOnes(prefab.transform, "reel_root_connector");
|
||
reel.rootCompensator = FindTransformsByNameContainsOnes(prefab.transform, "reel_root_compensator");
|
||
reel.lineConnector = FindTransformsByNameContainsOnes(prefab.transform, "line_connector");
|
||
reel.lineIntersect = FindTransformsByNameContainsOnes(prefab.transform, "line_intersect");
|
||
reel.lineIntersectHelper = reel.lineIntersect.parent;
|
||
reel.handle = FindTransformsByNameContainsOnes(prefab.transform, "ik_locator_handle");
|
||
reel.handleEnd = reel.handle.parent;
|
||
|
||
|
||
var anim = reel.rootConnector.parent.GetComponent<Animator>();
|
||
if (anim == null)
|
||
{
|
||
anim = reel.rootConnector.parent.gameObject.AddComponent<Animator>();
|
||
}
|
||
|
||
reel.animator = anim;
|
||
|
||
// var anim = reel.rootConnector.parent.GetComponent<Animation>();
|
||
// if (anim == null)
|
||
// {
|
||
// anim = reel.rootConnector.parent.gameObject.AddComponent<Animation>();
|
||
// }
|
||
|
||
// List<AnimationClip> clips = _animationClips.Where(clip => clip.name.Contains(prefab.name)).ToList();
|
||
// foreach (var clip in clips)
|
||
// {
|
||
// anim.AddClip(clip, clip.name);
|
||
// var lowName = clip.name.ToLower();
|
||
// if (lowName.Contains("open"))
|
||
// {
|
||
// reel.openAnimation = clip;
|
||
// }
|
||
// else if (lowName.Contains("close"))
|
||
// {
|
||
// reel.closeAnimation = clip;
|
||
// }
|
||
// else if (lowName.Contains("handle_roll"))
|
||
// {
|
||
// reel.rollHandleAnimation = clip;
|
||
// }
|
||
// }
|
||
|
||
|
||
// anim.playAutomatically = true;
|
||
// reel.anim = anim;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 浮漂
|
||
|
||
[MenuItem("Assets/Fix/修复浮漂", false, 4)]
|
||
private static void FixBobbers()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixBobber(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼漂失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixBobber(GameObject prefab)
|
||
{
|
||
// RemoveMissingScriptsFrom(prefab);
|
||
var bobber = prefab.GetComponent<BobberAsset>();
|
||
if (bobber == null)
|
||
{
|
||
bobber = prefab.AddComponent<BobberAsset>();
|
||
}
|
||
|
||
bobber.body = FindTransformsByNameContainsOnes(prefab.transform, "_body");
|
||
bobber.stick = FindTransformsByNameContainsOnes(prefab.transform, "_stick");
|
||
bobber.topConnector = FindTransformsByNameContainsOnes(prefab.transform, "_topConnector");
|
||
bobber.bottomConnector = FindTransformsByNameContainsOnes(prefab.transform, "_bottomConnector");
|
||
bobber.waterline = FindTransformsByNameContainsOnes(prefab.transform, "_waterline");
|
||
|
||
// var boxCollider = prefab.GetComponent<BoxCollider>();
|
||
// if (boxCollider != null)
|
||
// {
|
||
// DestroyImmediate(boxCollider);
|
||
// // boxCollider = prefab.AddComponent<BoxCollider>();
|
||
// }
|
||
//
|
||
// boxCollider.center = new Vector3(0, -0.01f, 0);
|
||
// boxCollider.size = new Vector3(0.005f, 0.005f, 0.005f);
|
||
|
||
var rigidbody = prefab.GetComponent<Rigidbody>();
|
||
if (rigidbody == null)
|
||
{
|
||
rigidbody = prefab.AddComponent<Rigidbody>();
|
||
}
|
||
|
||
rigidbody.useGravity = false;
|
||
|
||
var configurableJoint = prefab.GetComponent<ConfigurableJoint>();
|
||
if (configurableJoint == null)
|
||
{
|
||
configurableJoint = prefab.AddComponent<ConfigurableJoint>();
|
||
}
|
||
|
||
configurableJoint.xMotion = ConfigurableJointMotion.Locked;
|
||
configurableJoint.yMotion = ConfigurableJointMotion.Locked;
|
||
configurableJoint.zMotion = ConfigurableJointMotion.Locked;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 钩
|
||
|
||
[MenuItem("Assets/Fix/修复鱼钩", false, 5)]
|
||
private static void FixHooks()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixHook(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼钩失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixHook(GameObject prefab)
|
||
{
|
||
// RemoveMissingScriptsFrom(prefab);
|
||
var hook = prefab.GetComponent<HookAsset>();
|
||
if (hook == null)
|
||
{
|
||
hook = prefab.AddComponent<HookAsset>();
|
||
}
|
||
|
||
hook.baitConnector = FindTransformsByNameContainsOnes(prefab.transform, "bait_connector");
|
||
|
||
var boxCollider = prefab.GetComponent<BoxCollider>();
|
||
if (boxCollider == null)
|
||
{
|
||
boxCollider = prefab.AddComponent<BoxCollider>();
|
||
}
|
||
|
||
boxCollider.center = new Vector3(0, -0.01f, 0);
|
||
boxCollider.size = new Vector3(0.005f, 0.005f, 0.005f);
|
||
|
||
var rigidbody = prefab.GetComponent<Rigidbody>();
|
||
if (rigidbody == null)
|
||
{
|
||
rigidbody = prefab.AddComponent<Rigidbody>();
|
||
}
|
||
|
||
rigidbody.useGravity = false;
|
||
|
||
var configurableJoint = prefab.GetComponent<ConfigurableJoint>();
|
||
if (configurableJoint == null)
|
||
{
|
||
configurableJoint = prefab.AddComponent<ConfigurableJoint>();
|
||
}
|
||
|
||
configurableJoint.xMotion = ConfigurableJointMotion.Locked;
|
||
configurableJoint.yMotion = ConfigurableJointMotion.Locked;
|
||
configurableJoint.zMotion = ConfigurableJointMotion.Locked;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 鱼饵
|
||
|
||
[MenuItem("Assets/Fix/修复鱼饵", false, 6)]
|
||
private static void FixBaits()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixBait(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼钩失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixBait(GameObject prefab)
|
||
{
|
||
var bait = prefab.GetComponent<BaitAsset>();
|
||
if (bait == null)
|
||
{
|
||
bait = prefab.AddComponent<BaitAsset>();
|
||
}
|
||
|
||
bait.hook = FindTransformsByNameContainsOnes(prefab.transform, "_hook");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 仿生饵
|
||
|
||
[MenuItem("Assets/Fix/修复路亚饵", false, 6)]
|
||
private static void FixLures()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixLure(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼钩失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixLure(GameObject prefab)
|
||
{
|
||
RemoveMissingScriptsFrom(prefab);
|
||
var lure = prefab.GetComponent<LureAsset>();
|
||
if (lure == null)
|
||
{
|
||
lure = prefab.AddComponent<LureAsset>();
|
||
}
|
||
|
||
List<Transform> hookPoints = new List<Transform>();
|
||
for (int i = 1; i < 5; i++)
|
||
{
|
||
var hook = FindTransformByName(prefab.transform, $"hook_0{i}");
|
||
if (hook == null) break;
|
||
hookPoints.Add(hook);
|
||
}
|
||
|
||
lure.hookPoints = hookPoints.ToArray();
|
||
// hook_01
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 鱼
|
||
|
||
[MenuItem("Assets/Fix/修复鱼", false, 7)]
|
||
private static void FixFishs()
|
||
{
|
||
_animationClips = GetAllClips();
|
||
var rods = GetSelectPrefab<GameObject>();
|
||
foreach (var rod in rods)
|
||
{
|
||
try
|
||
{
|
||
FixFish(rod);
|
||
EditorUtility.SetDirty(rod);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"修复鱼钩失败,name={rod.name} e={e}");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static void FixFish(GameObject prefab)
|
||
{
|
||
var bait = prefab.GetComponent<FishAsset>();
|
||
if (bait == null)
|
||
{
|
||
bait = prefab.AddComponent<FishAsset>();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 工具类
|
||
|
||
private static List<AnimationClip> GetAllClips()
|
||
{
|
||
List<AnimationClip> list = new List<AnimationClip>();
|
||
// 获取项目中所有的AnimationClip
|
||
string[] guids = AssetDatabase.FindAssets("t:AnimationClip");
|
||
|
||
foreach (string guid in guids)
|
||
{
|
||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||
AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(path);
|
||
|
||
if (clip != null)
|
||
{
|
||
list.Add(clip);
|
||
}
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
private static string GetPathToParent(Transform currentTransform)
|
||
{
|
||
if (currentTransform == null || currentTransform.parent == null)
|
||
{
|
||
return string.Empty; // 如果没有父级,返回空字符串
|
||
}
|
||
|
||
// 递归调用,先获取父级的路径,然后加上当前Transform的名字
|
||
return GetPathToParent(currentTransform.parent) + "/" + currentTransform.name;
|
||
}
|
||
|
||
private static T FindFirstComponentInChildren<T>(GameObject parent) where T : Component
|
||
{
|
||
// 检查当前对象
|
||
T component = parent.GetComponent<T>();
|
||
if (component != null)
|
||
{
|
||
return component;
|
||
}
|
||
|
||
// 递归检查子对象
|
||
foreach (Transform child in parent.transform)
|
||
{
|
||
T result = FindFirstComponentInChildren<T>(child.gameObject);
|
||
if (result != null)
|
||
{
|
||
return result;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private static Transform FindTransformByName(Transform parent, string name)
|
||
{
|
||
// 检查当前对象
|
||
if (parent.name == name)
|
||
{
|
||
return parent;
|
||
}
|
||
|
||
// 递归检查子对象
|
||
foreach (Transform child in parent)
|
||
{
|
||
Transform result = FindTransformByName(child, name);
|
||
if (result != null)
|
||
{
|
||
return result;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="parent"></param>
|
||
/// <param name="namePrefix"></param>
|
||
/// <returns></returns>
|
||
private static List<Transform> FindTransformsByNamePrefix(Transform parent, string namePrefix)
|
||
{
|
||
List<Transform> result = new List<Transform>();
|
||
|
||
// 检查当前对象
|
||
if (parent.name.StartsWith(namePrefix))
|
||
{
|
||
result.Add(parent);
|
||
}
|
||
|
||
// 递归检查子对象
|
||
foreach (Transform child in parent)
|
||
{
|
||
result.AddRange(FindTransformsByNamePrefix(child, namePrefix));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private static Transform FindTransformsByNameContainsOnes(Transform parent, string nameContains)
|
||
{
|
||
var trans = FindTransformsByNameContains(parent, nameContains);
|
||
if (trans != null && trans.Count > 0)
|
||
{
|
||
return trans.First();
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取首个包含制定名字的tran
|
||
/// </summary>
|
||
/// <param name="parent"></param>
|
||
/// <param name="nameContains"></param>
|
||
/// <returns></returns>
|
||
private static List<Transform> FindTransformsByNameContains(Transform parent, string nameContains)
|
||
{
|
||
List<Transform> result = new List<Transform>();
|
||
|
||
// 检查当前对象
|
||
if (parent.name.Contains(nameContains))
|
||
{
|
||
result.Add(parent);
|
||
}
|
||
|
||
// 递归检查子对象
|
||
foreach (Transform child in parent)
|
||
{
|
||
result.AddRange(FindTransformsByNameContains(child, nameContains));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private static T[] GetSelectPrefab<T>(string ext = ".prefab") where T : Object
|
||
{
|
||
// 获取当前选中的路径
|
||
string selectedPath = GetSelectedFolderPath();
|
||
|
||
if (string.IsNullOrEmpty(selectedPath))
|
||
{
|
||
Debug.LogWarning("No folder selected.");
|
||
return Array.Empty<T>();
|
||
}
|
||
|
||
List<T> list = new List<T>();
|
||
// 获取该文件夹中的所有资产路径
|
||
string[] assetGuids = AssetDatabase.FindAssets("", new[] { selectedPath });
|
||
|
||
foreach (string guid in assetGuids)
|
||
{
|
||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||
|
||
// 检查路径是否以 ".prefab" 结尾
|
||
if (path.EndsWith(ext))
|
||
{
|
||
var prefab = AssetDatabase.LoadAssetAtPath<T>(path);
|
||
if (prefab != null)
|
||
{
|
||
list.Add(prefab);
|
||
}
|
||
}
|
||
}
|
||
|
||
return list.ToArray();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除missing的脚步
|
||
/// </summary>
|
||
/// <param name="objects"></param>
|
||
/// <returns></returns>
|
||
private static int RemoveMissingScriptsFrom(params GameObject[] objects)
|
||
{
|
||
List<GameObject> forceSave = new();
|
||
int removedCounter = 0;
|
||
foreach (GameObject current in objects)
|
||
{
|
||
if (current == null) continue;
|
||
|
||
int missingCount = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(current);
|
||
if (missingCount == 0) continue;
|
||
|
||
GameObjectUtility.RemoveMonoBehavioursWithMissingScript(current);
|
||
EditorUtility.SetDirty(current);
|
||
|
||
if (EditorUtility.IsPersistent(current) && PrefabUtility.IsAnyPrefabInstanceRoot(current))
|
||
forceSave.Add(current);
|
||
|
||
Debug.Log($"Removed {missingCount} Missing Scripts from {current.gameObject.name}", current);
|
||
removedCounter += missingCount;
|
||
}
|
||
|
||
foreach (GameObject o in forceSave) PrefabUtility.SavePrefabAsset(o);
|
||
|
||
return removedCounter;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取选中的文件夹路径
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private static string GetSelectedFolderPath()
|
||
{
|
||
// 获取当前选中的对象
|
||
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.Assets);
|
||
|
||
if (selection.Length > 0)
|
||
{
|
||
string path = AssetDatabase.GetAssetPath(selection[0]);
|
||
|
||
if (AssetDatabase.IsValidFolder(path))
|
||
{
|
||
return path;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在所有子对象中查找名字为childName的对象
|
||
/// </summary>
|
||
/// <param name="parent"></param>
|
||
/// <param name="childName"></param>
|
||
/// <returns></returns>
|
||
public static Transform FindDeepChild(Transform parent, string childName)
|
||
{
|
||
Transform result = parent.Find(childName);
|
||
if (result != null)
|
||
return result;
|
||
|
||
foreach (Transform child in parent)
|
||
{
|
||
result = FindDeepChild(child, childName);
|
||
if (result != null)
|
||
return result;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |