I know there is a way to condense this block of code can you guys show me how? Thanks

[NOTE: A full rigidbody character controller script has been posted a few posts down. It turned out pretty good for newbs to learn the concept from in my opinion so I posted it]

I know there is a more elegant code to replace this chunk of if() statements below, could one of you guys show me how you would write this to be more condensed and elegant but do the same thing?

rb.velocity-=previous_input_force;

if(rb.velocity.x<0 && previous_input_force.x>0) rb.velocity.x=0;
if(rb.velocity.x>0 && previous_input_force.x<0) rb.velocity.x=0;
if(rb.velocity.y<0 && previous_input_force.y>0) rb.velocity.y=0;
if(rb.velocity.y>0 && previous_input_force.y<0) rb.velocity.y=0;
if(rb.velocity.z<0 && previous_input_force.z>0) rb.velocity.z=0;
if(rb.velocity.z>0 && previous_input_force.z<0) rb.velocity.z=0;

rb.velocity+=newest_input_force;

Optional info: This is just a small block of code in my script for some rigidbody character movement based on player input. I don’t think context matters much but basically this chunk of code just subtracts the input force from the last physics update then “refreshes” or “replaces” it with the newest input force. And those 6 lines of if() statements just make sure that once previous_input_force is subtracted from rb.velocity it does not cause a partial reversal of any axis of rb.velocity.

Thank you for any answers. I feel like I once knew a lot more elegant coding tricks but I’m so rusty I’ve forgotten. It’s been 8 months since I coded anything.

A Vector3 can have its components accessed by index, so you can easily condense it like this for starters:

for (int j=0;j<2;j++) {
if(rb.velocity[j]<0 && previous_input_force[j]>0) rb.velocity[j]=0;
if(rb.velocity[j]>0 && previous_input_force[j]<0) rb.velocity[j]=0;
}

I think we can do one better though, taking advantage of Mathf.Sign:

for (int j=0;j<2;j++) {
if (Mathf.Sign(rb.velocity[j]) != Mathf.Sign(previous_input_force[j]) rb.velocity[j] = 0;
}

(you might also need to check that one of the two numbers is != 0, since Mathf.Sign returns 1 for zero along with positive numbers.)

Beware of excessive code-shrinking in general - sometimes it makes code less readable or less efficient. In this case I think you’re in the clear, though. It’s still pretty clear what’s going on.

Cool thanks, I need to make a little document for myself logging all these tricks that I can’t seem to hold in my head after long breaks. I remember now that not only Vector3 but quite a few other classes are accessible by index.

I maybe dicovered a Unity bug. rigidbody.velocity can not be assigned by index like a normal Vector3.
rigidbody.velocity[0]=5 will compile but will not actually set the x component to 5. It just literally does nothing.

I’m not gonna report it but as a so-called Vector3 it should be able to be assigned by index.

Instead I had to do this:

var v:Vector3=rb.velocity;
v[j]=0;
rb.velocity=v;

no. unless Unity Script, then maybe.

Not a bug, an artefact of the nature of structs in C#.

I’ll post this rigidbody character controller script for scrubs like myself to look at. It turned out to be a simple way to snappily control a rigidbody character without interfering with outside forces. The Standard Assets rigidbody controller and the Wiki’s controller DO interfere with outside forces, they completely block outside forces while WASD is held by the player. Also this script is more straightforward and easy to understand which is better for newbs to learn a concept from it, because I know I sure didn’t understand the standard assets one personally. I understood the one from the Wiki, but it interferes with outside forces, making it useless to me.

var rb:Rigidbody;
var cam:Transform;

var input_force:Vector3;
var previous_input_force:Vector3;

private var h:float;
private var v:float;

private var speed=6f;

function Start(){
    rb=GetComponent(Rigidbody);
    cam=Camera.main.transform;
    }
 
function Update(){
    Record_input();
    }

function FixedUpdate(){
    Update_input_force();
    Apply_velocity();
    }

function Record_input(){
    h=Input.GetAxis("Horizontal");
    v=Input.GetAxis("Vertical");
    }

function Apply_velocity(){

    for(var axis=0; axis<=2; axis++){
        if(Mathf.Abs(previous_input_force[axis]) > Mathf.Abs(rb.velocity[axis])){
            previous_input_force[axis]=rb.velocity[axis];
            }
        }

    rb.velocity-=previous_input_force;
    rb.velocity+=input_force;
    }

function Update_input_force(){
    previous_input_force=input_force;

    //input_force=h*cam.right + v*cam.forward;
    input_force=Vector3(h,0,v);
    input_force=Vector3.ClampMagnitude(input_force, 1);

    input_force*=speed;
    }

Apply_velocity() is the core of the script that demonstrates snappy rigidbody movement without interfering with outside forces.
It is set to move in world space but that doesn’t matter it’s easy to change, the commented out line will let it move relative to the camera, just uncomment it and comment out input_force=Vector3(h,0,v);