x


OnCollisionStay perfomance

Hi,

I have a large scene with many collisions and OnCollisionStay is consuming too much resources. I'd like this event to be fired every seconds. Is somebody have a tip for this? I have tried "yield return new WaitForSeconds(1.0f);" but it doesn't prevent from firing.

Is there another way to get existing collision information without OnCollisionStay?

Thanks Harold

EDITED: Thanks for your answer.

But the problem is that my collision is changing each frame and I need more than the existence of the contact.

Vector3 GetContactsBarycenter(ContactPoint[] points, GameObject target)
{
    Vector3 bar = Vector3.zero;
    foreach (ContactPoint pt in points)
        bar += pt.point;
    return target.transform.InverseTransformPoint(bar / (float)points.Length);
}
IEnumerator OnCollisionStay(Collision collision)
{
    Debug.DrawRay(collision.gameObject.transform.TransformPoint(
            GetContactsBarycenter(collision.contacts, collision.gameObject)),
            collision.gameObject.transform.TransformDirection(Vector3.up),
            Color.green);
    yield return 0;
}
more ▼

asked Dec 22 '11 at 09:01 AM

HPx gravatar image

HPx
16 2 2 4

@HPx, I edited your question and added the script to it (the Your answer box must be used only to post answers - UA is different from forums)

Dec 22 '11 at 11:10 AM aldonaletto
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

Why do you need to use OnCollisionStay? Saving a copy of contacts during OnCollisionEnter could be enough, depending on what you need to do:

var myContacts: ContactPoint[];

function OnCollisionEnter(coll: Collision){
  myContacts = coll.contacts;
}

You should edit your question an post your script - we could check it and have more ideas on how to reduce the CPU load.

EDITED:

OnCollisionStay is called each physics cycle while the rigidbody is awake - even if you disable the script - but maybe you could reduce the load by calling the barycenter calculation routine only at some interval, like this:

public float baryInterval = 1; // report barycenter each second
float baryTime = 0;

Vector3 GetContactsBarycenter(ContactPoint[] points, GameObject target)
{
    Vector3 bar = Vector3.zero;
    foreach (ContactPoint pt in points)
        bar += pt.point;
    return target.transform.InverseTransformPoint(bar / (float)points.Length);
}

void OnCollisionStay(Collision collision)
{
    if (Time.time > baryTime){ // report only when the time has come
        baryTime = Time.time + baryInterval; // calculate new baryTime
        Debug.DrawRay(collision.gameObject.transform.TransformPoint(
            GetContactsBarycenter(collision.contacts, collision.gameObject)),
            collision.gameObject.transform.TransformDirection(Vector3.up),
            Color.green);
    }
}

Physx will still have to calculate the contact points each time, but at least your code will only execute at the defined interval.

more ▼

answered Dec 22 '11 at 10:06 AM

aldonaletto gravatar image

aldonaletto
41.5k 16 42 197

I don't think my code influence anything.

What is time-consuming is the computing of Collision structure. What's why I'd like to execute it once a second or if it's not possible to store collisions in a list with Enter and Exit and calculate Collision struct in a co-routine, but I'm not sure it's possible.

Dec 22 '11 at 11:42 AM HPx

I think it's rather a problem of physX than Unity. I think I've reached the joint number limitations. It would be better if PhysX was multithreaded.

Thanks anyway.

Dec 22 '11 at 01:44 PM HPx

Physx and Unity functions run much faster than our code: they are created in C++ or other high level languages and compiled to native machine code, while our scripts are compiled to CIL, an interpreted language that has a lot of overhead. Generating the Collision structure takes time, for sure, but maybe reducing the script part you get some appreciable speed improvement. I once had a script that used Debug.DrawRay to show the contact normals of 8 blocks, and it reduced the frame rate to ridiculous levels; when I removed the Debug instructions, the frame rate returned to the regular speed.

Dec 22 '11 at 02:58 PM aldonaletto
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x19

asked: Dec 22 '11 at 09:01 AM

Seen: 739 times

Last Updated: Dec 22 '11 at 02:58 PM