-
-
Save soraphis/5b3d01d8bb1086a88cce13325c40b56b to your computer and use it in GitHub Desktop.
Unity first person controller with extracted input handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using Assets._Game.Scripts.CharacterController; | |
[RequireComponent (typeof (Rigidbody))] | |
[RequireComponent (typeof (CapsuleCollider))] | |
public class FirstPersonController : MonoBehaviour { | |
public float RotationSpeed = 50; | |
public float MovementSpeed = 2; | |
public Vector2 Sensitivity = Vector2.one; | |
public Vector2 Smoothing = Vector2.one; | |
public GameObject Head; | |
public bool CanRun; | |
[Range(1, 10)] public float RunMultiplicator; | |
public bool CanJump => JumpHeight > 0; | |
public float JumpHeight; | |
private bool grounded = false; | |
private new Rigidbody rigidbody; | |
private new CapsuleCollider collider; | |
private Vector2 smoothMouse; | |
private Vector2 mouseAbsolute; | |
public Vector2 ClampInDegrees = new Vector2(360, 180); | |
private Vector2 targetDirection; | |
private Vector2 targetCharacterDirection; | |
public IFPInputProvider InputProvider; | |
void Awake() { | |
collider = this.GetComponent<CapsuleCollider>(); | |
rigidbody = this.GetComponent<Rigidbody>(); | |
rigidbody.freezeRotation = true; | |
} | |
void Start() { | |
if (Head == null) Head = GetComponentInChildren<Camera>().gameObject; | |
if (Head == null) this.enabled = false; | |
targetDirection = transform.localEulerAngles; | |
if (InputProvider == null) { | |
Debug.LogError("You need to add an FirstPersonInputProvider to this component."); | |
this.enabled = false; | |
} | |
} | |
void OnEnable() { | |
Cursor.lockState = CursorLockMode.Locked; | |
Cursor.visible = false; | |
} | |
void FixedUpdate () { | |
#region Movement | |
var dir = InputProvider.MoveDirection.normalized*MovementSpeed; | |
if (grounded) rigidbody.velocity = transform.TransformDirection(new Vector3(dir.x, 0, dir.y)); | |
else { | |
rigidbody.AddForce(Physics.gravity*3, ForceMode.Acceleration); | |
} | |
var oldLayer = this.gameObject.layer; | |
this.gameObject.layer = 4; | |
Vector3 feet = new Vector3(collider.bounds.center.x, collider.bounds.min.y + collider.radius - 0.125f, collider.bounds.center.z); | |
grounded = Physics.CheckCapsule(collider.bounds.center, feet, collider.radius - 0.0625f, layermask: ~LayerMask.GetMask(LayerMask.LayerToName(this.gameObject.layer))); | |
this.gameObject.layer = oldLayer; | |
// todo: do jumping stuff | |
#endregion | |
#region LookAround | |
var mouse = Vector2.Scale(InputProvider.LookDirection, new Vector2(Sensitivity.x*Smoothing.x, Sensitivity.y + Smoothing.y)); | |
var targetOrientation = Quaternion.Euler(targetDirection); | |
smoothMouse.x = Mathf.Lerp(smoothMouse.x, mouse.x, 1f/Smoothing.x); | |
smoothMouse.y = Mathf.Lerp(smoothMouse.y, mouse.y, 1f/Smoothing.y); | |
mouseAbsolute += smoothMouse; | |
if (ClampInDegrees.x < 360) { | |
mouseAbsolute.x = Mathf.Clamp(mouseAbsolute.x, -ClampInDegrees.x*0.5f, ClampInDegrees.x*0.5f); | |
} | |
if (ClampInDegrees.y < 360) { | |
mouseAbsolute.y = Mathf.Clamp(mouseAbsolute.y, -ClampInDegrees.y*0.5f, ClampInDegrees.y*0.5f); | |
} | |
var yrot = Quaternion.AngleAxis(mouse.x, Vector3.up); | |
transform.localRotation *= yrot; | |
Head.transform.localRotation = Quaternion.AngleAxis(- mouseAbsolute.y, targetOrientation * Vector3.right); | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace Assets._Game.Scripts.CharacterController { | |
// would be better if this would be an Interface, but if its an interface you can't set the value in the inspector :( | |
// unless you use a plugin like this: https://www.assetstore.unity3d.com/en/#!/content/12117 | |
public abstract class IFPInputProvider : MonoBehaviour { | |
/// <summary> Should store the mouse-delta / joystick input from the last frame. (do not confuse with mouse-screen-position) </summary> | |
public Vector2 LookDirection { get; protected set; } | |
/// <summary> Should store the Direction the player desires to walk. (horizontal/vertical move axis) </summary> | |
public Vector2 MoveDirection { get; protected set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace Assets._Game.Scripts.CharacterController { | |
/// <summary> | |
/// example input provider with the Unity buildin input system | |
/// </summary> | |
public class Unity4Input_FPInputProvider : IFPInputProvider { | |
void Update() { | |
MoveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); | |
LookDirection = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.InputNew; | |
namespace Assets._Game.Scripts.CharacterController { | |
/// <summary> | |
/// example for use with the 2016 new input system: | |
/// http://blogs.unity3d.com/2016/04/12/developing-the-new-input-system-together-with-you/ | |
/// </summary> | |
public class Unity5NewInput_FPInputProvider : IFPInputProvider { | |
public PlayerInput PlayerInput; | |
private PlayerActionMap actionmap; | |
private PlayerActionMap ActionMap => actionmap ?? (actionmap = PlayerInput.GetActions<PlayerActionMap>()); | |
void Update() { | |
MoveDirection = new Vector2(ActionMap.moveHorizontal.rawValue, ActionMap.moveVertical.rawValue); | |
LookDirection = new Vector2(ActionMap.lookHorizontal.rawValue, ActionMap.lookVertical.rawValue); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment