简体   繁体   中英

Clamp magnitude not working on RigidBody.Velocity

I am using c# mono and unity3d 4.1.2.

I have the following script:

using UnityEngine;
using System.Collections;

public class PlayerMove : MonoBehaviour 
{
public float MoveSpeed = 10.0f;
public float maxVel = 0.000000001f;
// Use this for initialization
void Start () 
{

}

void FixedUpdate()
{
    if(Input.GetKey(KeyCode.D))
    {
        Debug.Log("D got called");
        rigidbody.AddForce(Vector3.right * MoveSpeed);
    }
    
    if(Input.GetKey(KeyCode.A))
    {
        Debug.Log("A got called");
        rigidbody.AddForce(Vector3.left * MoveSpeed);
    }
    
    rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxVel);
    Debug.Log (rigidbody.velocity.x);
}
// Update is called once per frame
void Update () 
{
    
}
}

As you can probably tell, it is a simple player move script. I have a Rigidbody attached to a sphere, and I wish to move it left and right along the x axis via "AddForce".

Works nicely all but one problem, I tried to implement a max velocity on the rigid body using "clampMagnitude" but it apears to do nothing at all. I've even set the "maxVel" value to 0.000000001! to see if anything would happen.

Clearly I'm missing something here, can anyone point out the problem?

Additional info:

Rigid-body is not kinematic, but does use gravity (it is a feature I plan to change in the future, but is irrelevant).

Debug Info

if(Input.GetKey(KeyCode.D))
{
rigidbody.AddForce(Vector3.right * MoveSpeed);
Debug.Log("BEFORE = " + rigidbody.velocity.magnitude);
}
    
if(Input.GetKey(KeyCode.A))
{
rigidbody.AddForce(Vector3.left * MoveSpeed);
}
    
rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxVel);
Debug.Log("AFTER = " + rigidbody.velocity.magnitude);

Reuslt snapshot on D, before = 12.1911 after = 12.1911 after = 12.38866 after = 12.50772

UPDATE: (answer)

Thanks to some help from Mr Blue it seems the issue was the variable maxVel, as it was public it seems to be getting changed in my inspector, set to private and checked entering on the fixed update has done the trick. So this script works now, giving user 2d control on the X axis of a rigid-body, hope you guys find this post useful! Note to Self = Rigid-Bodys = headaches!

Your default on your maxVel is probably set to a different value in the Unity inspector for that object. You can reset the component and it will return to the defaults that you have set in your script.

To prevent this in the future my personal preference is to make it private in your script until you are ready to start setting options solely in the Inspector. This ensures that the changes you create in MonoDevelop are the ones you expect to take effect until you are ready to round off that component as complete and customisable in the Inspector.

I keep track of those variables by using simple comments with TODO: and noting how to make them adjustable

private float MoveSpeed = 10.0f;     //TODO: Make MoveSpeed inspector adjustable (possibly slider control)
private float maxVel = 0.000000001f; //TODO: Make maxVel inspector adjustable

I think the problem is the following: FixedUpdate method is called just before the physics engine update.

So trying to clamping the velocity has no effect because the force you are applying to the RigidBody will be applied after the clamp. The only effect you'll get this way is reducing the actual velocity before the new force is applied. This is a guess because I'm not so familiar with physics in Unity3D, but I think you can clamp it just after the physics engine update if you use WaitForFixedUpdate .

Another, probably unrelated problem with your code, is that you are getting the input inside a FixedUpdate . You shouldn't do this: keep input handling inside Update and apply forces inside FixedUpdate .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM