Obi Official Forum
Help Obi rope deleteingt cutted part after cut? - Printable Version

+- Obi Official Forum (https://obi.virtualmethodstudio.com/forum)
+-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html)
+--- Forum: Obi Rope (https://obi.virtualmethodstudio.com/forum/forum-4.html)
+--- Thread: Help Obi rope deleteingt cutted part after cut? (/thread-2989.html)



Obi rope deleteingt cutted part after cut? - debruw - 24-06-2021

Hello I am trying to delete cuted part of the rope with particles but it doesnt work. Can anybody help me?


RE: Obi rope deleteingt cutted part after cut? - josemendez - 24-06-2021

(24-06-2021, 03:54 PM)debruw Wrote: Hello I am trying to delete cuted part of the rope with particles but it doesnt work. Can anybody help me?

Hi,

Can you share the code you have so far? Otherwise helping you it’s going to be hard Guiño


RE: Obi rope deleteingt cutted part after cut? - debruw - 24-06-2021

(24-06-2021, 04:19 PM)josemendez Wrote: Hi,

Can you share the code you have so far? Otherwise helping you it’s going to be hard Guiño
Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[particleIndex];

        //solver.colors[particleIndex] = Color.black;

        obiRopes[0].Tear(obiRopes[0].elements[pa.indexInActor + 1]);

        for (int i = pa.indexInActor + 1; i < obiRopes[0].elements.Count; i++)
        {
            obiRopes[0].DeactivateParticle(solver.particleToActor[obiRopes[0].elements[i].particle2].indexInActor);
            obiRopes[0].elements.RemoveAt(i);
        }

        obiRopes[0].RebuildConstraintsFromElements();

        foreach (ObiRopeCursor cr in cursors)
        {
            cr.cursorMu = (float)pa.indexInActor / (float)obiRopes[0].activeParticleCount;
            cr.UpdateCursor();
        }
Here is my code . I am not sure about the for loop


RE: Obi rope deleteingt cutted part after cut? - josemendez - 25-06-2021

(24-06-2021, 04:39 PM)debruw Wrote:
Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[particleIndex];

        //solver.colors[particleIndex] = Color.black;

        obiRopes[0].Tear(obiRopes[0].elements[pa.indexInActor + 1]);

        for (int i = pa.indexInActor + 1; i < obiRopes[0].elements.Count; i++)
        {
            obiRopes[0].DeactivateParticle(solver.particleToActor[obiRopes[0].elements[i].particle2].indexInActor);
            obiRopes[0].elements.RemoveAt(i);
        }

        obiRopes[0].RebuildConstraintsFromElements();

        foreach (ObiRopeCursor cr in cursors)
        {
            cr.cursorMu = (float)pa.indexInActor / (float)obiRopes[0].activeParticleCount;
            cr.UpdateCursor();
        }
Here is my code . I am not sure about the for loop

Hi there!

I don't think I'll be able to post full functioning code today, I will on monday for sure. However at first glance the for loop looks suspicious indeed.
RemoveAt(i) moves all elements in the list at indices larger than "i" one index back, and reduces the list length by one (see: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.removeat?view=net-5.0)

This will cause the for loop to skip over elements. When removing elements while iterating trough an array/list, do it backwards:
Code:
for (int i = obiRopes[0].elements.Count -1; i >= pa.indexInActor + 1, --i)

This will prevent any issues, since all elements shifted when removing one have been already visited by the for loop. It's also more efficient, since the amount of shifting that needs to be done is minimized.

There might be other issues with your code, hold on and I'll post a fully working version asap.


RE: Obi rope deleteingt cutted part after cut? - debruw - 25-06-2021

(25-06-2021, 12:03 PM)josemendez Wrote: There might be other issues with your code, hold on and I'll post a fully working version asap.
 
Thank you so much  Tímido


RE: Obi rope deleteingt cutted part after cut? - josemendez - 28-06-2021

Here's working code to remove part of the rope after a cut. I've subscribed to the rope's OnRopeTorn event, there I remove all elements after the cut.
The only caveat is when iterating trough elements and removing them, you must iterate backwards to avoid skipping over elements.

Code:
using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiRope))]
public class DestroyTorn : MonoBehaviour
{
    void Start()
    {
        GetComponent<ObiRope>().OnRopeTorn += DestroyTeared_OnRopeTorn;
    }

    private void DestroyTeared_OnRopeTorn(ObiRope rope, ObiRope.ObiRopeTornEventArgs tearInfo)
    {
        for (int i = rope.elements.Count-1; i >= 0; --i)
        {
            var elm = rope.elements[i];

            rope.DeactivateParticle(rope.solver.particleToActor[elm.particle2].indexInActor);
            rope.elements.RemoveAt(i);

            if (elm == tearInfo.element)
                break;
        }

        rope.RebuildConstraintsFromElements();
    }

}



RE: Obi rope deleteingt cutted part after cut? - debruw - 28-06-2021

(28-06-2021, 09:35 AM)josemendez Wrote: Here's working code to remove part of the rope after a cut. I've subscribed to the rope's OnRopeTorn event, there I remove all elements after the cut.
The only caveat is when iterating trough elements and removing them, you must iterate backwards to avoid skipping over elements.

Code:
using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiRope))]
public class DestroyTorn : MonoBehaviour
{
    void Start()
    {
        GetComponent<ObiRope>().OnRopeTorn += DestroyTeared_OnRopeTorn;
    }

    private void DestroyTeared_OnRopeTorn(ObiRope rope, ObiRope.ObiRopeTornEventArgs tearInfo)
    {
        for (int i = rope.elements.Count-1; i >= 0; --i)
        {
            var elm = rope.elements[i];

            rope.DeactivateParticle(rope.solver.particleToActor[elm.particle2].indexInActor);
            rope.elements.RemoveAt(i);

            if (elm == tearInfo.element)
                break;
        }

        rope.RebuildConstraintsFromElements();
    }

}
Thank you so much i will be try this as soon as possible