0
\$\begingroup\$

I made touch controls, but when I set forward movement, the control stops working.

[SerializeField]
Rigidbody _rigidbody;

float? _lastX = null;

void FixedUpdate()
{
    // Vector3.right = new Vector(1f, 0f, 0f)
    // the control does not work because of this line
    _rigidbody.MovePosition(_rigidbody.position + Vector3.right * 3f * Time.fixedDeltaTime);
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        _lastX = Input.mousePosition.x;
    }
    else if (_lastX != null && Input.GetMouseButton(0))
    {
        var pos = _rigidbody.position;
        var x = Input.mousePosition.x;
        pos.z += -((x - (float)_lastX) / Screen.width * 12f);
        pos.z = Mathf.Clamp(pos.z, -2.6f, 2.6f);
        _rigidbody.MovePosition(pos);
        _lastX = x;
    }
    else if (Input.GetMouseButtonUp(0))
    {
        _lastX = null;
    }
}

How can you solve this?

thanks for help

\$\endgroup\$
1
  • 1
    \$\begingroup\$ MovePosition is an instruction about where you want the Rigidbody to move to on the next physics step. If just before that step happens, in FixedUpdate, you say "wait no, I changed my mind, move here instead" then the Rigidbody obeys your command and moves to the new location, not the place you told it to go in Update. Have you tried using a variable to store your desired position instead of calculating it from the body's old position each time, or moving your MovePosition code from Update so all the physics interaction happens in FixedUpdate? \$\endgroup\$ – DMGregory Jun 6 at 11:22
0
\$\begingroup\$
[SerializeField]
Rigidbody _rigidbody;

float? _lastX = null;

float _p = 0f;

void FixedUpdate()
{
    var pos = _rigidbody.position;
    pos.x += 3f * Time.fixedDeltaTime;
    pos.z = _p;
    _rigidbody.MovePosition(pos);
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        _lastX = Input.mousePosition.x;
    }
    else if (_lastX != null && Input.GetMouseButton(0))
    {
        var pos = _rigidbody.position.z;
        var x = Input.mousePosition.x;
        pos += -((x - (float)_lastX) / Screen.width * 160f * Time.deltaTime);
        pos = Mathf.Clamp(pos, -2f, 2f);
        //_rigidbody.MovePosition(pos);
        _p = pos;
        _lastX = x;
    }
    else if (Input.GetMouseButtonUp(0))
    {
        _lastX = null;
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Inputs always needd to happen in Update(), NOT FixedUpdate(), that's normal for Unity. \$\endgroup\$ – Engineer Jun 7 at 12:26
  • 1
    \$\begingroup\$ What Engineer says is generally correct for instantaneous inputs like button presses/releases. Continuous inputs like the held position of an analog stick are safe to handle in FixedUpdate - the Input system caches them from the previous frame as required so you don't need to duplicate that in Update. And using the new input system, you can configure it to track instantaneous inputs in FixedUpdate instead. So, I'd be cautious of "inputs always need to happen in Update not FixedUpdate" as a blanket rule. There are reasons it's a mantra, but there are also cases where it does not apply. \$\endgroup\$ – DMGregory Jun 7 at 13:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.