Is it possible to recreate Half-Life 2 FPS controller?

As in topic. I need very good fps controller (very good = controller which feels good, not sensitive and responsive), and HL2 controller feels so good for me, so I decided to recreate it, but I don’t know where to start. Now I have simple FPS controller with rigidbody but it’s too unresponsive :confused:

1 Like

That question is extremely vague. If you post a particular portion of your setup/code, explain what is happening and what you would prefer to see happening, people might be able to offer some insight/suggestions :slight_smile:

@methos5k
My code is:

using UnityEngine;
using System.Collections;

public class Move : MonoBehaviour {
   
    public float maxSpeed = 10;
    public float force = 6;
    public float jumpSpeed = 5;
    public Rigidbody rigidbody;

    int state = 0;
    bool grounded = false;
    float jumpLimit = 0;

    void Awake () { 
        rigidbody.freezeRotation = true;
    }
    void OnCollisionEnter () {
        state ++;
        if(state > 0) {
            grounded = true;
        }
    }
    void OnCollisionExit () {
        state --;
        if(state < 1) {
            grounded = false;
            state = 0;
        }
    }
    public virtual bool jump {
        get {
            return Input.GetButtonDown ("Jump");
        }
    }

    public virtual float horizontal {
        get    {
            return Input.GetAxis("Horizontal") * force;
        } 
    } 
    public virtual float vertical {
        get    {
            return Input.GetAxis("Vertical") * force;
        } 
    }

    void FixedUpdate () {
        if(rigidbody.velocity.magnitude < maxSpeed && grounded == true) {
            rigidbody.AddForce (transform.rotation * Vector3.forward * vertical);
            rigidbody.AddForce (transform.rotation * Vector3.right * horizontal);
        }

        if(jumpLimit < 10) jumpLimit ++;

        if(jump && grounded  && jumpLimit >= 10) {
            rigidbody.velocity = rigidbody.velocity + (Vector3.up * jumpSpeed);
            jumpLimit = 0;
        }
    }
}

And I have capsule with rigidbody and camera (I am using camera for my mouse look script). The moves are not smooth, I need to hold movement buttons for a while to see any movement, but if I’m moving, it’s hard to stop it. It’s very unresponsive, so I can’t use it :confused: I can give you entire project if needed. I appreciate any help :wink:

Okay, just a quick observation… I don’t often see people trying to add force for general movement (jumping it’s common to see that).
You ever try having the input set a velocity directly instead?

@methos5k
I’m new in Unity, i haven’t played with rigidbodies too much, so I don’t know how to do that. Replace force with velocity? Or what?

Yes, for general movement … velocity. Just set it to what you want and it should be good. at least try it and see what you think … and if it’s any better/what you’re looking for.

@methos5k
I did changed rigidbody.addForce to rigidbody.velocity and it’s much better, but now I cant move forward and backward, can you help me with this too? My code now looks like this:

using UnityEngine;
using System.Collections;

public class Move : MonoBehaviour {
   
    public float maxSpeed  = 7;
    public float force     = 3;
    public float jumpSpeed = 4;
    public Rigidbody rigidbody;

    private int state = 0;
    private bool grounded = false;
    private float jumpLimit = 0;

    void Awake () { 
        rigidbody.freezeRotation = true;
    }
    void OnCollisionEnter () {
        state ++;
        if(state > 0) {
            grounded = true;
        }
    }
    void OnCollisionExit () {
        state --;
        if(state < 1) {
            grounded = false;
            state = 0;
        }
    }
    public virtual bool jump {
        get {
            return Input.GetButtonDown ("Jump");
        }
    }

    public virtual float horizontal {
        get    {
            return Input.GetAxis("Horizontal") * force;
        } 
    } 
    public virtual float vertical {
        get    {
            return Input.GetAxis("Vertical") * force;
        } 
    }

    void FixedUpdate () {
        if(rigidbody.velocity.magnitude < maxSpeed && grounded == true) {
            rigidbody.velocity = (transform.rotation * Vector3.forward * vertical);
            rigidbody.velocity = (transform.rotation * Vector3.right * horizontal);
        }

        if(jumpLimit < 10) jumpLimit ++;

        if(jump && grounded  && jumpLimit >= 10) {
            rigidbody.velocity = rigidbody.velocity + (Vector3.up * jumpSpeed);
            jumpLimit = 0;
        }
    }
}

k, well i’m fairly certain that you have no need for the rotation to be part of the velocity, eh?
I would just remove that…
secondly, you don’t want to set velocity twice, right?
I mean the first time… you’re saying : my velocity is ( … this calculation here)
then , you’re saying : “Now, use this instead.” It just overwrites it.

// this is a bit oddly worded, as vertical to me usually means "up" but in this case it's "in/out" depth..anyways. I think this is right.
rigidbody.velocity = new Vector3(horizontal, 0, vertical);

I think that’s what you want. I haven’t tested it but please try it and let me know :slight_smile:

PS. I’m glad it’s better at least , minus the problem listed lol

@methos5k
Thanks, It’s working that, how I did excepted :smile: But I have few more questions, can I have any private contact (skype, facebook, steam or just email)?

Very cool. I’m glad that it’s working. We can chat a bit, within reason :slight_smile:

You ever get this figured out? I’ve been struggling to get the same results. I literally just want my movement to feel as smooth as that in Source.