Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Detect specific rope collision.
#11
(19-11-2020, 02:24 PM)canerozdemir Wrote: Oh, I missed that one. However, the outcome is still the same. FPS drop happens and the game becomes unplayable. This is the code: 


Code:
public class RopeCollision : MonoBehaviour
{
    private ObiSolver _solver;

    private ObiSolver.ObiCollisionEventArgs _collisionEvent;

    private void Awake()
    {
        _solver = GetComponent<ObiSolver>();
    }

    private void OnEnable ()
    {
        _solver.OnParticleCollision += Solver_OnParticleCollision;
    }

    private void OnDisable()
    {
        _solver.OnParticleCollision -= Solver_OnParticleCollision;
    }

    private void Solver_OnParticleCollision (object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            if (contact.distance < 0.01)
            {
                var theCollider = world.colliderHandles[contact.other].owner;
                if (theCollider)
                {
                    print(theCollider.name);
                }
            }
        }
    }
}

Well, you're writing the collider name to console once per contact, no wonder performance goes down the drain  Huh. Writing to the console is extremely slow.
Remove the print() line and it should run acceptably fast.

Edit: also, you're using the second index of the contact (which for particle-particle contacts, is a particle index) to access the collider handles array, which will result in an out of bounds exception.
Reply
#12
(19-11-2020, 02:25 PM)josemendez Wrote: Well, you're writing the collider name to console once per contact, no wonder performance goes down the drain  Huh. Writing to the console is extremely slow.
Remove the print() line and it should run acceptably fast.

Edit: also, you're using the second index of the contact (which for particle-particle contacts, is a particle index) to access the collider handles array, which will result in an out of bounds exception.

I wasn't paying attention to the documentation, I believe. I wasn't being careful, because I thought it would work like CollisionStay callback but I forgot that I am actually calling for a particle collision which is very expensive considering that I have over 4000 particles on the scene Gran sonrisa This code actually does what I want: 

Code:
private void Solver_OnParticleCollision(object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            if (contact.distance < 0.01)
            {
                var pa = _solver.particleToActor[contact.particle];
                var po = _solver.particleToActor[contact.other];
                if (pa.actor.gameObject != po.actor.gameObject)
                {
                    Debug.Log(pa.actor.gameObject.name + " collides with: " + po.actor.gameObject.name);
                }
            }
        }
    }

I can now receive an information about who collides with whom. Therefore, I can now detect when a rope is colliding with another one and I can use it to expand the gameplay further. Thank you for putting out the obvious that I was missing out Gran sonrisa.
Reply
#13
(19-11-2020, 02:41 PM)canerozdemir Wrote: I wasn't paying attention to the documentation, I believe. I wasn't being careful, because I thought it would work like CollisionStay callback but I forgot that I am actually calling for a particle collision which is very expensive considering that I have over 4000 particles on the scene Gran sonrisa This code actually does what I want: 

Code:
private void Solver_OnParticleCollision(object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            if (contact.distance < 0.01)
            {
                var pa = _solver.particleToActor[contact.particle];
                var po = _solver.particleToActor[contact.other];
                if (pa.actor.gameObject != po.actor.gameObject)
                {
                    Debug.Log(pa.actor.gameObject.name + " collides with: " + po.actor.gameObject.name);
                }
            }
        }
    }

I can now receive an information about who collides with whom. Therefore, I can now detect when a rope is colliding with another one and I can use it to expand the gameplay further. Thank you for putting out the obvious that I was missing out Gran sonrisa.

That's 100% correct. Glad you got it working! Sonrisa.

Forgive me for not giving you the solution straight away. I'm a bit hesitant of giving ready-made solutions for this kind of thing, as understanding the code you're using is paramount. Later down the road, fixing someone else's code that you didn't get to properly understand is often harder than writing your own Sonrisa
Reply
#14
(19-11-2020, 02:50 PM)josemendez Wrote: That's 100% correct. Glad you got it working! Sonrisa.

Forgive me for not giving you the solution straight away. I'm a bit hesitant of giving ready-made solutions for this kind of thing, as understanding the code you're using is paramount. Later down the road, fixing someone else's code that you didn't get to properly understand is often harder than writing your own Sonrisa

Ah yes, I can't argue with you there. However, you have been more than helpful to me in this couple of weeks. I never expected a fast support like this when I started using the Obi Rope. Thank you again for being a reliable provider Sonrisa
Reply
#15
(19-11-2020, 02:24 PM)canerozdemir Wrote: Oh, I missed that one. However, the outcome is still the same. FPS drop happens and the game becomes unplayable. This is the code: 


Code:
public class RopeCollision : MonoBehaviour
{
    private ObiSolver _solver;

    private ObiSolver.ObiCollisionEventArgs _collisionEvent;

    private void Awake()
    {
        _solver = GetComponent<ObiSolver>();
    }

    private void OnEnable ()
    {
        _solver.OnParticleCollision += Solver_OnParticleCollision;
    }

    private void OnDisable()
    {
        _solver.OnParticleCollision -= Solver_OnParticleCollision;
    }

    private void Solver_OnParticleCollision (object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            if (contact.distance < 0.01)
            {
                var theCollider = world.colliderHandles[contact.other].owner;
                if (theCollider)
                {
                    print(theCollider.name);
                }
            }
        }
    }
}

why am I getting this error :- Assets/Scripts/RopeCollision.cs(37,58): error CS1061: 'Oni.Contact' does not contain a definition for 'particle' and no accessible extension method 'particle' accepting a first argument of type 'Oni.Contact' could be found (are you missing a using directive or an assembly reference?)


Assets/Scripts/RopeCollision.cs(38,58): error CS1061: 'Oni.Contact' does not contain a definition for 'other' and no accessible extension method 'other' accepting a first argument of type 'Oni.Contact' could be found (are you missing a using directive or an assembly reference?)
Reply
#16
(04-07-2022, 11:57 AM)Gauri7 Wrote: why am I getting this error :- Assets/Scripts/RopeCollision.cs(37,58): error CS1061: 'Oni.Contact' does not contain a definition for 'particle' and no accessible extension method 'particle' accepting a first argument of type 'Oni.Contact' could be found (are you missing a using directive or an assembly reference?)


Assets/Scripts/RopeCollision.cs(38,58): error CS1061: 'Oni.Contact' does not contain a definition for 'other' and no accessible extension method 'other' accepting a first argument of type 'Oni.Contact' could be found (are you missing a using directive or an assembly reference?)

Hi,

Contacts do not have “particle” or “other” member variables.

You must use contact.bodyA to access the simplex, and contact.bodyB to access the collider. See the scripting section of the manual for details:
http://obi.virtualmethodstudio.com/manua...sions.html
Reply
#17
(04-07-2022, 01:23 PM)josemendez Wrote: Hi,

Contacts do not have “particle” or “other” member variables.

You must use contact.bodyA to access the simplex, and contact.bodyB to access the collider. See the scripting section of the manual for details:
http://obi.virtualmethodstudio.com/manua...sions.html

yes I am using bodyA and bodyB but it always gives the wrong ropes ( I mean wrong names of colliding ropes )

this is the script :
Code:
using System.Collections;
using System.Collections.Generic;
using Obi;
using UnityEngine;

public class RopeCollision : MonoBehaviour
{

    private ObiSolver _solver;

    private ObiSolver.ObiCollisionEventArgs _collisionEvent;

    private void Awake()
    {
        _solver = GetComponent<ObiSolver>();
    }

    private void OnEnable()
    {
        _solver.OnParticleCollision += Solver_OnParticleCollision;
    }

    private void OnDisable()
    {
        _solver.OnParticleCollision -= Solver_OnParticleCollision;
    }

    private void Solver_OnParticleCollision(object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            //Debug.Log(contact.pointA + " pt");
            if (true || contact.distance < 0.01f)
            {
                var pa = _solver.particleToActor[contact.bodyA];
                var po = _solver.particleToActor[contact.bodyB];
               
                if (pa.actor.gameObject != po.actor.gameObject)
                {
                    Debug.Log(pa.actor.gameObject.name + " collides with: " + po.actor.gameObject.name);
                }
            }


        }
    }
}
Reply
#18
(04-07-2022, 02:12 PM)Gauri7 Wrote: yes I am using bodyA and bodyB but it always gives the wrong ropes ( I mean wrong names of colliding ropes )

this is the script :
Code:
using System.Collections;
using System.Collections.Generic;
using Obi;
using UnityEngine;

public class RopeCollision : MonoBehaviour
{

    private ObiSolver _solver;

    private ObiSolver.ObiCollisionEventArgs _collisionEvent;

    private void Awake()
    {
        _solver = GetComponent<ObiSolver>();
    }

    private void OnEnable()
    {
        _solver.OnParticleCollision += Solver_OnParticleCollision;
    }

    private void OnDisable()
    {
        _solver.OnParticleCollision -= Solver_OnParticleCollision;
    }

    private void Solver_OnParticleCollision(object sender, ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (var contact in e.contacts)
        {
            // this one is an actual collision:
            //Debug.Log(contact.pointA + " pt");
            if (true || contact.distance < 0.01f)
            {
                var pa = _solver.particleToActor[contact.bodyA];
                var po = _solver.particleToActor[contact.bodyB];
              
                if (pa.actor.gameObject != po.actor.gameObject)
                {
                    Debug.Log(pa.actor.gameObject.name + " collides with: " + po.actor.gameObject.name);
                }
            }


        }
    }
}

bodyA and bodyB are simplex indices, cannot be used to access the particleToActor array directly. You must get the particle index from the simplex index first. Check the sample code in the manual, the link I provided in the previous post.

Cheers!
Reply
#19
(04-07-2022, 07:52 PM)josemendez Wrote: bodyA and bodyB are simplex indices, cannot be used to access the particleToActor array directly. You must get the particle index from the simplex index first. Check the sample code in the manual, the link I provided in the previous post.

Cheers!

hello , 
thanks , this thing worked 

i have one more question , can we have collision in only middle part of the rope ? ( no collision detection at end of the ropes only mid part)
Reply
#20
(05-07-2022, 09:33 AM)Gauri7 Wrote: hello , 
thanks , this thing worked 

i have one more question , can we have collision in only middle part of the rope ? ( no collision detection at end of the ropes only mid part)

You can control collision behavior for each individual particle in the rope. This is done using collision filters, see:

http://obi.virtualmethodstudio.com/manua...sions.html

In-editor, filters are specified for each control point in the blueprint. At runtime you can set the filter value for each particle by writing into the solver.filters array.
Reply