SixDPhysicsController

From Unify Community Wiki
Jump to: navigation, search

This is probably the simplest way to implement a six degrees of freedom (6DoF) controller that doesn't suffer from Gimbal lock. It's physics based so we let Unity's buit-in PhysX system do most of the work for us. However, it's not perfect and most users will probably want more control over how rotation is handled. But it's still a good starting point.


using UnityEngine;
 
/// <summary>
/// Simple physics based Six degrees of freedom (6DoF) controller.
/// Allows you to control a Rigidbody like in the game Descent.
/// </summary>
/// <remarks>
/// For proper functionality freeze all rotation on the Rigidbody,
/// disable gravity, set drag to 1 and angular drag to 5.
/// </remarks>
 
[RequireComponent (typeof(Rigidbody),typeof(Camera))]
public class SixDPhysicsController : MonoBehaviour
{
    [SerializeField] float moveSpeed = 1f;
    [SerializeField] float turnSpeed = 1f;
    [SerializeField] float rollSpeed = 0.1f;
    [SerializeField] bool invertY = false;
 
    Rigidbody body;
 
    void Awake ()
    {
        body = GetComponent<Rigidbody> ();
    }
 
    void OnEnable ()
    {
        // Lock the cursor and hide it.
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }
 
    void FixedUpdate ()
    {
        body.AddRelativeTorque (GetRotation (), ForceMode.VelocityChange);
        body.AddRelativeForce (GetDirection () * moveSpeed, ForceMode.VelocityChange);
    }
 
    Vector3 GetDirection ()
    {
        // Create a movement direction vector based on keyboard input.
        var dir = new Vector3 ();
        if (Input.GetKey (KeyCode.W)) dir += Vector3.forward;
        if (Input.GetKey (KeyCode.S)) dir += Vector3.back;
        if (Input.GetKey (KeyCode.A)) dir += Vector3.left;
        if (Input.GetKey (KeyCode.D)) dir += Vector3.right;
        if (Input.GetKey (KeyCode.LeftControl)) dir += Vector3.down;
        if (Input.GetKey (KeyCode.Space)) dir += Vector3.up;
        return dir;
    }
 
    Vector3 GetRotation ()
    {
        float yaw = Input.GetAxis ("Mouse X");
        float pitch = Input.GetAxis ("Mouse Y") * (invertY ? 1 : -1);
        float roll = 0;
        if (Input.GetKey (KeyCode.Q)) roll += 1;
        if (Input.GetKey (KeyCode.E)) roll -= 1;
        return new Vector3 (pitch * turnSpeed, yaw * turnSpeed, roll * rollSpeed);
    }
}
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox