Raycast and OnTriggerEnter performance

Hi.

I have several small objects the player (FPS) can interact with.
Examples:

  • a door and the player can interact with the doorknob to open the door
  • a machine with a button on it to power on the machine
  • a weapon on the ground to pick it up

I shoot a raycast from the players view to check if the player is looking at the object

What is best performance wise:

  1. Constantly shoot the raycast?

  2. Have a OnTriggerEnter on every interactive object and shoot a raycast only when the player enters the trigger?

I believe you are putting your performance efforts in the wrong place. Colliders or Raycasts are pretty efficient. They are the backbone of many apps. When I have these kinds of questions, I run a test to see what I get. So here is a basic FPS script:

#pragma strict

private var data : float[] = new float[160];
private var i = 0;
private var fps : int;

function Update () {
	data *= Time.time;*
  • i = (i + 1) % data.Length;*
  • fps = 0;*
  • for (var j = 0; j < data.Length; j++) {*
  •  if (data[j] > 0 && data[j] >= Time.time - 1.0)*
    
  •  	fps++;*
    
  • }*
    }

function OnGUI() {

  • GUI.Label(Rect(10,10,100,50), fps.ToString());*
    }
    And here is a test script. It creates a set of planes and then Raycasts() against those planes. The spacebar doubles the number of Raycasts().
    #pragma strict

private var casts = 1;
private var planes = 200;

function Start() {

  • for (var i = 0; i < planes; i++) {*
  •  var go = GameObject.CreatePrimitive(PrimitiveType.Plane);*
    
  •  go.AddComponent.<MeshCollider>();*
    
  •  go.transform.rotation = Random.rotation;*
    

_ go.transform.position = Random.insideUnitSphere * 10.0;_

  • } *

}

function Update () {

  • var hit : RaycastHit;*

  • for (var i = 0; i < casts; i++) {*

  •  Physics.Raycast(transform.position, Random.onUnitSphere, hit);*
    
  • }*

  • if (Input.GetKeyDown(KeyCode.Space)) {*
    _ casts *= 2;_

  • }*
    }

function OnGUI() {

  • GUI.Label(Rect(10,60,50,100), casts.ToString());*
    }
    Put both scripts on an empty game object or the camera and hit play. Start hitting the space bar to increase (double) the number of casts. See when you get an FPS drop. For me in the editor, it was 2048 casts when I first see a drop, but for an accurate test, you would want to use object representative of the complexity you have in your game, and you would want to run on the target device. But my point is, that one continuous Raycast() is not a big deal.
    And if you ended up with enough raycasts and/or objects for raycasting to become a problem, then there are ways to mitigate the issue.
    - Make sure you have the objects that you want to detect on their own layer and use a layer mask in the Raycast().
    - Use a distance check to avoid raycasting when nothing is in range.
    - Use an angle check to make sure the player can ‘see’ the object
    The Unity Wiki also has an FPS script:
    http://wiki.unity3d.com/index.php?title=FramesPerSecond