Unity Custom Editor Raycast Not Working Right After When Instantiate Objects
Asked Answered
M

1

0
  1. I created Test.cs and TestEditor.cs (Test class is a simple class.)
  2. Test.cs is empty and here is 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. If I press the "Create" button in Unity, the objects are created but the RayCastTest() function does not work. But, if I press the "Create" button first and then the "RayCast Test" button, the function works.

So, How can I get the RayCastTest() function to work in the first part?

Murder answered 14/10, 2020 at 12:4 Comment(0)
T
3

The raycast is from the Physics engine. Afaik it only works after one Physics update since before that the Collider might not be recalculated yet ->The Physics doesn't "know" that Collider yet.

You could try and force it using Physics.Simulate after your Create

if (GUILayout.Button("Create"))
{
    Create();
    Physics.Simulate(Time.fixedDeltaTime);
    RayCastTest();
}

Additionally you might have to disable the Physics.autoSimulation .. unfortunately the API isn't so clear on that. If it is the case you might do it like

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

Also Physics.SyncTransforms might help

When a Transform component changes, any Rigidbody or Collider on that Transform or its children may need to be repositioned, rotated or scaled depending on the change to the Transform. Use this function to flush those changes to the Physics engine manually.

Since you are moving your created objects you might additionally have to call this (again might be necessary to be used together with Physics.autoSyncTransforms) before the simulation like

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

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

    RayCastTest();
}
Thriftless answered 14/10, 2020 at 12:16 Comment(1)
Good explanation.. Thanks.Murder

© 2022 - 2024 — McMap. All rights reserved.