Unity 自定义编辑器 Raycast 在实例化对象后无法正常工作

Posted

技术标签:

【中文标题】Unity 自定义编辑器 Raycast 在实例化对象后无法正常工作【英文标题】:Unity Custom Editor Raycast Not Working Right After When Instantiate Objects 【发布时间】:2021-01-28 19:58:48 【问题描述】:
    我创建了 Test.cs 和 TestEditor.cs(Test 类是一个简单的类。) Test.cs 是空的,这里是 TestEditor.cs:
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Test))]
public class TestEditor : Editor

    Test test;
    GameObject cube;
    GameObject sphere;

    public override void OnInspectorGUI()
    
        base.OnInspectorGUI();

        test = (Test)target;

        if (GUILayout.Button("Create"))
        
            Create();
            RayCastTest();
        

        if (GUILayout.Button("RayCast Test"))
        
            RayCastTest();
        
    

    void Create()
    
        cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position = test.transform.position;
        sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position = test.transform.position + Vector3.right * 5f;
    

    void RayCastTest()
    
        Ray ray;
        RaycastHit hit;
        ray = new Ray(test.transform.position, Vector3.right);
        if (Physics.Raycast(ray, out hit, 1000f))
        
            GameObject target = hit.collider.gameObject;
            target.transform.localScale *= 2f;
        
    

    如果我在 Unity 中按下“创建”按钮,则会创建对象,但 RayCastTest() 函数不起作用。但是,如果我先按“创建”按钮,然后按“RayCast 测试”按钮,该功能就会起作用。

那么,我怎样才能让 RayCastTest() 函数在第一部分工作?

【问题讨论】:

【参考方案1】:

光线投射来自Physics 引擎。 Afaik 它仅在 Physics 更新后才有效,因为在此之前 Collider 可能尚未重新计算 -> Physics 尚不“知道” Collider

您可以尝试在您的Create 之后使用Physics.Simulate 强制它

if (GUILayout.Button("Create"))

    Create();
    Physics.Simulate(Time.fixedDeltaTime);
    RayCastTest();


此外,您可能必须禁用Physics.autoSimulation .. 不幸的是,API 对此并不太清楚。如果是这样,你可能会这样做

     Physics.autoSimulation = false;
     Physics.Simulate(Time.fixedDeltaTime);
     Physics.autoSimulation = true;

Physics.SyncTransforms 也可能有帮助

Transform 组件更改时,该Transform 或其子级上的任何RigidbodyCollider 可能需要根据Transform 的更改重新定位、旋转或缩放。使用此函数手动将这些更改刷新到 Physics 引擎。

由于您要移动创建的对象,因此您可能还必须在模拟之前调用它(再次可能需要与Physics.autoSyncTransforms一起使用)

if (GUILayout.Button("Create"))

    Create();
    
    Physics.SyncTransforms();

    Physics.autoSimulation = false;
    Physics.Simulate(Time.fixedDeltaTime);
    Physics.autoSimulation = true;

    RayCastTest();

【讨论】:

很好的解释......谢谢。

以上是关于Unity 自定义编辑器 Raycast 在实例化对象后无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Unity (C#) - 如何在销毁/重生系统中挑选出被 Raycast 检测到的 GameObject

Raycast 不在电话上工作,但在 Unity 编辑器上工作

使用光线投射和实例化对象问题检查与多边形碰撞器的碰撞(统一)

Unity3D研究院编辑器之不实例化Prefab获取删除更新组件(十五)

unity游戏自定义分辨率 教你如何自定义

在 Unity 中沿光线投射实例化预定义数量的对象