Weird issues regarding Vector3.Lerp and Velocity

Hey everyone;
I need a little bit of help when it comes to 3D physics. I’m trying to write a program that will allow a robot to consistently move forward at a constant speed and direction until otherwise stated, with 3D collision. I think I’ve almost have it figured out, however I don’t know if something is wrong with my code or if Unity just hates me, but I’m getting extremely strange behavior from the robot. Mainly, for example, if I tell the robot to move forward, it will move forward very slowly for a short period of time, and then almost immediately after blast off into the opposite direction. Here’s my code for it:

private void FixedUpdate()
    {
        if (isMovingForward == true)
        {
            rb.transform.position = Vector3.Lerp(rb.position, moveTarget(-1), Time.deltaTime);
            rb.velocity = maxSpeed * (rb.velocity.normalized);
        }
        else if (isMovingBackwards == true)
        {
            rb.transform.position = Vector3.Lerp(rb.position, moveTarget(1),  Time.deltaTime);
            rb.velocity = maxSpeed * (rb.velocity.normalized);
        }
        //Note, rb is my robot gameobject's rigidbody



    }

For the actual attributes on my robot’s rigidbody interpolates collision with “continuous speculative” and its rotation is frozen on the X and Z axis.

I simply want the robot to just move forward/backwards at a constant speed when commanded to. If there’s anything that could help, it’d be great to know.
Thanks!

Try this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour
{
    [SerializeField] public bool isMovingForward = true;
    [SerializeField] public bool isMovingBackwards = false;
    [SerializeField] private float maxSpeed = 10;
    private Rigidbody rb;


    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }


    private void FixedUpdate()
    {
        // For a kinematic rigidbody
        if (isMovingForward == true)
        {
            rb.MovePosition(rb.position + maxSpeed * Time.fixedDeltaTime * transform.forward);
        }
        else if (isMovingBackwards == true)
        {
            rb.MovePosition(rb.position - maxSpeed * Time.fixedDeltaTime * transform.forward);
        }
    }
}

You can’t set velocity for a kinematic rigidbody.

You should not directly set a kinematic rigidbody’s transform position as in doing so you are effectively teleporting it around, breaking the interaction with non-kinematic rigidbodies. To move it whilst avoiding this you should use Rigidbody.MovePosition to move a kinematic rigidbody.

It can be confusing, but the IsKinematic checkbox gives you access to two very different behaviours, that require different control methods.

Wow, thank you so much! Works like a charm!

1 Like