A wall run script for a non-rigidboy player:
var crouchSpeed : float = 2;
public var walkSpeed : float = 6.0;
var runSpeed : float = 11.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
// Units that player can fall before a falling damage function is run. To disable, type "infinity" in the inspector
var fallingDamageThreshold : float = 10.0;
// If the player ends up on a slope which is at least the Slope Limit as set on the character controller, then he will slide down
var slideWhenOverSlopeLimit = false;
// If checked and the player is on an object tagged "Slide", he will slide down it regardless of the slope limit
var slideOnTaggedObjects : boolean = false;
var slideSpeed : float = 12.0;
// If checked, then the player can change direction while in the air
var airControl : boolean = false;
// Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
var antiBumpFactor : float = .75;
// Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
var antiBunnyHopFactor : int = 1;
private var moveDirection = [login to view URL];
var grounded = false;
private var controller : CharacterController;
private var myTransform : Transform;
var speed : float;
private var hit : RaycastHit;
private var fallStartLevel : float;
private var falling = false;
private var slideLimit : float;
private var rayDistance : float;
private var contactPoint : Vector3;
private var playerControl = false;
private var jumpTimer : int;
@HideInInspector
var state : int = 0;
// 0 = standing
// 1 = crouching
// 2 = prone
@HideInInspector
var run : boolean;
@HideInInspector
var canRun : boolean = true;
//@HideInInspector
var running : boolean;
private var distanceToObstacle : float;
var cameraHolder : GameObject;
private var normalHeight : float = 0.7;
private var crouchHeight : float = 0.0;
private var crouchCamSpeed : float = 4;
function Start () {
controller = GetComponent(CharacterController);
myTransform = transform;
speed = walkSpeed;
rayDistance = [login to view URL] * .5 + [login to view URL];
slideLimit = [login to view URL] - .1;
jumpTimer = antiBunnyHopFactor;
}
function Update() {
var inputX = [login to view URL]("Horizontal");
var inputY = [login to view URL]("Vertical");
var inputModifyFactor = (inputX != 0.0 && inputY != 0.0)? .7071 : 1.0;
if (grounded) {
var sliding = false;
// See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point,
// because that interferes with step climbing amongst other annoyances
if ([login to view URL]([login to view URL], [login to view URL], hit, rayDistance)) {
if ([login to view URL]([login to view URL], [login to view URL]) > slideLimit)
sliding = true;
}
// However, just raycasting straight down from the center can fail when on steep slopes
// So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
else {
[login to view URL](contactPoint + [login to view URL], [login to view URL], hit);
if ([login to view URL]([login to view URL], [login to view URL]) > slideLimit)
sliding = true;
}
// If we were falling, and we fell a vertical distance greater than the threshold, run a falling damage routine
if (falling) {
falling = false;
if (myTransform.position.y < fallStartLevel - fallingDamageThreshold)
FallingDamageAlert (fallStartLevel - myTransform.position.y);
}
if(canRun && cameraHolder.transform.localPosition.y > normalHeight - 0.1){
if([login to view URL]([login to view URL]) && [login to view URL]("w")) run = true;
else run = false;
}
// If sliding (and it's allowed), or if we're on an object tagged "Slide", get a vector pointing down the slope we're on
if ( (sliding && slideWhenOverSlopeLimit) || (slideOnTaggedObjects && [login to view URL] == "Slide") ) {
var hitNormal = [login to view URL];
moveDirection = Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
[login to view URL] (hitNormal, moveDirection);
moveDirection *= slideSpeed;
playerControl = false;
} else {
if(state == 0){
if (run){
speed = runSpeed;
}else{
if([login to view URL]("Fire2")){
speed = crouchSpeed;
}else{
speed = walkSpeed;
}
}
}else if(state == 1){
speed = crouchSpeed;
run = false;
}
if([login to view URL]) moveDirection = Vector3(inputX * inputModifyFactor, -antiBumpFactor, inputY * inputModifyFactor);
else moveDirection = Vector3(0, -antiBumpFactor, 0);
moveDirection = [login to view URL](moveDirection);
moveDirection *= speed;
if (![login to view URL]([login to view URL])){
jumpTimer++;
}else if (jumpTimer >= antiBunnyHopFactor){
jumpTimer = 0;
moveDirection.y = jumpSpeed;
if(state > 0){
CheckDistance();
if(distanceToObstacle > 1.6){
state = 0;
}
}
}
}
}else {
// If we stepped over a cliff or something, set the height at which we started falling
if (!falling) {
falling = true;
fallStartLevel = myTransform.position.y;
}
// If air control is allowed, check movement but don't touch the y component
if (airControl && playerControl) {
moveDirection.x = inputX * speed * inputModifyFactor;
moveDirection.z = inputY * speed * inputModifyFactor;
moveDirection = [login to view URL](moveDirection);
}
}
if ([login to view URL]([login to view URL])) {
CheckDistance();
if(state == 0){
state = 1;
}else if(state == 1){
if(distanceToObstacle > 1.6){
state = 0;
}
}
}
if(state == 0){ //Stand Position
[login to view URL] = 2.0;
[login to view URL] = Vector3 (0, 0, 0);
if(cameraHolder.transform.localPosition.y > normalHeight){
cameraHolder.transform.localPosition.y = normalHeight;
} else if(cameraHolder.transform.localPosition.y < normalHeight){
cameraHolder.transform.localPosition.y += [login to view URL] * crouchCamSpeed;
}
}else if(state == 1){ //Crouch Position
[login to view URL] = 1.4;
[login to view URL] = Vector3 (0, -0.3, 0);
if(cameraHolder.transform.localPosition.y != crouchHeight){
if(cameraHolder.transform.localPosition.y > crouchHeight){
cameraHolder.transform.localPosition.y -= [login to view URL] * crouchCamSpeed;
}
if(cameraHolder.transform.localPosition.y < crouchHeight){
cameraHolder.transform.localPosition.y += [login to view URL] * crouchCamSpeed;
}
}
}
// Apply gravity
moveDirection.y -= gravity * [login to view URL];
// Move the controller, and set grounded true or false depending on whether we're standing on something
grounded = ([login to view URL](moveDirection * [login to view URL]) & [login to view URL]) != 0;
}
function CheckDistance(){
var pos : Vector3 = [login to view URL] + [login to view URL] - Vector3(0, [login to view URL], 0);
var hit : RaycastHit;
if([login to view URL](pos, [login to view URL], [login to view URL], hit, 10)){
distanceToObstacle = [login to view URL];
[login to view URL] ( pos, [login to view URL], [login to view URL], 2.0);
}else{
distanceToObstacle = 3;
}
}
// Store point that we're in contact with for use in FixedUpdate if needed
function OnControllerColliderHit (hit : ControllerColliderHit) {
contactPoint = [login to view URL];
}
// If falling damage occured, this is the place to do something about it. You can make the player
// have hitpoints and remove some of them based on the distance fallen, add sound effects, etc.
function FallingDamageAlert (fallDistance : float) {
[login to view URL] ("Ouch! Fell " + fallDistance + " units!");
}
@script RequireComponent(CharacterController)