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

问题描述

  1. 我创建了Test.cs和TestEditor.cs(Test类是一个简单的类。)
  2. 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;
        }
    }
}
  1. 如果我在Unity中按下“创建”按钮,则会创建对象,但RayCastTest()函数将不起作用。但是,如果我先按“创建”按钮,然后按“ RayCast测试”按钮,则该功能有效。

那么,如何使RayCastTest()函数在第一部分中起作用?

解决方法

射线广播来自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组件发生更改时,可能需要重新定位,旋转或缩放Rigidbody或其子元素上的任何ColliderTransform或子元素。 Transform。使用此功能可将这些更改手动刷新到Physics引擎。

由于要移动创建的对象,因此在模拟之前,可能还必须调用此对象(再次与可能)

if (GUILayout.Button("Create"))
{
    Create();
    
    Physics.SyncTransforms();

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

    RayCastTest();
}