Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Collider Effect On Obi Cloth Stops After A Few Seconds.
#1
I'm running into an issue where a collider I create to interact with the obi cloth seems to stop effecting or barely effects the cloth after a few seconds. I was wondering if you guys could possibly shed some light on why this might be. It's not what I expected considering the cloth lays across objects below it.

Here's a video demonstrating what I am describing:

https://drive.google.com/file/d/1Zun775_...sp=sharing

Edit:

Also, is there some place I can find a tutorial or documentation on how to use a ray cast to select particles? I've seen the question multiple times in the archive, and there's pieces of code but after finding substantial differences between the different versions of Obi I don't really think wading through old posts from the archive is feasible because some are from over a year ago. I saw the slime simulation video that's not listed on youtube, it looked like all that happened was the addition of the particle dragger and picker but it doesn't seem to work that way anymore.
Reply
#2
(02-02-2020, 04:19 AM)GrimCaplan Wrote: I'm running into an issue where a collider I create to interact with the obi cloth seems to stop effecting or barely effects the cloth after a few seconds. I was wondering if you guys could possibly shed some light on why this might be. It's not what I expected considering the cloth lays across objects below it.

Here's a video demonstrating what I am describing:

https://drive.google.com/file/d/1Zun775_...sp=sharing

Edit:

Also, is there some place I can find a tutorial or documentation on how to use a ray cast to select particles? I've seen the question multiple times in the archive, and there's pieces of code but after finding substantial differences between the different versions of Obi I don't really think wading through old posts from the archive is feasible because some are from over a year ago. I saw the slime simulation video that's not listed on youtube, it looked like all that happened was the addition of the particle dragger and picker but it doesn't seem to work that way anymore.

Hi,

Without taking a look at your scene setup and any custom script you may have, it's pretty much impossible to tell the cause of this. It could simply be that particles are getting projected outside the reach of the collider in the Z axis after colliding with it a few times (at least that's what it looks like: zones where the collider hasn't passed yet collide fine, but any parts that have already collided with it stop colliding).

You can't use Unity's built-in raycast methods to select particles, as they are not part of Unity's physics system. The particle dragger/picker are what you should use most of the time, all they do is cast a line segment from the mouse cursor position and then select the particle that's closest to it within a user-defined distance. They haven't changed at all since they were added back in 4.X, all you need to do is add them to an actor and drag over a solver to the picker's "Solver" slot. Could you tell me what issues are you having with them?
Reply
#3
(03-02-2020, 08:35 AM)josemendez Wrote: Hi,

Without taking a look at your scene setup and any custom script you may have, it's pretty much impossible to tell the cause of this. It could simply be that particles are getting projected outside the reach of the collider in the Z axis after colliding with it a few times (at least that's what it looks like: zones where the collider hasn't passed yet collide fine, but any parts that have already collided with it stop colliding).

You can't use Unity's built-in raycast methods to select particles, as they are not part of Unity's physics system. The particle dragger/picker are what you should use most of the time, all they do is cast a line segment from the mouse cursor position and then select the particle that's closest to it within a user-defined distance. They haven't changed at all since they were added back in 4.X, all you need to do is add them to an actor and drag over a solver to the picker's "Solver" slot. Could you tell me what issues are you having with them?

The code on the collider is pretty simple. At first I thought it was because the sphere just wasn't touching it because the mesh would deform down but I've tried to use it in 2d mode and I've also changed the collider prefab to an elongated capsule that is tall enough that it's always colliding. I assumed it was due to the lack of collision because I was getting some weird behaviors like the sphere ending up under the mesh even though the mesh is being pushed down and the sphere height is locked. I've confirmed it is running through the mesh and it still produces the same behavior as the sphere. 


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

public class PressureObjectManager : MonoBehaviour
{
    [SerializeField]
    bool m_IndependentDebugging;
    [SerializeField]
    Camera m_TargetCamera;
    [SerializeField]
    private GameObject m_PressureObject;

    public void Awake()
    {
        InputHandler.OnTouch += InputHandler_OnTouch;
    }

    private void InputHandler_OnTouch(InputHandler.TouchEventArgs args)
    {
        HandleTouchByPhase(args);
    }

    private void HandleTouchByPhase(InputHandler.TouchEventArgs args)
    {
        switch(args.Phase)
        {
            case TouchPhase.Began:
                {
                    BeginTouch(args.TouchIndex, args.TouchPosition, args.TouchPressure);
                    break;
                }
            case TouchPhase.Moved:
                {
                    MoveTouch(args.TouchIndex, args.TouchPosition, args.TouchPressure);
                    break;
                }
            case TouchPhase.Ended:
                {
                    EndTouch(args.TouchIndex);
                    break;
                }
            default:
                {
                    Debug.LogWarningFormat("Attempting To Handle Unregistered Touch Phase: {0}", args.Phase);
                    break;
                }
        }
    }

    Dictionary<int, GameObject> m_PressureObjects = new Dictionary<int, GameObject>();

    private void BeginTouch(int index, Vector3 position, double pressure)
    {
        if (m_IndependentDebugging)
            Debug.LogFormat
                ("Touch Began At Position ({0}) With A Pressure Of [{1}] At Index <{2}>", position, pressure, index);

        RaycastHit rayHit;
        if (Physics.Raycast(m_TargetCamera.ScreenPointToRay(position), out rayHit, 25.1f))
        {
            if (m_IndependentDebugging)
                Debug.LogFormat("Screen Touch Position Ray Hit Location: {0}", rayHit.point);

            Vector3 objPosition = rayHit.point;

            objPosition.y = -1;  //Account For Pressure

            if (!m_PressureObjects.ContainsKey(index))
            {
                m_PressureObjects.Add(index, Instantiate(m_PressureObject, objPosition, Quaternion.identity));
            }
        }
    }

    private void MoveTouch(int index, Vector3 position, double pressure)
    {
        if (m_IndependentDebugging)
            Debug.LogFormat
                ("Touch Moved To Position ({0}) With A Pressure Of [{1}] At Index <{2}>", position, pressure, index);

        RaycastHit rayHit;
        if (Physics.Raycast(m_TargetCamera.ScreenPointToRay(position), out rayHit, 25.1f))
        {
            if (m_IndependentDebugging)
                Debug.LogFormat("Screen Touch Position Ray Hit Location: {0}", rayHit.point);

            Vector3 objPosition = rayHit.point;

            objPosition.y = -1;  //Account For Pressure

            if (m_PressureObjects.ContainsKey(index))
            {
                m_PressureObjects[index].transform.position = objPosition;
            }
        }
    }

    private void EndTouch(int index)
    {
        if(m_PressureObjects.ContainsKey(index))
        {
            var o = m_PressureObjects[index];

            m_PressureObjects.Remove(index);

            Destroy(o);
        }
    }
}


As far a the particle dragger and picker, I've just been unable to find many resources on them. I was thinking it would be an alternative route to the colliders if they turn out to not be feasible. So I went looking for some demo code or something like that but the closest I could find to what I was looking for was a video on youtube that demonstrates the picker being used to simulate slime but It does not include the dragger and I think it's from a much earlier version. The dragger and picker work, but I've got some requirements like multi-touch that it the dragger does seem to support. Does it? I'd also like to be able to control what happens when I click and drag and the only way there seems to be to modify the behavior is through the constraints and parameters on the solver and the dragger component but I can't really produce the results I'm looking for with just that so I'm thinking I need to actually interact with the particles themselves. There's also some stuff I found on particle scripting but it doesn't really have demo code on how to select a particle. It more or less seems to iterate through an array of the particles in the solver. Ideally I would like to bridge this gap and be able to use the particle picker (I would guess?) in order to create my own drag, touch, and hold behaviors. I assume I would use the events in the particle picker, but I can't really seem to find documentation, sample code, or video on how to specifically use that component other than the attaching of it in the video. Also the particle dragger does not seem to require the hooking of an event from the editor side. Unless it subscribes to it via code? Having said all that, is it possible to support multi-touch with the particle picker? Is it possible to select multiple particles at a time like the blueprint editor aside from trying to determine what indices the particles around them would be at? If so, could you provide a link to maybe some sample code on the basics of it like unity has for the raycast or write me a quick snippet? I looked everywhere I could think, the only thing I've really found is the documentation generated by the .cs file and that just pretty much lists class members and functions, not so much how to use them.

This is the video: https://www.youtube.com/watch?v=yEYQyiQN...4&index=14

This is the particle scripting doc I mentioned: http://obi.virtualmethodstudio.com/tutor...icles.html

I think in this, you're saying that multi-touch is possible, but I'm not sure.
http://obi.virtualmethodstudio.com/forum...21#pid2121
Reply
#4
Your PressureObjectManager looks ok, although there are a few things that aren't immediately obvious to me. They might not be related to the issue at hand, though:

- Why do you perform a raycast against all colliders in the scene when pressing down? What do you need to raycast against? Wouldn't a simple cast against a plane be enough? (or even no raycast at all, if using a full-screen orthographic view)

Code:
objPosition.y = -1;  //Account For Pressure

- You're lowering the collider one meter in the y axis to account for pressure, when creating the object as well as when the user drags around. So I assume you have some sort of collider above the cloth mesh, that you use to detect touches against using a raycast, and then create a "pressure object" collider one meter below this raycast object, where the cloth is?


Regarding the particle picker, it is a "courtesy" script that keeps track of a single particle and raises picked, held, dragged and released events passing the particle index and position to anyone subscribed to these events. The dragger subscribes to the picker events at runtime, and deals with the physics of the picked particle. This is what the dragger's OnEnable method looks like:

Code:
picker = GetComponent<ObiParticlePicker>();
picker.OnParticlePicked.AddListener(Picker_OnParticleDragged);
picker.OnParticleDragged.AddListener(Picker_OnParticleDragged);
picker.OnParticleReleased.AddListener(Picker_OnParticleReleased);

You can of course subscribe your own scripts to these events in-editor, they're UnityEvents.

The picker is intended to offer basic scaffolding to build more complex systems on top, but it does not take advantage of multitouch. You're expected to use the particle API to move particles around in response to input, just like you'd use Unity's rigid body API to make rigid bodies react to input. After all, Obi is a physics engine, not an input system.

If you take a look at the picker's code you'll see that it reacts on Input.GetMouseButtonDown(0): iterates over all particles calculating their distance to a ray cast from the mouse position, and stores the index of the closest one. Adding multitouch capabilities on top of that involves casting one ray per finger instead of only one, and keeping track of one particle per finger, so it's only a bit more complex.

Quote:I'd also like to be able to control what happens when I click and drag and the only way there seems to be to modify the behavior is through the constraints and parameters on the solver and the dragger component but I can't really produce the results I'm looking for with just that so I'm thinking I need to actually interact with the particles themselves.

Then you'd have to write your own "dragger". The built-in one calculates a spring force and applies it to the particle, it's efficient and reasonably customizable via the spring parameters. But there's tons of other ways to interact with a particle/object: teleport it to a new position? change its velocity directly? apply an impulse? we cannot possibly cover them all.

Quote:Is it possible to select multiple particles at a time like the blueprint editor aside from trying to determine what indices the particles around them would be at? If so, could you provide a link to maybe some sample code on the basics of it like unity has for the raycast or write me a quick snippet?

Just like you don't have built-in object selection in Unity, and you must store a reference to them somewhere, "selecting" a particle is not something built-in in Obi. To select a particle you simply keep track of its index somewhere (in a variable, in an array, etc). Keep in mind that a particle is just an index, just like entities in Unity's ECS system.

The usual approach is to simply iterate through all particles, find the ones you're interested in, and store their index. The manual has several sample scripts that filter out specific particles based on some criteria, and then does something with them. The last sample found in this link fixes all particles within a given distance to a transform:

http://obi.virtualmethodstudio.com/tutor...icles.html
Reply
#5
Thanks for the reply.

The code I gave you was just something I wrote up quickly for prototyping purposes and is in no way what you would consider optimized. That's why the raycast does not discriminate. It's just targeting a plane I have at the same y-level as the mesh. Same for the height of the object, that comment there is actually there to remind me to account for the pressure. Nothing is actually calculated at the moment. The mesh sits at a y-level of zero, I was experimenting with values between -1 and 1, that just happens to be the last value I was testing before I copied it.

I'll go ahead and start working on interacting with particles directly instead of using a collider.

I think I've digested most of what was in your reply. I'll go ahead and dissect the particle picker and go from there.

Thanks again!
Reply