Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Some questions & requests
#11
(08-08-2022, 02:24 PM)josemendez Wrote: If you wanted to get rid of this, you would need to teleport all particles in the rope to a new position and not just the ends (placing them in a straight line from Origin transform to End transform is a good idea). Also set all particle velocities to zero to remove any unwanted velocity from the previous use of the rope.

Hi again!

Ok, I did it and it almost worked 100%!
The attachment, position and motion are now fine, but, for some reason, the end point is sometimes being dettached. Here you can see this:
https://streamable.com/d1ticx

Here's how the code is:

Code:
public void Connect(Transform origin, Transform end)
{
    cursor.ChangeLength((end.position - origin.position).magnitude);
   
    for (var i = 0; i < rope.elements.Count; i++)
    {
        ObiStructuralElement element = rope.elements[i];
        float t = (float)i / (float)rope.elements.Count;
        Vector3 position = Vector3.Lerp(origin.position, end.position, t);
        int particleIndex1 = element.particle1;
        int particleIndex2 = element.particle2;
        rope.solver.positions[particleIndex1] = position;
        rope.solver.positions[particleIndex2] = position;
       
        rope.solver.velocities[particleIndex1] = Vector4.zero;
        rope.solver.velocities[particleIndex2] = Vector4.zero;
    }

    attachment1.enabled = true;
    attachment2.enabled = true;
    attachment1.target = origin;
    attachment2.target = end;
}

public void Disconnect()
{
    attachment1.target = null;
    attachment2.target = null;
    attachment1.enabled = false;
    attachment2.enabled = false;
}

Once again, sorry for bothering you so much but thank you for the amazing support!  Corazón
Reply
#12
(08-08-2022, 02:56 PM)landosilva Wrote: The attachment, position and motion are now fine, but, for some reason, the end point is sometimes being dettached.

When you change the length of a rope using a cursor, particles might be removed from/added to it (for obvious reasons). So existing attachments can go "outside scope" so to speak, referencing particles that no longer exist (or rather, are inactive): because they were removed when reducing the length of the rope, and replaced by other particles when increasing the length again.

There's no guarantee that the particles that were removed when decreasing the length of a rope are added in the exact same order they were removed, since particles are pooled. This is what's causing the end attachment to stop working: after you shorten the rope, the end attachment references a particle that no longer exists.

The way to do this is to update the attachment's particle group to reference the new particle at the end of the rope:

Code:
public void Connect(Transform origin, Transform end)
    {
        cursor.ChangeLength((end.position - origin.position).magnitude);

        for (var i = 0; i < rope.elements.Count; i++)
        {
            ObiStructuralElement element = rope.elements[i];
            float t = i / (float)rope.elements.Count;
            Vector3 position = Vector3.Lerp(origin.position, end.position, t);
            int particleIndex1 = element.particle1;
            int particleIndex2 = element.particle2;
            rope.solver.positions[particleIndex1] = position;
            rope.solver.positions[particleIndex2] = position;

            rope.solver.velocities[particleIndex1] = Vector4.zero;
            rope.solver.velocities[particleIndex2] = Vector4.zero;
        }

        // Update the attachments to reference whichever particles are now at the ends of the rope, after changing its length:
        int firstParticle = rope.elements[0].particle1;
        int lastParticle = rope.elements[rope.elements.Count - 1].particle2;
        attachment1.particleGroup.particleIndices[0] = rope.solver.particleToActor[firstParticle].indexInActor;
        attachment2.particleGroup.particleIndices[0] = rope.solver.particleToActor[lastParticle].indexInActor;

        attachment1.target = origin;
        attachment2.target = end;
        attachment1.enabled = true;
        attachment2.enabled = true;
    }

Note that depending on where you place the cursor and which side of the rope it is facing, both the end and start attachments might be affected (since the rope can also grow/shrink from the start), so it's safer to update both attachments. This prevents issues if you later flip the cursor to face the start of the rope instead.

kind regards,
Reply
#13
(08-08-2022, 03:21 PM)josemendez Wrote: The way to do this is to update the attachment's particle group to reference the new particle at the end of the rope:

Now everything is working 100%! Gran sonrisa 
Thank you very much!  Corazón
Reply
#14
(08-08-2022, 03:44 PM)landosilva Wrote: Now everything is working 100%! Gran sonrisa 
Thank you very much!  Corazón

You're welcome! Sonrisa
Reply
#15
Hey Jose! It's me again! ^^'

I'm now trying to simply detach the rope but I'm having some problems.

If I call Disconnect() from the example the rope is not being detached at all. Both attachments are disabled and with their targets null but they are still behaving like it was attached. 

Code:
public void Disconnect()
{
    _attachment1.target = null;
    _attachment2.target = null;
    _attachment1.enabled = false;
    _attachment2.enabled = false;
}

Also, if I call Despawn (setting the rope's object to false) in a OnTriggerEnter event, and I'm getting this error:


Quote:Destroying GameObjects immediately is not permitted during physics trigger/contact, animation event callbacks, rendering callbacks or OnValidate. You must use Destroy instead.
UnityEngine.ObjectGran sonrisaestroyImmediate (UnityEngine.Object)
Obi.BurstColliderWorldGran sonrisaecreaseReferenceCount () (at Assets/Plugins/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderWorld.cs:61)


Well, basically the question is: how can I detach the rope?

Thank you!
Reply
#16
(09-08-2022, 04:51 PM)landosilva Wrote: Hey Jose! It's me again! ^^'

I'm now trying to simply detach the rope but I'm having some problems.

If I call Disconnect() from the example the rope is not being detached at all. Both attachments are disabled and with their targets null but they are still behaving like it was attached. 

Code:
public void Disconnect()
{
    _attachment1.target = null;
    _attachment2.target = null;
    _attachment1.enabled = false;
    _attachment2.enabled = false;
}

First disable the attachment, then you may set its target to null. Otherwise you're pulling the rug from under the attachment's feet, so to speak, as it loses the reference to the target and can no longer disable the underlying constraint. Note this is a special case, when you set the target to a different object, the attachment will swap targets.

(09-08-2022, 04:51 PM)landosilva Wrote: Also, if I call Despawn (setting the rope's object to false) in a OnTriggerEnter event, and I'm getting this error:

Removing the last rope from the last solver in the scene will destroy the BurstColliderWorld object in the scene, as it's no longer used. This is an object that keeps track of colliders/rigidbodies in the scene and syncs them with Obi. It must be destroyed using DestroyImmediate() as it must exist in-editor, but it cannot be immediately destroyed during a contact callback since that would remove objects mid-simulation. I would recommend enabling a flag variable during collision, then destroy the rope in Update().

kind regards,
Reply
#17
(10-08-2022, 07:18 AM)josemendez Wrote: First disable the attachment, then you may set its target to null. Otherwise you're pulling the rug from under the attachment's feet, so to speak, as it loses the reference to the target and can no longer disable the underlying constraint. Note this is a special case, when you set the target to a different object, the attachment will swap targets.

Yes, it worked! Thank you!
I feel like all these questions I'm asking should be somewhere in the examples/documentation, since it doesn't have many scripts examples. Seems like something pretty basic to do with ropes (attach, detach, change targets) and yet I'm struggling. Maybe I'm just dumb. ^^'


(10-08-2022, 07:18 AM)josemendez Wrote: Removing the last rope from the last solver in the scene will destroy the BurstColliderWorld object in the scene, as it's no longer used. This is an object that keeps track of colliders/rigidbodies in the scene and syncs them with Obi. It must be destroyed using DestroyImmediate() as it must exist in-editor, but it cannot be immediately destroyed during a contact callback since that would remove objects mid-simulation. I would recommend enabling a flag variable during collision, then destroy the rope in Update().


I will do something like this then. Thanks!
Reply
#18
(10-08-2022, 10:03 AM)landosilva Wrote: Yes, it worked! Thank you!
I feel like all these questions I'm asking should be somewhere in the examples/documentation, since it doesn't have many scripts examples. Seems like something pretty basic to do with ropes (attach, detach, change targets) and yet I'm struggling.

Sure, I will add a "scripting attachments" section to the manual, covering these use cases. Thanks!
Reply
#19
Just added a new page in the manual:

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

Any feedback is most welcome!
Reply