unity如何查找某个脚本挂在了哪些物体上

在开发中往往会遇到一个问题:不知道整个场景中究竟有哪些物体挂载了某一个脚本。如果挨个查找太麻烦了,下面有一种方法可以快速找到解决这个问题

在unity的Window里有一项Editor tests runner 选择这个会出现一个窗口:如下图:

然后点击创建脚本会有脚本自动创建在project里的Editor下。之后我们要写两个脚本(如下图)



这两个脚本代码,一个是用来盛放要被找的那些物体另个是盛放你要来查找被物体挂载的脚本:

盛放物体的代码:

using UnityEngine;
using UnityEditor;
public class FindMissingScriptsRecursively : EditorWindow
{
    static int go_count = 0, components_count = 0, missing_count = 0;

    [MenuItem("Window/FindMissingScriptsRecursively")]
    public static void ShowWindow()
    {
        EditorWindow.GetWindow(typeof(FindMissingScriptsRecursively));
    }

    public void OnGUI()
    {
        if (GUILayout.Button("Find Missing Scripts in selected GameObjects"))
        {
            FindInSelected();
        }
    }
    private static void FindInSelected()
    {
        GameObject[] go = Selection.gameObjects;
        go_count = 0;
        components_count = 0;
        missing_count = 0;
        foreach (GameObject g in go)
        {
            FindInGO(g);
        }
        Debug.Log(string.Format("Searched {0} GameObjects, {1} components, found {2} missing", go_count, components_count, missing_count));
    }

    private static void FindInGO(GameObject g)
    {
        go_count++;
        Component[] components = g.GetComponents<Component>();
        for (int i = 0; i < components.Length; i++)
        {
            components_count++;
            if (components[i] == null)
            {
                missing_count++;
                string s = g.name;
                Transform t = g.transform;
                while (t.parent != null)
                {
                    s = t.parent.name + "/" + s;
                    t = t.parent;
                }
                Debug.Log(s + " has an empty script attached in position: " + i, g);
            }
        }
        // Now recurse through each child GO (if there are any):  
        foreach (Transform childT in g.transform)
        {
            //Debug.Log("Searching " + childT.name  + " " );  
            FindInGO(childT.gameObject);
        }
    }
}

盛放脚本的代码:

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

/
//查找节点及所有子节点中,是否有指定的脚本组件
/
public class MonoFinder : EditorWindow
{
    Transform root = null;
    MonoScript scriptObj = null;
    int loopCount = 0;

    List<Transform> results = new List<Transform>();

    [MenuItem("Level4/Finder/MonoFinder")]
    static void Init()
    {
        EditorWindow.GetWindow(typeof(MonoFinder));
    }

    void OnGUI()
    {
        GUILayout.Label("节点:");
        root = (Transform)EditorGUILayout.ObjectField(root, typeof(Transform), true);
        GUILayout.Label("脚本类型:");
        scriptObj = (MonoScript)EditorGUILayout.ObjectField(scriptObj, typeof(MonoScript), true);
        if (GUILayout.Button("Find"))
        {
            results.Clear();
            loopCount = 0;
            Debug.Log("开始查找.");
            FindScript(root);
        }
        if (results.Count > 0)
        {
            foreach (Transform t in results)
            {
                EditorGUILayout.ObjectField(t, typeof(Transform), false);
            }
        }
        else
        {
            GUILayout.Label("无数据");
        }
    }

    void FindScript(Transform root)
    {
        if (root != null && scriptObj != null)
        {
            loopCount++;
            Debug.Log(".." + loopCount + ":" + root.gameObject.name);
            if (root.GetComponent(scriptObj.GetClass()) != null)
            {
                results.Add(root);
            }
            foreach (Transform t in root)
            {
                FindScript(t);
            }
        }
    }
}
有了这两个脚本,会发现unity的菜单里会多出一个level4(如图)的选项,然后点击它,会出现一个弹窗。上面那个节点(如图)就是盛放物体的,下面那个脚本类型(如图)就是放脚本的。

例如下面的案例中,我要查找一个名字叫AsyncImageDownloader的脚本在panoramic这个物体里有多少被挂载了。直接把对应的东西拖进去,然后点击find就会发现在userhead_portrait这个子物体里有这个脚本。



这种方法可以找到所有父物体下的子物体中所有的挂载。它会遍历整个父物体中个的子物体

从下图中可以看出在panoramic这个父物体中有575个子物体,它们都被查找了一遍。可见刚才查到只有userhead_portrait上挂载了刚才要找的脚本。


### 如何在 Unity 中将脚本附加到游戏对象上 #### 使用 C# 脚本挂载至 GameObject 为了使 Lua 或其他类型的脚本能像 C# 脚本一样挂载到 `GameObject` 上,在 Unity 中通常的做法是创建一个中介 C# 组件,该组件负责加载并执行相应的 Lua 逻辑[^1]。 对于标准的 C# 脚本而言,可以直接通过以下方式完成挂载: - **编写脚本**:先按照需求开发好所需的 C# 类型脚本。例如,如果要实现基本的对象移动功能,则会有一个类似于下面这样的简单运动控制类定义[^4]: ```csharp using System.Collections; using System.Collections.Generic; using UnityEngine; public class Movement : MonoBehaviour { public Rigidbody2D starBody; public float speed; private void Start() { // 初始化操作可在此处进行设置 } private void Update() { starBody.velocity = new Vector2( Input.GetAxisRaw("Horizontal") * speed, Input.GetAxisRaw("Vertical") * speed); } } ``` - **保存脚本**:确保上述代码被妥善存入项目的 Assets 文件夹下的 Scripts 子目录内,并命名为 `Movement.cs`。 - **选择目标 GameObject**:进入 Unity 编辑器后,找到想要关联此行为的游戏对象(即 `GameObject`),可以通过 Hierarchy 面板选取。 - **添加组件**: - 方法一:右键点击所选对象 -> Add Component... -> Custom -> 浏览直至定位到刚刚编写的 `Movement` 并双击确认; - 方法二:直接把 Script 文件从 Project 视图拖拽到 Inspector 窗口内的 Components 列表区域; 一旦成功应用了这些步骤之后,就可以看到新加入的行为已经作为一项属性列于选定实体之下,并允许进一步调整公开字段参数值,比如速度 (`speed`) 和刚体引用 (`starBody`) 的设定。 另外值得注意的是,当涉及到更复杂的交互或是希望能在编辑状态下获取额外视觉反馈时,还可以考虑利用 Editor 扩展机制来增强用户体验,就像文中提到的方法可以在编辑期间向场景视图中的特定实例添加序号标签那样[^2]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值