Help me to fix the error

Cannot modify the return value of ‘Rigidbody.velocity’ because it is not a variable
Here is my code(I wrote it following the example of JS):

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

public class PlayerMovementScript : MonoBehaviour
{
    Rigidbody rigidbody;
    public GameObject camera;
    public float walkAcceleration = 5;
    public float maxWalkSpeed = 20;
    float velocityX ;
    float velocityZ ;
    Vector2 horizontalMovement;
   

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

    void Update()
    {
        horizontalMovement = new Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
        if (horizontalMovement.magnitude>maxWalkSpeed)
        {
            horizontalMovement=horizontalMovement.normalized;
            horizontalMovement *= maxWalkSpeed;
        }

        rigidbody.velocity.x = horizontalMovement.x;//error
        rigidbody.velocity.z = horizontalMovement.y;//error

        transform.rotation = Quaternion.Euler(0, camera.GetComponent<MouseLookScript>().currentYRotation, 0);
        rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration, 0, Input.GetAxis("Vertical") * walkAcceleration);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovementScript : MonoBehaviour
{
    Rigidbody rigidbody;
    public GameObject camera;
    public float walkAcceleration = 5;
    public float maxWalkSpeed = 20;
    float velocityX ;
    float velocityZ ;
    Vector2 horizontalMovement;
  

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

    void Update()
    {
        horizontalMovement = new Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
        if (horizontalMovement.magnitude>maxWalkSpeed)
        {
            horizontalMovement=horizontalMovement.normalized;
            horizontalMovement *= maxWalkSpeed;
        }

        rigidbody.velocity = new Vector3(horizontalMovement.x, rigidbody.velocity.y, horizontalMovement.y);

        transform.rotation = Quaternion.Euler(0, camera.GetComponent<MouseLookScript>().currentYRotation, 0);
        rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration, 0, Input.GetAxis("Vertical") * walkAcceleration);
    }
}
1 Like

When you modify rigidbody.velocity, you can’t modify the x/y/z one at a time, you have to assign the whole thing at once using a vector.

The reason for this is a bit subtle. It looks like rigidbody.velocity is a variable, but it’s actually a property. Properties look like variables but are actually functions (one function for getting the value, and another function for setting the value). Behind the scenes, the compiler is replacing
rigidbody.velocity = myVector;
with something like
rigidbody.SetVelocityTo(myVector);

3 Likes

Thank you all! It works)

The reason is even more subtle. Would velocity be regular class, your code would work just fine. But velocity is Vector3, wich is value type. Value types are always copied. So when you write

var velocity = body.velocity;

actually happens

  • call to property get function
  • create copy of Rigidbody’s private velocity variable
  • put that copy into local variable of calling function

sou your code modifies values x,y of a copy of rigidbody valocity, but you have not create local vairable to it so your modification will be lost. that’s why this is error rewrite:

var velocity = rigidbody.velocity;
velocity.x = 1;
velocity.y = 2;
rigidbody.velocity = velocity;

This is how it is intended to work. This code creates local variable, accepts a copy of rigidbody private velocity class field, modifies it, and writes back the modified value.