Posts: 4
Threads: 1
Joined: Dec 2022
Reputation:
0
06-07-2023, 08:45 AM
(This post was last modified: 06-07-2023, 09:37 AM by EunBhin Park.)
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.
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(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,
Posts: 4
Threads: 1
Joined: Dec 2022
Reputation:
0
06-07-2023, 10:16 AM
(This post was last modified: 06-07-2023, 10:20 AM by EunBhin Park.)
(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.
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
06-07-2023, 10:25 AM
(This post was last modified: 06-07-2023, 10:27 AM by josemendez.)
(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.
Posts: 4
Threads: 1
Joined: Dec 2022
Reputation:
0
(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());
}
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
06-07-2023, 11:50 AM
(This post was last modified: 06-07-2023, 11:51 AM by josemendez.)
(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,
Posts: 4
Threads: 1
Joined: Dec 2022
Reputation:
0
(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!
Posts: 6
Threads: 2
Joined: Sep 2023
Reputation:
0
(07-07-2023, 01:29 AM)EunBhin Park Wrote: Using the solver's OnEndStep callback, it works perfectly like magic. thanks for your help! Can you share the code, i have the same problem
|