Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  ObiRope Collided Object Info Retrieving
#1
Triste 
Hi there, 
I want to make a 2d game where you spawn balls to land on ropes. After a ball collides with rope it will self destruct. So I need help with getting the info of the collided object. I looked at the main page and a few forums, tried to do a few things but ended up with spahetti code and confusion. Can please someone help me?

    public ObiSolver solver;
    Obi.ObiSolver.ObiCollisionEventArgs frame;
    Obi.ObiList<Oni.Contact> _contacts = new Obi.ObiList<Oni.Contact>();
    void OnEnable()
    {
        solver.OnParticleCollision += Solver_OnCollision;
    }

    void OnDisable()
    {
        solver.OnParticleCollision -= Solver_OnCollision;
    }

     void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        _contacts = e.contacts;
        if (_contacts != null) Debug.Log("Collision!");
    }


I used this to see if there is any collisions before the ball hits, and there is on every update??? After the ball hits and stays on the rope nothing changes. I get this code block from another forum. The problem is nobody so far wanted to get the collider or gameobject info who's collided to rope so far. That's where I am stuck.

What I want is something like here:

     private void OnCollisionEnter(Collision collision)
    {
        Destroy(collision.gameObject);
    }

Please help.
Reply
#2
Exclamación 
       
I found a problem. 

1)In Solver_OnCollision() method both "for" and "foreach" methods are not working. So I cannot retrieve every contact info one by one to compare if they are actual collision contacts.

2)How did I found out? Simple I both in debugging mode and not in debugging mode the traversing through code is failing. The system directly jumps through end when it sees a for or foreach. Also "There is a contact" text never seen.
At first I thought maybe its a bug because IDE so I closed debugging and added debug.logs. Even after there is nothing.

3)So I just wanted to take the first contact info. When I used _contacts[0].bodyB it shows the collider of collided object which is the thing I wanted at first. So I thought my problem was solved. As you can see it is not. Why simple I can't compare every particles contact info without any loop. 
And much more importantly even if I can do that, the contact info is generated without even a ball or any object touches it. How can I detect objects? The code and ball photo took at the same time.

Please someone help me. I read 10 page of obirope forum and 5 pages of obi general forums, also I readed everything about collisions and basics so far. But it is not working. Huh
Reply
#3
(15-10-2022, 03:43 PM)Ropuska Wrote: I used this to see if there is any collisions before the ball hits, and there is on every update???

Hi!

You've subscribed to an event that is called every frame, providing a list of contacts that happened during that frame. Your original code does nothing with this list except check if it's null. Since it's never null, your Debug.Log will be printed every frame.


(15-10-2022, 03:43 PM)Ropuska Wrote: After the ball hits and stays on the rope nothing changes. I get this code block from another forum. The problem is nobody so far wanted to get the collider or gameobject info who's collided to rope so far.

The manual explains all of this in detail and also includes code snippets for you to use as a basis. These include getting the collider involved in a contact, in a section aptly named "retrieving the collider involved in a contact" Guiño:
http://obi.virtualmethodstudio.com/manua...sions.html

(16-10-2022, 04:09 PM)Ropuska Wrote: I found a problem. 

1)In Solver_OnCollision() method both "for" and "foreach" methods are not working. So I cannot retrieve every contact info one by one to compare if they are actual collision contacts.

If the loops are not executing any iteration that's because the length of the list they're iterating trough is zero. This is probably because you've subscribed to solver.OnParticleCollision instead of solver.OnCollision. OnParticleCollision returns a list of particle-particle contacts, while OnCollision returns particle-collider contacts. Quoting the manual:

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

Quote:Contacts can happen between a simplex and a collider, or between two simplices. To request the simplex-collider contact list from the solver, subscribe to its OnCollision event. To retrieve the simplex-simplex contact list, subscribe to its OnParticleCollision event.



(16-10-2022, 04:09 PM)Ropuska Wrote: 2)How did I found out? Simple I both in debugging mode and not in debugging mode the traversing through code is failing. The system directly jumps through end when it sees a for or foreach. Also "There is a contact" text never seen.
At first I thought maybe its a bug because IDE so I closed debugging and added debug.logs. Even after there is nothing.

As I pointed out above, this is because the amount of elements in the _contacts list is zero. Built-in control structures in a language (such as for loops) don't just randomly break or stop working, and the IDE has absolutely nothing to do with either the compiler or the debugger: it's just a "frontend" for both. So even if the IDE had a bug, that would not change the behavior of your code or alter step-by-step execution in any way.

(16-10-2022, 04:09 PM)Ropuska Wrote: 3)So I just wanted to take the first contact info. When I used _contacts[0].bodyB it shows the collider of collided object which is the thing I wanted at first. So I thought my problem was solved. As you can see it is not.

In a nutshell: Your for loop is working just fine, it's just that the loop will execute zero times since are no contacts to iterate trough, because you've subscribed to inter-particle contacts instead of collider contacts.

(16-10-2022, 04:09 PM)Ropuska Wrote: Why simple I can't compare every particles contact info without any loop. 

There's no way to compare contact info on every particle without looping trough them. In any existing programming language you'd need a loop for this, there's just no way around it. Unity's built-in physics engine also uses a for loop internally to iterate trough all contacts, and then calls OnCollisionEnter() for each collider involved in it. This wouldn't work for a particle-based engine -like Obi- since it typically deals with *a lot* more contacts and it would result in very poor performance. In Obi you have raw access to the contacts list instead, which allows you to even process contacts using multiple threads in parallel if needed.

hope this gets you back on track, let me know if you need further help.

kind regards,
Reply
#4
Sonrisa 
Thank you for your reply, yeah I did saw OnCollision part but looks like I forgot because the example was OnParticleCollision one and I feel dumb. Now it is working Sonrisa
Reply
#5
(17-10-2022, 08:20 AM)Ropuska Wrote: Thank you for your reply, yeah I did saw OnCollision part but looks like I forgot because the example was OnParticleCollision one and I feel dumb. Now it is working Sonrisa

No worries! let me know if you need any help.

kind regards,
Reply
#6
Hi there I have another problem. I have multiple ropes under the same solver when a ball collides with upper rope, the effect applies to the downest rope. And after rope has 0 health(which becomes cut) the same rope still gets the damage. When I have seperate obi solvers this problem does not happen but this will have problme issues. How can I solve this? 
   
   
   

Also there is another problem when I have 2 balls spawned at the same frame, whenever one of the mhits any rope, both ropes got 1 damage and both balls gets despawned even one of them didn't hit any ropes.

   
   
Reply
#7
(17-10-2022, 10:51 AM)Ropuska Wrote: Hi there I have another problem. I have multiple ropes under the same solver when a ball collides with upper rope, the effect applies to the downest rope. And after rope has 0 health(which becomes cut) the same rope still gets the damage. When I have seperate obi solvers this problem does not happen but this will have problme issues. How can I solve this? 
Also there is another problem when I have 2 balls spawned at the same frame, whenever one of the mhits any rope, both ropes got 1 damage and both balls gets despawned even one of them didn't hit any ropes.

Hi!

Could you share the code you're using? I can't help much otherwise... probably you're not using correct particle indices or not checking which actor they belong to.
Reply
#8
(17-10-2022, 11:01 AM)josemendez Wrote: Hi!

Could you share the code you're using? I can't help much otherwise... probably you're not using correct particle indices or not checking which actor they belong to.
Here is the code part that has importance.
//Find and get middle contact point
    //
    void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        _contacts = e.contacts;
        for (int i = 0; i < _contacts.Count; i++)
        {
            var collider = world.colliderHandles[_contacts[i].bodyB].owner;
            if (collider != null && (collider.gameObject.tag == "Ball" || collider.gameObject.tag == "MainBall"))
            {
                //Destroy(collider.gameObject);
                ballPool.Despawn(collider.gameObject);
                if (Health > 0)
                {
                    Health--;
                    if (Health <= 0)
                    {
                        //Tear the rope apart from last position of ball contacted with rope
                        //Or just from center
                        TraverseAndCutRope();
                        Rope.surfaceCollisions = false;
                    }
                    if (TextMesh != null)
                        TextMesh.text = Health.ToString();
                }
                break;
            }
        }
    }

    public void TraverseAndCutRope()
    {
        int count = Rope.elements.Count;
        if(count > 0)
        {
            //Odd number like 1,3,5
            //Can find a center, cut from center
            if(count % 2 == 1)
            {
                int target = count / 2;
                Rope.Tear(Rope.elements[target]);
            }
            //Even number like 2,4,6
            //Doesnt have a center, cut from center +-1
            else
            {
                int target = count / 2;
                Rope.Tear(Rope.elements[target]);
            }
            //Rebuild rope
            Rope.RebuildConstraintsFromElements();
        }
        else
        {
            Debug.Log("No Elements");
            return;
        }
    }
Reply
#9
Your code doesn't check which rope the particles belong to.

As soon as a particle belonging to *any* rope in the solver collides against either Ball or MainBall, you call TraverseAndCutRope(), which tears "Rope". I'm not too sure what "Rope" is but I'd guess it is a ObiRope component in the same object?

Instead of always tearing a specific rope regardless of which rope actually touched the ball, get the rope that the collided particle belongs to and tear that instead. See "Retrieving the actor involved in a contact":
http://obi.virtualmethodstudio.com/manua...sions.html
Reply