Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Two Quick Beginner Questions
#1
Hi,

two quick questions:

1. How do you manage that your softbodies collide with each other?
I saw that you can click on Edit Particles, then select "Phase", type in a unique number and click on the "Fill all" icon.
But my objects still don't collide. Also, I think this procedure is a bit tedious. I suppose the workflow is to do it by code?

2. I have a trash bag that was turned into a softbody. When my player collides with the softbody he just walks over it (looks awesome though).
I want the player to kick the trashbag in his walking direction when colliding with it. I thought that the script at the end of this site would be perfect for that:
http://obi.virtualmethodstudio.com/tutor...sions.html

My problem is that I dont find a reference to anything I could use force on, when I reach the point:

Code:
           // this one is an actual collision:
           if (contact.distance < 0.01)
           {
               Component collider;
               if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
               {
                   // do something with the collider.
                   //contact.
               }
           }

I know that I can compute all the needed values by checking the collider rigidbody and transform, but what I am looking for is something like:
contact.softbody.addForce();

I hope you understand my issue.

Best regards, and thanks again for the awesome support.
Reply
#2
(05-08-2019, 01:53 PM)HenryChinaski Wrote: Hi,

two quick questions:

1. How do you manage that your softbodies collide with each other?
I saw that you can click on Edit Particles, then select "Phase", type in a unique number and click on the "Fill all" icon.
But my objects still don't collide. Also, I think this procedure is a bit tedious. I suppose the workflow is to do it by code?

2. I have a trash bag that was turned into a softbody. When my player collides with the softbody he just walks over it (looks awesome though).
I want the player to kick the trashbag in his walking direction when colliding with it. I thought that the script at the end of this site would be perfect for that:
http://obi.virtualmethodstudio.com/tutor...sions.html

My problem is that I dont find a reference to anything I could use force on, when I reach the point:

Code:
           // this one is an actual collision:
           if (contact.distance < 0.01)
           {
               Component collider;
               if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
               {
                   // do something with the collider.
                   //contact.
               }
           }

I know that I can compute all the needed values by checking the collider rigidbody and transform, but what I am looking for is something like:
contact.softbody.addForce();

I hope you understand my issue.

Best regards, and thanks again for the awesome support.

Hi,

1.- Make sure the solver has Particle Collisions enabled, then set your softbody particle phases to a different value using the particle editor: click on "select all", then set the phase value you want.

Also, make sure your particle sampling density is high enough so that there are no huge holes in the softbody representation. You can increase the particle overlap setting when initializing the softbody, so that particles can overlap a bit, closing any gaps. See:
http://obi.virtualmethodstudio.com/tutor...setup.html


2.- Use solver.externalForces[contact.particle] = <your force here>.

kind regards,
Reply
#3
Hi, 

thanks for the explanation but - unfortunately - adding force to the SoftBody when the player collides with it still doesn't work for me. 
Here is my complete code that I assigned as a component to the same GameObject as the Obi Solver. Am I missing something?

Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Obi;

[RequireComponent(typeof(ObiSolver))]
public class SoftBody_Physics : MonoBehaviour
{

   Obi.ObiSolver Solver;

   Obi.ObiSolver.ObiCollisionEventArgs collisionEvent;

   void Awake()
   {
       Solver = GetComponent<Obi.ObiSolver>();
   }

   void OnEnable()
   {
       Solver.OnCollision += Solver_OnCollision;
   }

   void OnDisable()
   {
       Solver.OnCollision -= Solver_OnCollision;
   }

   void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
   {
       foreach (Oni.Contact contact in e.contacts)
       {
           // this one is an actual collision:
           if (contact.distance < 0.01)
           {
               Component collider;
               if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
               {
                   if (!collider.transform.root.gameObject.CompareTag("Player")) return;

                   Vector3 direction = transform.position - collider.transform.position;
                   direction.Normalize();

                   Solver.externalForces[contact.particle] = new Vector4(0, 1, 0, 1000f);//new Vector4(direction.x, direction.y, direction.z, 1000f);
               }
           }
       }
   }

}
Reply
#4
Ok, I found the error. It is just that I thought that collider.transform.gameObject.tag would reference the tag of the gameObject that 
hit the SoftBody, but it references the SoftBody itself. So is it not possible to get the ObiCollider that collided with a SoftBody?
I see no other way to make the SoftBodies really interactable.

I also want to buy Obi Ropes and Cloth as soon as possible, because overall this is an amazing asset. Still, even the best assets need some
explanation to the user.

Best regards,
Daniel
Reply
#5
(19-08-2019, 09:15 PM)HenryChinaski Wrote: Ok, I found the error. It is just that I thought that collider.transform.gameObject.tag would reference the tag of the gameObject that 
hit the SoftBody, but it references the SoftBody itself. So is it not possible to get the ObiCollider that collided with a SoftBody?
I see no other way to make the SoftBodies really interactable.

I also want to buy Obi Ropes and Cloth as soon as possible, because overall this is an amazing asset. Still, even the best assets need some
explanation to the user.

Best regards,
Daniel

Hi Daniel,

To get the ObiCollider that hit a soft body, simply use the idToCollider map, as in the docs (see "Retrieving the collider involved in a contact"):
http://obi.virtualmethodstudio.com/tutor...sions.html

then just use GetComponent<ObiCollider>() on the Collider.

Anyway your code seems fine to me. The tag returned by collider.transform.root.gameObject is the one at the collider's root transform, so if you compare it to "Player" it should return whether the collider root is a player or not. Note this is standard Unity behavior and not dependant on Obi in any way.
Reply
#6
Thanks for the reply.
I tried your suggestions but I am very sorry that I still have problems getting the player collider. 

Code:
   void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
   {
       foreach (Oni.Contact contact in e.contacts)
       {
           // this one is an actual collision:
           if (contact.distance < 0.01)
           {
               Component collider;
               if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
               {
                   Collider ContactCollider = ObiCollider.idToCollider[contact.other] as Collider;

                   Debug.Log(ContactCollider.transform.gameObject.name);
               }
           }
       }
   }

There is a debug log message whenever the softbody touches the ground, but there is no debug log message when the player touches the softbody.

The player has a capsule collider, a rigidbody, an obi collider and an obi rigidbody.
Reply
#7
(20-08-2019, 04:51 PM)HenryChinaski Wrote: Thanks for the reply.
I tried your suggestions but I am very sorry that I still have problems getting the player collider. 

Code:
   void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
   {
       foreach (Oni.Contact contact in e.contacts)
       {
           // this one is an actual collision:
           if (contact.distance < 0.01)
           {
               Component collider;
               if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
               {
                   Collider ContactCollider = ObiCollider.idToCollider[contact.other] as Collider;

                   Debug.Log(ContactCollider.transform.gameObject.name);
               }
           }
       }
   }

There is a debug log message whenever the softbody touches the ground, but there is no debug log message when the player touches the softbody.

The player has a capsule collider, a rigidbody, an obi collider and an obi rigidbody.

Make sure the player collider's phase is different than that of the softbody particles. Other than that, there's no reason for it to work with one collider but not with the other. I'd need to take a deep look at your setup to figure out the problem.

Also, this line is redundant:
Code:
Collider ContactCollider = ObiCollider.idToCollider[contact.other] as Collider;

You're already retrieving the collider in
Code:
ObiCollider.idToCollider.TryGetValue(contact.other, out collider)

So why accessing the map two times per contact? double performance hit for no reason. Just get rid of the second lookup.
Reply
#8
Works perfectly now. 
Fortunately it was just a user error, since I left a "!" in front of a condition.

Thanks for your time and I hope Obi Ropes will be implemented in our project without user misfunctions! 

Best regards,
Daniel
Reply