Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Obi rope deleteingt cutted part after cut?
#1
Pregunta 
Hello I am trying to delete cuted part of the rope with particles but it doesnt work. Can anybody help me?
Reply
#2
(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
Reply
#3
(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
Reply
#4
(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/...ew=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.
Reply
#5
(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
Reply
#6
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();
    }

}
Reply
#7
(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
Reply