Best aproach for Car Vision?

Guys, im working with cars for the first time. In my first test i used a single raycast for collision detection, it works fine with other cars(they all follow a path) but if the player is in front of the car the raycast will not aways detect it. So i moved to sphere cast, working fine but with high performance cost. Then my client changed his mind and now want 120 cars moving. Is there a better to do the car vision with a “not so high” performance cost?

Attached an image to represent my problem with the single raycast.

In the first scenario the car just cas his ray without colliding
In the second scenario there is a car collision, no problem there.
In the third scenario the player is RIGHT IN FRONT of the car, the collision works fine
In the fourth scenario the player moves a bit and the collision is no more and the car will run over the player

Thanks and sorry for the bad english

You say Collision detection and you say Vision - which one is it?

Collision detection, sorry for my mistake.

No, he means obstacle avoidance.

To start, you need a way to “see” object that are around the car with a relatively low cost. The best solution that I have seen is to have each vehicle and person have a large sphere collider set as a trigger, say 30 units. Everytime that something enters the area it would be added to a List, whenver they leave, it is removed. Using this method means that your not having to constantly do searches for stuff.

With that, all you then have to do is go down the list and check the Vector3.Dot to the object and see if it is facing towards the obstacle. So lets say a Dot of greater than .66 (or about 60 degrees and a distance of lets say 20 units would net you all obstacles in the immediate front area of the vehicle.

You could omit raycast and just use triggers. A large trigger cube or offset trigger sphere parented to the back of each car will yield the same result at cheaper cost. Remember to give the trigger a rigidbody set to isKinematic so physx understands it is dynamic and will not try to kill the framerate optimising it.

An alternative approach which is faster still will be to divide the area up into a large grid (a 2D array), and each loop (or spread across loops) you’ll update the grid. This means it is a simple Bresenham's line algorithm - Wikipedia check in the array to determine if there is a potential car. If there is a potential car, then you can do the more expensive raycast check. Bear in mind, physx triggers do a similar check themselves, although a bit more heavy.

This will reduce the number of raycasts you need to do per loop to something really managable ie 128 cars checking * 128 cars (16,384 checks) would probably drop to 128 or so per frame run fine on mobiles even, with no lack of precision.

To get even faster, you’d want to further stagger how often each car checks ie do 10 cars per frame, which is still fine.

I will for sure try the .Dot aproach, but how do you add objects to the list?

Pseudocode:

class player : MonoBehavior
{
       void OnTriggerEnter(collider o)
       {
                if(o.gameobject.tag == "car")
                {
                     o.gameobject.GetComponent<car>().AddToList();
                }
       }

       void OnTriggerExit(collider o)
       {
                if(o.gameobject.tag == "car")
                {
                     o.gameobject.GetComponent<car>().RemoveFromList();
                }
       }
}

This way ill have car related code inside the player, is this correct?

And just to confirm: The car is locked on a path i just want it to stop and go as obstacles appear on the way.

The trigger solutions seens so simple, how could i not think of it hehe

I will for sure try your solution as well, thanks!

something like this:

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

public class example : MonoBehaviour {
	List<GameObject> list;
	
	void Start(){
		list = new List<GameObject>();
	}
	
	void OnTriggerEnter(Collider other) {
		GameObject go = other.gameObject.transform.root.gameObject;
		if(go.tag=="Vehicle" || go.tag=="Person"){
			if(list.indexOf(go)==-1) list.Add(go);
		}
	}
	
	void OnTriggerExit(Collider other) {
		GameObject go = other.gameObject.transform.root.gameObject;
		if(go.tag=="Vehicle" || go.tag=="Person"){
			if(list.indexOf(go)>-1) list.Remove(go);
		}
	}
}

Remember to give the trigger a rigidbody set to isKinematic so physx understands it is dynamic and will not try to kill the framerate optimising it. (if you’re trying triggers)

Where can i obtain more info about this? For me a simple box collider was the “fastest” way to do collisions with low cost :frowning:

Thanks

The lowest cost collider is a sphere. It basically is a vector and a distance. A cube is height, width, length, position and rotation.

Wow! thats nice! This thread is already bookmarked just need to know about the rigidbody set to kinematic :smile:

If you look in the inspector for the rigid body, there is a check box for isKinematic. :wink:

you can also set it via script:

i´ve used kinematic objects before :slight_smile: But never aware of this performance problem with simple box colliders, i want to know why a rigidbody set to kinematic, that in my mind was aways more expensive, is better than a simple box collider.

I have a project with some trees using box collider should i use rigidbody with kinematic set to on instead? :face_with_spiral_eyes:

box collider or sphere collider is SLOW if it does not have a rigidbody, if you’re MOVING it. Because physx rebuilds collision tables. It thinks you’re moving stuff around as part of level setup or whatever.

You need to hint to the engine not to do this by adding a kinematic rigidbody if your triggers or colliders will move.

I believe Hippo is refering to adding a new child to your vehicle or person, giving it a sphere collider (assigning that as a trigger) and a rigid body and assigning the rigidbody’s isKinematic to true.

If not, he needs to be a bit more specific because we know you want vehicles and those should not be set to isKinematic. :wink:

Thanks!

If someone can provide documentation, even physX docs, it would be a great addition