Created
July 11, 2017 01:32
-
-
Save Kimeiga/14d171dc36721fce6ee91d0e8080f79c to your computer and use it in GitHub Desktop.
A better version of Gravity FPS Walker for Unity FP games
This file contains hidden or 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; | |
/* ------------------------------------------------------------------------------- | |
GravityFPSWalkerModified | |
This component is added to a GameObject with a RigidBody. It allows the player | |
to move the RigidBody using the vertical and horizontal inputs, and to jump | |
using the jump button. | |
The RigidBody is pushed towards its own custom Gravity vector. The body will | |
rotate to stay upright with the RotationRate. | |
This component uses a raycast to determine if the RigidBody is standing on | |
the ground. The GroundHeight variable should be the distance between the | |
GameObject transform and a little further than the bottom of the RigidBody. | |
The LookTransform should be a child GameObject which points in the direction | |
that the player is looking at. This could for example be a child GameObject | |
with a camera. The LookTransform is used to determine the movement vectors. | |
Hakan changed some things around a bunch of years ago just so you know~ | |
------------------------------------------------------------------------------ */ | |
[RequireComponent(typeof(Rigidbody))] | |
public class GravityFPSWalkerModified : MonoBehaviour { | |
private Transform lookTransform; | |
private Vector3 gravity = Vector3.down * 9.81f; | |
private float rotationRate = 0.1f; | |
private float velocity = 8; | |
private float crouchVelocity = 5; | |
private float groundControl = 1.0f; | |
private float airControl = 0.2f; | |
private float jumpVelocity = 5; | |
private float groundHeight = 1.1f; | |
private bool jump; | |
private bool slide; | |
private float height; | |
private CapsuleCollider cap; | |
private Transform t; | |
private bool walljump = false; | |
private Vector3 wallNormal; | |
private bool grounded; | |
public Transform LookTransform { get => lookTransform; set => lookTransform = value; } | |
public Vector3 Gravity { get => gravity; set => gravity = value; } | |
public global::System.Single RotationRate { get => rotationRate; set => rotationRate = value; } | |
public global::System.Single Velocity { get => velocity; set => velocity = value; } | |
public global::System.Single CrouchVelocity { get => crouchVelocity; set => crouchVelocity = value; } | |
public global::System.Single GroundControl { get => groundControl; set => groundControl = value; } | |
public global::System.Single AirControl { get => airControl; set => airControl = value; } | |
public global::System.Single JumpVelocity { get => jumpVelocity; set => jumpVelocity = value; } | |
public global::System.Single GroundHeight { get => groundHeight; set => groundHeight = value; } | |
public global::System.Boolean Jump { get => jump; set => jump = value; } | |
public global::System.Boolean Slide { get => slide; set => slide = value; } | |
public global::System.Single Height { get => height; set => height = value; } | |
public CapsuleCollider Cap { get => cap; set => cap = value; } | |
public Transform T { get => t; set => t = value; } | |
public global::System.Boolean Walljump { get => walljump; set => walljump = value; } | |
public Vector3 WallNormal { get => wallNormal; set => wallNormal = value; } | |
public global::System.Boolean Grounded { get => grounded; set => grounded = value; } | |
void Start() { | |
GetComponent<Rigidbody>().freezeRotation = true; | |
GetComponent<Rigidbody>().useGravity = false; | |
T = transform; | |
Height = Cap.height; | |
} | |
void OnCollisionStay(Collision hit) { | |
WallNormal = hit.contacts[0].normal; | |
if(Grounded == false){ | |
if(Input.GetButton("Jump")){ | |
Walljump = true; | |
} | |
} | |
} | |
void Update() { | |
Jump = Jump || Input.GetButton("Jump"); | |
if(Input.GetButton("Slide")){ | |
Slide = true; | |
}else{ | |
Slide = false; | |
} | |
} | |
void FixedUpdate() { | |
float h; | |
if(Input.GetButton("Crouch")){ | |
h = 0.5f * Height; | |
Velocity = CrouchVelocity; | |
}else{ | |
h = Height; | |
Velocity = 7; | |
} | |
float lastHeight = Cap.height; // crouch/stand up smoothly | |
Cap.height = Mathf.Lerp(Cap.height, h, 5*Time.deltaTime); | |
// Cast a ray towards the ground to see if the Walker is grounded | |
Grounded = Physics.Raycast(transform.position, Gravity.normalized, GroundHeight); | |
// Rotate the body to stay upright | |
Vector3 gravityForward = Vector3.Cross(Gravity, transform.right); | |
Quaternion targetRotation = Quaternion.LookRotation(gravityForward, -Gravity); | |
GetComponent<Rigidbody>().rotation = Quaternion.Lerp(GetComponent<Rigidbody>().rotation, targetRotation, RotationRate); | |
// Add velocity change for movement on the local horizontal plane | |
Vector3 forward = Vector3.Cross(transform.up, -LookTransform.right).normalized; | |
Vector3 right = Vector3.Cross(transform.up, LookTransform.forward).normalized; | |
Vector3 targetVelocity = (forward * Input.GetAxis("Vertical") + right * Input.GetAxis("Horizontal")) * Velocity; | |
Vector3 localVelocity = transform.InverseTransformDirection(GetComponent<Rigidbody>().velocity); | |
Vector3 velocityChange = transform.InverseTransformDirection(targetVelocity) - localVelocity; | |
// The velocity change is clamped to the control velocity | |
// The vertical component is either removed or set to result in the absolute jump velocity | |
velocityChange = Vector3.ClampMagnitude(velocityChange, Grounded ? GroundControl : AirControl); | |
velocityChange.y = Jump && Grounded ? -localVelocity.y + JumpVelocity : 0; | |
if(Walljump == true){ | |
velocityChange.y = -localVelocity.y + (JumpVelocity * 0.7f); | |
//velocityChange += wallNormal.normalized * 10; | |
//walljump = false; | |
} | |
velocityChange = transform.TransformDirection(velocityChange); | |
if(Slide == false){ | |
GetComponent<Rigidbody>().AddForce(velocityChange, ForceMode.VelocityChange); | |
if(Walljump == true){ | |
GetComponent<Rigidbody>().AddForce(WallNormal.normalized * 5, ForceMode.VelocityChange); | |
//targetVelocity = (forward * Input.GetAxis("Vertical") + right * Input.GetAxis("Horizontal")) * Velocity; | |
//localVelocity = transform.InverseTransformDirection(rigidbody.velocity); | |
//velocityChange = transform.InverseTransformDirection(targetVelocity) - localVelocity; | |
//rigidbody.AddForce(velocityChange * 0.5f, ForceMode.VelocityChange); | |
Walljump = false; | |
} | |
} | |
// Add gravity | |
GetComponent<Rigidbody>().AddForce(Gravity * GetComponent<Rigidbody>().mass); | |
Jump = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
QUERO GRAFICOS BOMS