Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  When the Obi Rope is tensioned
#1
I'm testing with two ropes in singles to get ObiRope's ropes to match in multiplayer. Sending and receiving position and rotation values worked, but when the rope is attached somewhere with an Obi Particle Attachment and the player grabs and pulls the rope giving the value, the other rope receiving the value bounces around a lot. (Likewise, if I pull the rope with both hands to create tension, the rope that receives the value bounces quickly.) How can I make other ropes move the same as the rope that is stretched under tension? I am not familiar with English, so the writing may be strange. sorry.
Reply
#2
(06-07-2023, 08:45 AM)EunBhin Park Wrote: I'm testing with two ropes in singles to get ObiRope's ropes to match in multiplayer. Sending and receiving position and rotation values worked, but when the rope is attached somewhere with an Obi Particle Attachment and the player grabs and pulls the rope giving the value, the other rope receiving the value bounces around a lot. (Likewise, if I pull the rope with both hands to create tension, the rope that receives the value bounces quickly.) How can I make other ropes move the same as the rope that is stretched under tension? I am not familiar with English, so the writing may be strange. sorry.

Hi,

Can't help much without any information about how you're sending and applying particle positions/rotations. As long as they're identical to the ones sent from the simulation, its stands to reason that the receiving end should look and behave the same.

kind regards,
Reply
#3
(06-07-2023, 10:03 AM)호세멘데즈 Wrote: 안녕하세요,

입자 위치/회전을 보내고 적용하는 방법에 대한 정보 없이는 많은 도움을 드릴 수 없습니다. 시뮬레이션에서 보낸 것과 동일한 한 수신 측이 동일하게 보이고 동작해야 한다고 추론할 수 있습니다.

친절한 안부,


for (int i = 0; i < actor.solverIndices.Length; ++i)

        {
rope.solver.externalForces[actor.solverIndices[i]] = otherRope.solver.externalForces[actor.solverIndices[i]];
rope.solver.externalTorques[actor.solverIndices[i]] = otherRope.solver.externalTorques[actor.solverIndices[i]];

rope.solver.positions[actor.solverIndices[i]] = otherRope.solver.positions[actor.solverIndices[i]];
rope.solver.velocities[actor.solverIndices[i]] = otherRope.solver.velocities[actor.solverIndices[i]];

        }


In this way, the position and rotation values are passed.

The 'otherRope' is the rope that gives the value, and the 'rope' is the rope that receives the value.

Even if i pass an External Forces and an External Torques, when tension is applied, the rope that receives the value does not move the same as the rope that gives the value.
Reply
#4
(06-07-2023, 10:16 AM)EunBhin Park Wrote: for (int i = 0; i < actor.solverIndices.Length; ++i)

        {
            rope.solver.externalForces[actor.solverIndices] = otherRope.solver.externalForces[actor.solverIndices[i]];
            rope.solver.externalTorques[actor.solverIndices[i]] = otherRope.solver.externalTorques[actor.solverIndices[i]];

            rope.solver.positions[actor.solverIndices[i]] = otherRope.solver.positions[actor.solverIndices[i]];
            rope.solver.velocities[actor.solverIndices[i]] = otherRope.solver.velocities[actor.solverIndices[i]];

        }


In this way, the position and rotation values are passed.

The 'otherRope' is the rope that gives the value, and the 'rope' is the rope that receives the value.

Ok, where during the update cycle are you doing this? Update, FixedUpdate, one of the solver callbacks...? You'd typically want to set these values in the solver's OnEndStep callback. Copying them at any other time may lead to the solver modifying these positions as part of its normal simulation cycle. The idea is that you want both solvers to have finished a simulation step, and copy their particle values before rendering takes place.

Also, make sure to copy previousPositions array and startPositions arrays. These are used to derive velocities and perform interpolation, respectively.

(06-07-2023, 10:16 AM)EunBhin Park Wrote: Even if i pass an External Forces and an External Torques, when tension is applied, the rope that receives the value does not move the same as the rope that gives the value.

Unless you're explicitly writing custom data in ExternalForces and ExternalTorques, these values will [i]always be zero. As the name implies, they're "external" to the simulation.
Reply
#5
(06-07-2023, 10:25 AM)josemendez Wrote: Ok, where during the update cycle are you doing this? Update, FixedUpdate, one of the solver callbacks...? You'd typically want to set these values in the solver's OnEndStep callback. Copying them at any other time may lead to the solver modifying these positions as part of its normal simulation cycle. The idea is that you want both solvers to have finished a simulation step, and copy their particle values before rendering takes place.

Also, make sure to copy previousPositions array and startPositions arrays. These are used to derive velocities and perform interpolation, respectively.


Unless you're explicitly writing custom data in ExternalForces and ExternalTorques, these values will always be zero. As the name implies, they're "external" to the simulation.

The source code is contained in a coroutine. It is initially called from Start() and repeats every 0.1 seconds using recursion.

private void Start()
    {
        if (isReceive)
        {
            StartCoroutine(Co_WaitUpdate());
        }
    }

private IEnumerator Co_WaitUpdate()
    {
        yield return new WaitForSeconds(0.1f);
        for (int i = 0; i < actor.solverIndices.Length; ++i)
        {
            rope.solver.positions[actor.solverIndices[i]] = otherRope.solver.positions[actor.solverIndices[i]];
            rope.solver.velocities[actor.solverIndices[i]] = otherRope.solver.velocities[actor.solverIndices[i]];
        }
        StartCoroutine(Co_WaitUpdate());
    }
Reply
#6
(06-07-2023, 10:31 AM)EunBhin Park Wrote: The source code is contained in a coroutine. It is initially called from Start() and repeats every 0.1 seconds using recursion.

private void Start()
    {
        if (isReceive)
        {
            StartCoroutine(Co_WaitUpdate());
        }
    }

private IEnumerator Co_WaitUpdate()
    {
        yield return new WaitForSeconds(0.1f);
        for (int i = 0; i < actor.solverIndices.Length; ++i)
        {
            rope.solver.positions[actor.solverIndices[i]] = otherRope.solver.positions[actor.solverIndices[i]];
            rope.solver.velocities[actor.solverIndices[i]] = otherRope.solver.velocities[actor.solverIndices[i]];
        }
        StartCoroutine(Co_WaitUpdate());
    }

Updating every 0.1 seconds without any regard for the physics timestep won't work. Moreover, coroutines are updated outside the normal physics loop in Unity.

Use the solver's callbacks to do this, as suggested.

kind regards,
Reply
#7
(06-07-2023, 11:50 AM)josemendez Wrote: Updating every 0.1 seconds without any regard for the physics timestep won't work. Moreover, coroutines are updated outside the normal physics loop in Unity.

Use the solver's callbacks to do this, as suggested.

kind regards,


Using the solver's OnEndStep callback, it works perfectly like magic. thanks for your help! Sonrisa
Reply
#8
(07-07-2023, 01:29 AM)EunBhin Park Wrote: Using the solver's OnEndStep callback, it works perfectly like magic. thanks for your help! Sonrisa
Can you share the code, i have the same problem Triste
Reply