Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rope ends didn't move correctly
#1
Información 
The end of the rope is attached to a moving object (the movement is not fast), when moving it, there's a always lag between the moving object and the rope's end, how can I achieve a better movement? I tried increasing timesteps and ObiSolver's Substeps but nothing has been changed.
Reply
#2
(19-05-2020, 10:13 PM)Kifwat Wrote: The end of the rope is attached to a moving object (the movement is not fast), when moving it, there's a always lag between the moving object and the rope's end, how can I achieve a better movement? I tried increasing timesteps and ObiSolver's Substeps but nothing has been changed.

It depends on when you move the object relative to the rope (before or after, remember that by default the solver is updated in FixedUpdate(), if you move the object after FixedUpdate there will be a 1-frame delay), and whether the attachment is static or dynamic.
Reply
#3
(20-05-2020, 10:44 AM)josemendez Wrote: It depends on when you move the object relative to the rope (before or after, remember that by default the solver is updated in FixedUpdate(), if you move the object after FixedUpdate there will be a 1-frame delay), and whether the attachment is static or dynamic.

The object is moving with NavmeshAgent movement, and the attachment is static, should I make it dynamic? and what's the difference between static and dynamic?
Reply
#4
(20-05-2020, 12:11 PM)Kifwat Wrote: The object is moving with NavmeshAgent movement, and the attachment is static, should I make it dynamic? and what's the difference between static and dynamic?

Static attachments do not provide two-way interaction. This means the rope will follow whatever object it is attached to, but won't apply forces to it.

Dynamic attachments implement two-way interaction. The rope will follow the object, and also apply forces to it. You could use these to hang objects from a rope, for instance.

Using a NavmeshAgent, a static attachment should be enough if you don't want it to be driven by the rope. In this case, just make sure the agent is moving before the solver is updated each frame.
Reply
#5
(20-05-2020, 12:18 PM)josemendez Wrote: Static attachments do not provide two-way interaction. This means the rope will follow whatever object it is attached to, but won't apply forces to it.

Dynamic attachments implement two-way interaction. The rope will follow the object, and also apply forces to it. You could use these to hang objects from a rope, for instance.

Using a NavmeshAgent, a static attachment should be enough if you don't want it to be driven by the rope. In this case, just make sure the agent is moving before the solver is updated each frame.

Ok I see, but as you know there's no way to move the NavMesh in FixedUpdate, is there any way we can fix this?
Reply
#6
(20-05-2020, 01:21 PM)Kifwat Wrote: Ok I see, but as you know there's no way to move the NavMesh in FixedUpdate, is there any way we can fix this?

Why not? by default its automatically updated in Update(), but nothing stops you from doing it manually anywhere else. Simply turn updatePosition off, then update the transform position yourself. Same for rotation if desired. There's even an example of this in the documentation:
https://docs.unity3d.com/ScriptReference...ition.html

This script works fine for me: it subscribes to the solver's OnBeginStep event (that happens right before each physics step, regardless of where it is taken) and updates the agent there:

Code:
using UnityEngine;
using UnityEngine.AI;
using Obi;

public class NavMeshAgentUpdater : MonoBehaviour
{
   public Transform goal;
   public ObiSolver solver;

   private NavMeshAgent agent;

   private void OnEnable()
   {
       agent = GetComponent<NavMeshAgent>();
       agent.updatePosition = false;
       solver.OnBeginStep += Solver_OnBeginStep;
   }

   private void OnDisable()
   {
       solver.OnBeginStep -= Solver_OnBeginStep;
   }

   // Update is called once per frame
   void Update()
   {
       if (Input.GetKeyDown(KeyCode.Space) && goal != null)
       {
           agent.destination = goal.position;
       }
   }

   private void Solver_OnBeginStep(ObiSolver solver, float stepTime)
   {
       transform.position = agent.nextPosition;
   }
}

Alternatively, you could just update the solver after the agent, by writing your own updater component or using the included LateUpdater component. However keep in mind that using a variable fixed timestep is not ideal. For accuracy using a fixed timestep should be preferred. See:
http://obi.virtualmethodstudio.com/tutor...aters.html
Reply