Unity工具脚本-检测文件夹中有预制体引用指定Layer、指定脚本

效果:

先在菜单栏里面找到Tools/CheckPrefab打开窗口

代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class CheckPrefabLayers : EditorWindow
{
    private Vector2 scrollViewPosition;
    [MenuItem("Tools/Check Prefab")]
    static void Init()
    {
        // 创建窗口实例并显示
        CheckPrefabLayers window = (CheckPrefabLayers)EditorWindow.GetWindow(typeof(CheckPrefabLayers));
        window.Show();
    }
    void OnGUI()
    {
        scrollViewPosition = EditorGUILayout.BeginScrollView(scrollViewPosition); // 开始滚动视图
        //检查用了指定层级的预制体
        CheckReferLayers();
        GUILayout.Space(10);
        //检查用了指定脚本的预制体
        CheckReferScripts();
        EditorGUILayout.EndScrollView();
    }


    #region ---------------------------------检测所有用指定层级的物体----------------------------------
    private int selectedLayerIndex = 0;
    private List<GameObject> referLayerPrefabs = new List<GameObject>();
    private void CheckReferLayers()
    {
        GUILayout.Label("查找指定层级", EditorStyles.boldLabel);
        string[] layerNames = UnityEditorInternal.InternalEditorUtility.layers;
        selectedLayerIndex = EditorGUILayout.Popup("检查层级:", selectedLayerIndex, layerNames);
        if (GUILayout.Button("查找层级引用"))
        {
            CheckLayers();
        }
        ShowPrefabs(referLayerPrefabs);
    }
    private void CheckLayers()
    {
        referLayerPrefabs.Clear();
        
        //获取所有物体的GUID
        string[] allPrefabGUID = AssetDatabase.FindAssets("t:Prefab");
        
        foreach (string prefabPath in allPrefabGUID)
        {
            string prefabFullPath = AssetDatabase.GUIDToAssetPath(prefabPath);
            // 加载预制体
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabFullPath);

            // 检查预制体的 Layer 层级
            if (prefab != null && prefab.layer ==selectedLayerIndex)
            {
                //检测子物体
                Transform[] childObjs = prefab.GetComponentsInChildren<Transform>(true);
                for (int i = 0; i < childObjs.Length; i++)
                {
                    if (childObjs[i].gameObject.layer == selectedLayerIndex)
                    {
                        referLayerPrefabs.Add(prefab);
                        break;
                    }
                }
            }
        }
        Repaint();
        Debug.LogWarning("检测完毕");
    }
    
    #endregion


    #region ------------------------------检测所有引用此脚本的预制体------------------------------------
    private MonoScript targetScript;
    private List<GameObject> referScriptPrefabs = new List<GameObject>();
    private void CheckReferScripts()
    {
        GUILayout.Label("查找指定脚本", EditorStyles.boldLabel);
        targetScript = (MonoScript)EditorGUILayout.ObjectField("指定脚本", targetScript, typeof(MonoScript), false);
        if (GUILayout.Button("查找脚本引用"))
        {
            FindReferences();
        }
        ShowPrefabs(referScriptPrefabs);
    }
    
    void FindReferences()
    {
        referScriptPrefabs.Clear();

        if (targetScript == null)
        {
            Debug.LogError("请选择一个脚本");
            return;
        }
        
        string[] allPrefabGUID = AssetDatabase.FindAssets("t:Prefab");

        foreach (var prefabPath in allPrefabGUID)
        {
            string prefabFullPath = AssetDatabase.GUIDToAssetPath(prefabPath);
            
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabFullPath);

            if (PrefabHasScript(prefab))
            {
                referScriptPrefabs.Add(prefab);
            }
        }

        Repaint();
        Debug.LogWarning("检测完毕");
    }

    //检测预制体是否有指定脚本
    bool PrefabHasScript(GameObject prefab)
    {
        Type targetType = targetScript.GetClass();

        MonoBehaviour[] behaviours = prefab.GetComponentsInChildren<MonoBehaviour>(true);
        foreach (MonoBehaviour behaviour in behaviours)
        {
            MonoScript monoScript = MonoScript.FromMonoBehaviour(behaviour);
            if (monoScript != null && monoScript.GetClass() == targetType)
            {
                return true;
            }
        }

        return false;
    }
    #endregion

    #region ------------------------------------将预制体列表显示出来-------------------------------

    private void ShowPrefabs(List<GameObject> list)
    {
        GUILayout.Label("预制体列表展示:", EditorStyles.boldLabel);
        foreach (var prefab in list)
        {
            EditorGUILayout.ObjectField(prefab, typeof(GameObject), false);
        }
    }

    #endregion
}

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中将文件夹中的预制放在指定位置,可以通过以下步骤实现。 首先,我们需要创建一个空的游戏对象,作为后续预制的父对象。在Unity的Hierarchy面板中,选择Create - Empty Object来创建一个空的游戏对象。 接下来,我们需要将文件夹中的预制导入到Unity项目中。在Unity的Project面板中,找到需要导入的预制文件夹,将其拖拽到Unity的Project面板中的一个目录下,导入到项目中。 然后,我们需要在场景中创建一个空的游戏对象,并将其作为实例化的预制的父对象。在Unity的Hierarchy面板中,选择Create - Empty Object来创建一个空的游戏对象。 接着,我们需要编写代码来加载预制,并将其放置在指定位置。在Unity中可以使用Instantiate函数来实例化预制。我们可以通过代码获取到需要放置预制的位置信息,并将实例化的预制设置为父对象的子对象。 最后,我们将实例化的预制设置为父对象的子对象后,就可以调整它在场景中的位置。可以通过代码设置预制的Position、Rotation、Scale等属性,来调整其在场景中的具位置。 总结起来,我们可以通过在Unity中创建空的游戏对象、导入预制、实例化预制并设置其位置来将文件夹中的预制放置在指定位置。这样可以方便地管理和定位预制,提高项目开发的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值