Latest Versions : CharacterController v2.3 / CameraController v2.1

Details

Free Character Controller is a WoW/RPG like Character Controller Pack for Unity3D

A time ago I started working on my own RPG, one of my first steps was to move something around like a character in a rpg would do.... I have checked the www for ideas and hints but found only complete charactercontroller for money. I don't want to pay for this so I decided to work on my own character controller. With the help from the Unity-Community I finally reached my goal of a WoW-Like Camera- and Charakter-Controller.
And I want to share the results with you. Here you will find the Free Character Controller and some infos how to use it.

Don't miss to download the "ffcexample.zip" file if you have any problems, it's maybe helpfull for you.
If you have any questions or found a bug, feel free to contact me here Unity Forums or send me an email at:
semperion at ruhrnuklear dot de

What you will get and some more infos:
- the camera is moving back behind the player after moving around when the player was moving
- selfattaching the player gameobject to the camera target
- slower back and sidewalk
- strafing (need to setup Input as "Strafing") or when mousebutton hold down
- run just on hold key (need to setup Input as "Run")
- public var "swimming" to reduce movementspeed by 70% when triggered
- left & right mousebutton moving, also sidebutton movetoggel (like wow) (setup Input as "Toggle Move" ("mouse 3" for my mx518 )
- playerlayer avoid
- camera softreturn while moving with mousesidebutton // v1.7 - 09.Oct.2012
- added full movement list for animation usage to CharacterController // v1.9 - 09.Oct.2012
- codecleanup // v2.0 - 09.Oct.2012
- stop movement on autorun(sidebutton toggle) when jump or move back/forward // v2.1 - 09.Oct.2012
- stop automovement on L+R mousebuttons (sidebutton toggle) // v2.2 - 09.Oct.2012
- fixxed movingspeed bug (when L+R mousebuttons + MoveForward keys pressed, the speed was doubled) // v2.3 - 19.Sep.2013


Download

Settings

0. the Player/whatever u want to move needs a CharacterController



1. the Main Camera needs to be tagged as MainCamera



2. the Player/whatever u want to move needs to be tagged as Player



3. the player needs to be added to a seperate layer



4. attach the CameraController Script to the MainCamera and deselect the Layer from 3. at "collisionLayers"



5. the CharacterController script needs to be attached at the Player/whatever u want to move



6. "fix" for the clipping problem with the MainCamera. :
- go to MainCamera -> Camera -> Clipping Planes -> Near and set it to 0.01
- go to MainCamera -> Camera -> Field of View and set a value around 70 (it looks good)- 12.Oct.2012



Sourcecode


CharacterControllerjs.js (JavaScript) V2.3
//Character Controller in JS v2.3

//Var definition
public var swimming:boolean false;                //Can be triggert to slow down the movements (like when u swim)
public var moveStatus:String "idle";                //movestatus for animations

//Movement speeds
private var jumpSpeed:float 8.0;                    //Jumpspeed / Jumpheight
private var gravity:float 20.0;                    //Gravity for jump
private var runSpeed:float 10.0;                    //Speed when the Character is running
private var walkSpeed:float 4.0;                    //Speed when the Character is walking (normal movement)
private var rotateSpeed:float 250.0;                //Rotationspeed of the Character
private var walkBackMod:float 0.75;                //Speed in Percent for walk backwards and sidewalk

//Internal vars to work with
private var speedMod:float 0.0;                    //temp Var for Speedcalculation
private var grounded:boolean false;                //temp var if the character is grounded
private var moveDirection:Vector3 Vector3.zero;    //move direction of the Character
private var isWalking:boolean false;                //toggle var between move and run
private var jumping:boolean false;                //temp var for jumping
private var mouseSideButton:boolean false;        //temp var for mouse side buttons
private var pbuffer:float 0.0;                    //Cooldownpuffer for SideButtons
private var coolDown:float 0.5;                   //Cooldowntime for SideButtons

//Every Frame
function Update ()
{
    
//Set idel animation
    
moveStatus "idle";
        
    
// Hold "Run" to run
    
isWalking Input.GetAxis("Run") ? false true;
    
    
// Only allow movement and jumps while grounded
    
if(grounded) {
        
        
//movedirection
        
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
        
        
//pushbuffer to avoid on/off flipping
        
if(pbuffer>0)
            
pbuffer -=Time.deltaTime;
        if(
pbuffer<0)pbuffer=0;
                       
        
//Automove Sidebuttonmovement
        
if(Input.GetAxis("Toggle Move") && pbuffer == 0){
            
pbuffer=coolDown;
            
mouseSideButton = !mouseSideButton;
        }
        if(
mouseSideButton && ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump") || (Input.GetMouseButton(0) && Input.GetMouseButton(1)) ))
            
mouseSideButton false;        
        
        
//L+R MouseButton Movement
        
if (Input.GetMouseButton(0) && Input.GetMouseButton(1) || mouseSideButton)
            
moveDirection.+= 1;
        if (moveDirection.z > 1)
            moveDirection.z = 1;

                
        
        
//Strafing move (like Q/E movement    
        
moveDirection.-= Input.GetAxis("Strafing");
            
          
// if moving forward and to the side at the same time, compensate for distance
          
if(Input.GetMouseButton(1) && Input.GetAxis("Horizontal") && Input.GetAxis("Vertical")) {
            
moveDirection *= .7;
          }
                          
        
//Speedmodification / is moving forward or side/backward
        
speedMod = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1) && Input.GetAxis("Horizontal")) || Input.GetAxis("Strafing") != 0) ? walkBackMod 1.0;
        
        
//Use run or walkspeed
        
moveDirection *= isWalking walkSpeed speedMod runSpeed speedMod;
        
        
//reduce movement by 70% when swimming is toggled   
        
moveDirection*= swimming 0.7 1;
                  
        
// Jump!
        
if(Input.GetButton("Jump")){
            
jumping true;
            
moveDirection.jumpSpeed;
        }
        
        
//movestatus normal movement (for animations)              
        
if((moveDirection.== ) && (moveDirection.== 0))
            
moveStatus "idle";            
        if(
moveDirection.0)
            
moveStatus isWalking "walking" "running";
        if(
moveDirection.0)
            
moveStatus isWalking "backwalking" "backrunning";        
        if(
moveDirection.0)
            
moveStatus isWalking "sidewalking_r" "siderunning_r";
        if(
moveDirection.0)
            
moveStatus isWalking "sidewalking_l" "siderunning_l";    
        
        
//movestatus swim movement (for animations)              
        
if(swimming){
            if((
moveDirection.== ) && (moveDirection.== 0))
                
moveStatus "swimidle";            
            if(
moveDirection.0)
                
moveStatus isWalking "swim" "swimfast";
            if(
moveDirection.0)
                
moveStatus isWalking "backswim" "backswimfast";        
            if(
moveDirection.0)
                
moveStatus isWalking "sideswim_r" "sideswimfast_r";
            if(
moveDirection.0)
                
moveStatus isWalking "sidewswim_l" "sideswimfast_l";    
            if(
jumping)
                
moveStatus "swimup";                    
        }  
        
        
//transform direction
        
moveDirection transform.TransformDirection(moveDirection);        

    }
    
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    
if(Input.GetMouseButton(1)) {
        
transform.rotation Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    } else {
        
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed Time.deltaTime0);
    }

    
//Apply gravity
    
moveDirection.-= gravity Time.deltaTime;
    
    
//Move controller
    
var controller:CharacterController GetComponent(CharacterController);
    var 
flags controller.Move(moveDirection Time.deltaTime);
    
grounded = (flags CollisionFlags.Below) != 0;
    
    
//Reset jumping after landing
    
jumping grounded false jumping;

    
//movestatus jump/swimup (for animations)      
    
if(jumping)
        
moveStatus "jump";
    if(
jumping && swimming)
        
moveStatus "swimup";

CharacterControllercs.cs (CSharp) V2.3
/// <summary>
/// Charactercontrollercs.cs
/// Character Controller in CSharp v2.3
/// </summary>
using UnityEngine;

public class 
CharacterControllercs MonoBehaviour {
            
    
//Var definition
    
public bool swimming false;                    //Can be triggert to slow down the movements (like when u swim)
    
public string moveStatus "idle";                //movestatus for animations
    
    //Movement speeds
    
private float jumpSpeed 8.0f;                    //Jumpspeed / Jumpheight
    
private float gravity 20.0f;                    //Gravity for jump
    
private float runSpeed 10.0f;                    //Speed when the Character is running
    
private float walkSpeed 4.0f;                    //Speed when the Character is walking (normal movement)
    
private float rotateSpeed 250.0f;                //Rotationspeed of the Character
    
private float walkBackMod 0.75f;                //Speed in Percent for walk backwards and sidewalk
    
    //Internal vars to work with
    
private float speedMod 0.0f;                    //temp Var for Speedcalculation
    
private bool grounded false;                    //temp var if the character is grounded
    
private Vector3 moveDirection Vector3.zero;    //move direction of the Character
    
private bool isWalking false;                    //toggle var between move and run
    
private bool jumping false;                    //temp var for jumping
    
private bool mouseSideButton false;            //temp var for mouse side buttons
    
private float pbuffer 0.0f;                    //Cooldownpuffer for SideButtons
    
private float coolDown 0.5f;                   //Cooldowntime for SideButtons
    
private CharacterController controller;            //CharacterController for movement
    
    //Every Frame
    
void Update ()
    {
        
//Set idel animation
        
moveStatus "idle";
        
isWalking true;
            
        
// Hold "Run" to run
        
if(Input.GetAxis("Run") != 0)
            
isWalking false;
        
        
// Only allow movement and jumps while grounded
        
if(grounded) {
            
            
//movedirection
            
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
            
            
//pushbuffer to avoid on/off flipping
            
if(pbuffer>0)
                
pbuffer -=Time.deltaTime;
            if(
pbuffer<0)pbuffer=0;
                           
            
//Automove Sidebuttonmovement
            
if((Input.GetAxis("Toggle Move") !=0) && pbuffer == 0){
                
pbuffer=coolDown;
                
mouseSideButton = !mouseSideButton;
            }
            if(
mouseSideButton && ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump")) || (Input.GetMouseButton(0) && Input.GetMouseButton(1)))
                
mouseSideButton false;            
            
            
//L+R MouseButton Movement
            
if (Input.GetMouseButton(0) && Input.GetMouseButton(1) || mouseSideButton)
                
moveDirection.+= 1;
            if (moveDirection.z > 1)
                moveDirection.z = 1;

                
            
//Strafing move (like Q/E movement    
            
moveDirection.-= Input.GetAxis("Strafing");
                
              
// if moving forward and to the side at the same time, compensate for distance
              
if(Input.GetMouseButton(1) && (Input.GetAxis("Horizontal") != 0) && (Input.GetAxis("Vertical") != 0)) {
                
moveDirection *= 0.7f;
              }
                              
            
//Speedmodification / is moving forward or side/backward
            
speedMod = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1) && (Input.GetAxis("Horizontal")) != 0) || Input.GetAxis("Strafing") != 0) ? walkBackMod 1.0f;
            
            
//Use run or walkspeed
            
moveDirection *= isWalking walkSpeed speedMod runSpeed speedMod;
            
            
//reduce movement by 70% when swimming is toggled   
            
moveDirection*= swimming 0.7f 1;
                      
            
// Jump!
            
if(Input.GetButton("Jump")){
                
jumping true;
                
moveDirection.jumpSpeed;
            }
            
            
//movestatus normal movement (for animations)              
            
if((moveDirection.== ) && (moveDirection.== 0))
                
moveStatus "idle";            
            if(
moveDirection.0)
                
moveStatus isWalking "walking" "running";
            if(
moveDirection.0)
                
moveStatus isWalking "backwalking" "backrunning";        
            if(
moveDirection.0)
                
moveStatus isWalking "sidewalking_r" "siderunning_r";
            if(
moveDirection.0)
                
moveStatus isWalking "sidewalking_l" "siderunning_l";    
            
            
//movestatus swim movement (for animations)              
            
if(swimming){
                if((
moveDirection.== ) && (moveDirection.== 0))
                    
moveStatus "swimidle";            
                if(
moveDirection.0)
                    
moveStatus isWalking "swim" "swimfast";
                if(
moveDirection.0)
                    
moveStatus isWalking "backswim" "backswimfast";        
                if(
moveDirection.0)
                    
moveStatus isWalking "sideswim_r" "sideswimfast_r";
                if(
moveDirection.0)
                    
moveStatus isWalking "sidewswim_l" "sideswimfast_l";    
                if(
jumping)
                    
moveStatus "swimup";                    
            }  
            
            
//transform direction
            
moveDirection transform.TransformDirection(moveDirection);        
        
        }
        
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
        
if(Input.GetMouseButton(1)) {
            
transform.rotation Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
        } else {
            
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed Time.deltaTime0);
        }
        
        
//Apply gravity
        
moveDirection.-= gravity Time.deltaTime;
        
        
//Get CharacterController
        
controller GetComponent<CharacterController>();
        
//Move Charactercontroller and check if grounded
        
grounded = ((controller.Move(moveDirection Time.deltaTime)) & CollisionFlags.Below) != 0;
        
        
//Reset jumping after landing
        
jumping grounded false jumping;
        
        
//movestatus jump/swimup (for animations)      
        
if(jumping)
            
moveStatus "jump";
        if(
jumping && swimming)
            
moveStatus "swimup";    
    }

CameraControllerjs.js (JavaScript) V2.1
//Camera Controller in JS v2.1

public var target:GameObject;                      //Target to follow
public var targetHeight:float 1.7;            //Vertical offset adjustment
public var distance:float 12;                 //Default Distance
public var offsetFromWall:float 0.1;          //Bring camera away from any colliding objects
public var maxDistance:float 20;              //Maximum zoom Distance
public var minDistance:float 0.6;             //Minimum zoom Distance
public var xSpeed:float 200;                  //Orbit speed (Left/Right)
public var ySpeed:float 200;                  //Orbit speed (Up/Down)
public var yMinLimit:float = -80;               //Looking up limit
public var yMaxLimit:float 80;                //Looking down limit
public var zoomRate:float 40;                 //Zoom Speed
public var rotationDampening:float 3;         //Auto Rotation speed (higher = faster)
public var zoomDampening:float 5;             //Auto Zoom speed (Higher = faster)
public var collisionLayers:LayerMask = -1;        //What the camera will collide with
public var lockToRearOfTarget:boolean false;  //Lock camera to rear of target
public var allowMouseInputX:boolean true;     //Allow player to control camera angle on the X axis (Left/Right)
public var allowMouseInputY:boolean true;     //Allow player to control camera angle on the Y axis (Up/Down)
 
private var xDeg:float 0;                        //temp var
private var yDeg:float 0;                        //temp var
private var currentDistance:float;                //temp var
private var desiredDistance:float;                //temp var
private var correctedDistance:float;            //temp var
private var rotateBehind:boolean false;        //temp var
private var mouseSideButton:boolean false;    //temp var
private var pbuffer:float 0;                   //Cooldownpuffer for SideButtons
private var coolDown:float 0.5;                  //Cooldowntime for SideButtons 
     
function Start ()
{      
    var 
angles:Vector3 transform.eulerAngles;
    
xDeg angles.x;
    
yDeg angles.y;
    
currentDistance distance;
    
desiredDistance distance;
    
correctedDistance distance;
   
    
// Make the rigid body not change rotation
    
if (rigidbody)
        
rigidbody.freezeRotation true;
       
    if (
lockToRearOfTarget)
        
rotateBehind true;
 }
 
function 
Update(){
    if (
target == null){
        
target GameObject.FindGameObjectWithTag("Player") as GameObject;
        
Debug.Log("Looking for Player");
    }

}
     
//Only Move camera after everything else has been updated
function LateUpdate ()
{
    
// Don't do anything if target is not defined
    
if (target == null)
        return;
        
//pushbuffer
    
if(pbuffer>0)
        
pbuffer -=Time.deltaTime;
    if(
pbuffer<0)pbuffer=0;
       
    
//Sidebuttonmovement
    
if((Input.GetAxis("Toggle Move")!=0) && (pbuffer == 0)){
            
pbuffer=coolDown;
            
mouseSideButton = !mouseSideButton;
    }
    if(
mouseSideButton && Input.GetAxis("Vertical") != 0)
        
mouseSideButton false;
   
    var 
vTargetOffset:Vector3;
               
    
// If either mouse buttons are down, let the mouse govern camera position
    
if (GUIUtility.hotControl == 0)
    {
        if (
Input.GetMouseButton(0) || Input.GetMouseButton(1))
        {
            
//Check to see if mouse input is allowed on the axis
            
if (allowMouseInputX)
                
xDeg += Input.GetAxis ("Mouse X") * xSpeed 0.02;
            else
                
RotateBehindTarget();
            if (
allowMouseInputY)
                
yDeg -= Input.GetAxis ("Mouse Y") * ySpeed 0.02;
           
            
//Interrupt rotating behind if mouse wants to control rotation
            
if (!lockToRearOfTarget)
                
rotateBehind false;
        }

        
// otherwise, ease behind the target if any of the directional keys are pressed
        
else if (Input.GetAxis("Vertical") != || Input.GetAxis("Horizontal") != || rotateBehind || mouseSideButton)
        {
            
RotateBehindTarget();
        }
    }
    
yDeg ClampAngle (yDegyMinLimityMaxLimit);
 
    
// Set camera rotation
    
var rotation:Quaternion Quaternion.Euler (yDegxDeg0);
 
    
// Calculate the desired distance
    
desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime zoomRate Mathf.Abs (desiredDistance);
    
desiredDistance Mathf.Clamp (desiredDistanceminDistancemaxDistance);
    
correctedDistance desiredDistance;
 
    
// Calculate desired camera position
    
vTargetOffset = new Vector3 (0, -targetHeight0);
    var 
position:Vector3 target.transform.position - (rotation Vector3.forward desiredDistance vTargetOffset);
 
    
// Check for collision using the true target's desired registration point as set by user using height
    
var collisionHit:RaycastHit;
    var 
trueTargetPosition:Vector3 = new Vector3 (target.transform.position.xtarget.transform.position.targetHeighttarget.transform.position.z);
 
    
// If there was a collision, correct the camera position and calculate the corrected distance
    
var isCorrected:boolean false;
    if (
Physics.Linecast (trueTargetPositionpositioncollisionHitcollisionLayers))
    {
        
// Calculate the distance from the original estimated position to the collision location,
        // subtracting out a safety "offset" distance from the object we hit.  The offset will help
        // keep the camera from being right on top of the surface we hit, which usually shows up as
        // the surface geometry getting partially clipped by the camera's front clipping plane.
        
correctedDistance Vector3.Distance (trueTargetPositioncollisionHit.point) - offsetFromWall;
        
isCorrected true;
    }
 
    
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    
currentDistance = !isCorrected || correctedDistance currentDistance Mathf.Lerp (currentDistancecorrectedDistanceTime.deltaTime zoomDampening) : correctedDistance;
 
    
// Keep within limits
    
currentDistance Mathf.Clamp (currentDistanceminDistancemaxDistance);
 
    
// Recalculate position based on the new currentDistance
    
position target.transform.position - (rotation Vector3.forward currentDistance vTargetOffset);
   
    
//Finally Set rotation and position of camera
    
transform.rotation rotation;
    
transform.position position;
}
 
function 
RotateBehindTarget()
{
    var 
targetRotationAngle:float target.transform.eulerAngles.y;
    var 
currentRotationAngle:float transform.eulerAngles.y;
    
xDeg Mathf.LerpAngle (currentRotationAngletargetRotationAnglerotationDampening Time.deltaTime);
   
    
// Stop rotating behind if not completed
    
if (targetRotationAngle == currentRotationAngle)
    {
        if (!
lockToRearOfTarget)
            
rotateBehind false;
    }
    else
        
rotateBehind true
}
  
function 
ClampAngle(angle:floatmin:floatmax:float)
{
   if (
angle < -360)
      
angle += 360;
   if (
angle 360)
      
angle -= 360;
   return 
Mathf.Clamp (angleminmax);

CameraControllercs.cs (CSharp) V2.1
/// <summary>
/// CameraControllercs.cs
/// Camera Controller in CSharp v2.1
/// </summary>
    using UnityEngine;
    
using System.Collections;
     
    public class 
CameraControllercs MonoBehaviour {  
        public 
GameObject target;                           // Target to follow
        
public float targetHeight 1.7f;                         // Vertical offset adjustment
        
public float distance 12.0f;                            // Default Distance
        
public float offsetFromWall 0.1f;                       // Bring camera away from any colliding objects
        
public float maxDistance 20f;                       // Maximum zoom Distance
        
public float minDistance 0.6f;                      // Minimum zoom Distance
        
public float xSpeed 200.0f;                             // Orbit speed (Left/Right)
        
public float ySpeed 200.0f;                             // Orbit speed (Up/Down)
        
public float yMinLimit = -80f;                            // Looking up limit
        
public float yMaxLimit 80f;                             // Looking down limit
        
public float zoomRate 40f;                          // Zoom Speed
        
public float rotationDampening 3.0f;                // Auto Rotation speed (higher = faster)
        
public float zoomDampening 5.0f;                    // Auto Zoom speed (Higher = faster)
        
public LayerMask collisionLayers = -1;     // What the camera will collide with
        
public bool lockToRearOfTarget false;             // Lock camera to rear of target
        
public bool allowMouseInputX true;                // Allow player to control camera angle on the X axis (Left/Right)
        
public bool allowMouseInputY true;                // Allow player to control camera angle on the Y axis (Up/Down)
         
        
private float xDeg 0.0f;
        private 
float yDeg 0.0f;
        private 
float currentDistance;
        private 
float desiredDistance;
        private 
float correctedDistance;
        private 
bool rotateBehind false;
        private 
bool mouseSideButton false;   
        private 
float pbuffer 0.0f;       //Cooldownpuffer for SideButtons
        
private float coolDown 0.5f;      //Cooldowntime for SideButtons 
             
        
void Start ()
        {      
            
Vector3 angles transform.eulerAngles;
            
xDeg angles.x;
            
yDeg angles.y;
            
currentDistance distance;
            
desiredDistance distance;
            
correctedDistance distance;
           
            
// Make the rigid body not change rotation
            
if (rigidbody)
                
rigidbody.freezeRotation true;
               
            if (
lockToRearOfTarget)
                
rotateBehind true;
         }
        
void Update(){
            if (
target == null){
                
target GameObject.FindGameObjectWithTag("Player") as GameObject;
                
Debug.Log("Looking for Player");
            }
     
        }
             
        
//Only Move camera after everything else has been updated
        
void LateUpdate ()
        {
            
// Don't do anything if target is not defined
            
if (target == null)
                return;
                
//pushbuffer
            
if(pbuffer>0)
                
pbuffer -=Time.deltaTime;
            if(
pbuffer<0)pbuffer=0;
               
            
//Sidebuttonmovement
            
if((Input.GetAxis("Toggle Move")!=0) && (pbuffer == 0)){
                    
pbuffer=coolDown;
                    
mouseSideButton = !mouseSideButton;
            }
            if(
mouseSideButton && Input.GetAxis("Vertical") != )
                
mouseSideButton false;        
           
            
Vector3 vTargetOffset;
                       
            
// If either mouse buttons are down, let the mouse govern camera position
            
if (GUIUtility.hotControl == 0)
            {
                if (
Input.GetMouseButton(0) || Input.GetMouseButton(1))
                {
                    
//Check to see if mouse input is allowed on the axis
                    
if (allowMouseInputX)
                        
xDeg += Input.GetAxis ("Mouse X") * xSpeed 0.02f;
                    else
                        
RotateBehindTarget();
                    if (
allowMouseInputY)
                        
yDeg -= Input.GetAxis ("Mouse Y") * ySpeed 0.02f;
                   
                    
//Interrupt rotating behind if mouse wants to control rotation
                    
if (!lockToRearOfTarget)
                        
rotateBehind false;
                }
     
                
// otherwise, ease behind the target if any of the directional keys are pressed
                
else if (Input.GetAxis("Vertical") != || Input.GetAxis("Horizontal") != || rotateBehind || mouseSideButton)
                {
                    
RotateBehindTarget();
                }
            }
            
yDeg ClampAngle (yDegyMinLimityMaxLimit);
         
            
// Set camera rotation
            
Quaternion rotation Quaternion.Euler (yDegxDeg0);
         
            
// Calculate the desired distance
            
desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime zoomRate Mathf.Abs (desiredDistance);
            
desiredDistance Mathf.Clamp (desiredDistanceminDistancemaxDistance);
            
correctedDistance desiredDistance;
         
            
// Calculate desired camera position
            
vTargetOffset = new Vector3 (0, -targetHeight0);
            
Vector3 position target.transform.position - (rotation Vector3.forward desiredDistance vTargetOffset);
         
            
// Check for collision using the true target's desired registration point as set by user using height
            
RaycastHit collisionHit;
            
Vector3 trueTargetPosition = new Vector3 (target.transform.position.xtarget.transform.position.targetHeighttarget.transform.position.z);
         
            
// If there was a collision, correct the camera position and calculate the corrected distance
            
var isCorrected false;
            if (
Physics.Linecast (trueTargetPositionpositionout collisionHitcollisionLayers))
            {
                
// Calculate the distance from the original estimated position to the collision location,
                // subtracting out a safety "offset" distance from the object we hit.  The offset will help
                // keep the camera from being right on top of the surface we hit, which usually shows up as
                // the surface geometry getting partially clipped by the camera's front clipping plane.
                
correctedDistance Vector3.Distance (trueTargetPositioncollisionHit.point) - offsetFromWall;
                
isCorrected true;
            }
         
            
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
            
currentDistance = !isCorrected || correctedDistance currentDistance Mathf.Lerp (currentDistancecorrectedDistanceTime.deltaTime zoomDampening) : correctedDistance;
         
            
// Keep within limits
            
currentDistance Mathf.Clamp (currentDistanceminDistancemaxDistance);
         
            
// Recalculate position based on the new currentDistance
            
position target.transform.position - (rotation Vector3.forward currentDistance vTargetOffset);
           
            
//Finally Set rotation and position of camera
            
transform.rotation rotation;
            
transform.position position;
        }
         
        private 
void RotateBehindTarget()
        {
            
float targetRotationAngle target.transform.eulerAngles.y;
            
float currentRotationAngle transform.eulerAngles.y;
            
xDeg Mathf.LerpAngle (currentRotationAngletargetRotationAnglerotationDampening Time.deltaTime);
           
            
// Stop rotating behind if not completed
            
if (targetRotationAngle == currentRotationAngle)
            {
                if (!
lockToRearOfTarget)
                    
rotateBehind false;
            }
            else
                
rotateBehind true;
         
        }
         
         
         private 
float ClampAngle (float anglefloat minfloat max)
        {
           if (
angle < -360f)
              
angle += 360f;
           if (
angle 360f)
              
angle -= 360f;
           return 
Mathf.Clamp (angleminmax);
        }
       
    } 
Character Controllers V2.2 old
CharacterControllerjs.js (JavaScript) V2.2 old
//Character Controller in JS v2.2

//Var definition
public var swimming:boolean false;                //Can be triggert to slow down the movements (like when u swim)
public var moveStatus:String "idle";                //movestatus for animations

//Movement speeds
private var jumpSpeed:float 8.0;                    //Jumpspeed / Jumpheight
private var gravity:float 20.0;                    //Gravity for jump
private var runSpeed:float 10.0;                    //Speed when the Character is running
private var walkSpeed:float 4.0;                    //Speed when the Character is walking (normal movement)
private var rotateSpeed:float 250.0;                //Rotationspeed of the Character
private var walkBackMod:float 0.75;                //Speed in Percent for walk backwards and sidewalk

//Internal vars to work with
private var speedMod:float 0.0;                    //temp Var for Speedcalculation
private var grounded:boolean false;                //temp var if the character is grounded
private var moveDirection:Vector3 Vector3.zero;    //move direction of the Character
private var isWalking:boolean false;                //toggle var between move and run
private var jumping:boolean false;                //temp var for jumping
private var mouseSideButton:boolean false;        //temp var for mouse side buttons
private var pbuffer:float 0.0;                    //Cooldownpuffer for SideButtons
private var coolDown:float 0.5;                   //Cooldowntime for SideButtons

//Every Frame
function Update ()
{
    
//Set idel animation
    
moveStatus "idle";
        
    
// Hold "Run" to run
    
isWalking Input.GetAxis("Run") ? false true;
    
    
// Only allow movement and jumps while grounded
    
if(grounded) {
        
        
//movedirection
        
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
        
        
//pushbuffer to avoid on/off flipping
        
if(pbuffer>0)
            
pbuffer -=Time.deltaTime;
        if(
pbuffer<0)pbuffer=0;
                       
        
//Automove Sidebuttonmovement
        
if(Input.GetAxis("Toggle Move") && pbuffer == 0){
            
pbuffer=coolDown;
            
mouseSideButton = !mouseSideButton;
        }
        if(
mouseSideButton && ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump") || (Input.GetMouseButton(0) && Input.GetMouseButton(1)) ))
            
mouseSideButton false;        
        
        
//L+R MouseButton Movement
        
if (Input.GetMouseButton(0) && Input.GetMouseButton(1) || mouseSideButton)
            
moveDirection.+= 1;
        
        
//Strafing move (like Q/E movement    
        
moveDirection.-= Input.GetAxis("Strafing");
            
          
// if moving forward and to the side at the same time, compensate for distance
          
if(Input.GetMouseButton(1) && Input.GetAxis("Horizontal") && Input.GetAxis("Vertical")) {
            
moveDirection *= .7;
          }
                          
        
//Speedmodification / is moving forward or side/backward
        
speedMod = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1) && Input.GetAxis("Horizontal")) || Input.GetAxis("Strafing") != 0) ? walkBackMod 1.0;
        
        
//Use run or walkspeed
        
moveDirection *= isWalking walkSpeed speedMod runSpeed speedMod;
        
        
//reduce movement by 70% when swimming is toggled   
        
moveDirection*= swimming 0.7 1;
                  
        
// Jump!
        
if(Input.GetButton("Jump")){
            
jumping true;
            
moveDirection.jumpSpeed;
        }
        
        
//movestatus normal movement (for animations)              
        
if((moveDirection.== ) && (moveDirection.== 0))
            
moveStatus "idle";            
        if(
moveDirection.0)
            
moveStatus isWalking "walking" "running";
        if(
moveDirection.0)
            
moveStatus isWalking "backwalking" "backrunning";        
        if(
moveDirection.0)
            
moveStatus isWalking "sidewalking_r" "siderunning_r";
        if(
moveDirection.0)
            
moveStatus isWalking "sidewalking_l" "siderunning_l";    
        
        
//movestatus swim movement (for animations)              
        
if(swimming){
            if((
moveDirection.== ) && (moveDirection.== 0))
                
moveStatus "swimidle";            
            if(
moveDirection.0)
                
moveStatus isWalking "swim" "swimfast";
            if(
moveDirection.0)
                
moveStatus isWalking "backswim" "backswimfast";        
            if(
moveDirection.0)
                
moveStatus isWalking "sideswim_r" "sideswimfast_r";
            if(
moveDirection.0)
                
moveStatus isWalking "sidewswim_l" "sideswimfast_l";    
            if(
jumping)
                
moveStatus "swimup";                    
        }  
        
        
//transform direction
        
moveDirection transform.TransformDirection(moveDirection);        

    }
    
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    
if(Input.GetMouseButton(1)) {
        
transform.rotation Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    } else {
        
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed Time.deltaTime0);
    }

    
//Apply gravity
    
moveDirection.-= gravity Time.deltaTime;
    
    
//Move controller
    
var controller:CharacterController GetComponent(CharacterController);
    var 
flags controller.Move(moveDirection Time.deltaTime);
    
grounded = (flags CollisionFlags.Below) != 0;
    
    
//Reset jumping after landing
    
jumping grounded false jumping;

    
//movestatus jump/swimup (for animations)      
    
if(jumping)
        
moveStatus "jump";
    if(
jumping && swimming)
        
moveStatus "swimup";

CharacterControllercs.cs (CSharp) V2.2 old
/// <summary>
/// Charactercontrollercs.cs
/// Character Controller in CSharp v2.2
/// </summary>
using UnityEngine;

public class 
CharacterControllercs MonoBehaviour {
            
    
//Var definition
    
public bool swimming false;                    //Can be triggert to slow down the movements (like when u swim)
    
public string moveStatus "idle";                //movestatus for animations
    
    //Movement speeds
    
private float jumpSpeed 8.0f;                    //Jumpspeed / Jumpheight
    
private float gravity 20.0f;                    //Gravity for jump
    
private float runSpeed 10.0f;                    //Speed when the Character is running
    
private float walkSpeed 4.0f;                    //Speed when the Character is walking (normal movement)
    
private float rotateSpeed 250.0f;                //Rotationspeed of the Character
    
private float walkBackMod 0.75f;                //Speed in Percent for walk backwards and sidewalk
    
    //Internal vars to work with
    
private float speedMod 0.0f;                    //temp Var for Speedcalculation
    
private bool grounded false;                    //temp var if the character is grounded
    
private Vector3 moveDirection Vector3.zero;    //move direction of the Character
    
private bool isWalking false;                    //toggle var between move and run
    
private bool jumping false;                    //temp var for jumping
    
private bool mouseSideButton false;            //temp var for mouse side buttons
    
private float pbuffer 0.0f;                    //Cooldownpuffer for SideButtons
    
private float coolDown 0.5f;                   //Cooldowntime for SideButtons
    
private CharacterController controller;            //CharacterController for movement
    
    //Every Frame
    
void Update ()
    {
        
//Set idel animation
        
moveStatus "idle";
        
isWalking true;
            
        
// Hold "Run" to run
        
if(Input.GetAxis("Run") != 0)
            
isWalking false;
        
        
// Only allow movement and jumps while grounded
        
if(grounded) {
            
            
//movedirection
            
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
            
            
//pushbuffer to avoid on/off flipping
            
if(pbuffer>0)
                
pbuffer -=Time.deltaTime;
            if(
pbuffer<0)pbuffer=0;
                           
            
//Automove Sidebuttonmovement
            
if((Input.GetAxis("Toggle Move") !=0) && pbuffer == 0){
                
pbuffer=coolDown;
                
mouseSideButton = !mouseSideButton;
            }
            if(
mouseSideButton && ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump")) || (Input.GetMouseButton(0) && Input.GetMouseButton(1)))
                
mouseSideButton false;            
            
            
//L+R MouseButton Movement
            
if (Input.GetMouseButton(0) && Input.GetMouseButton(1) || mouseSideButton)
                
moveDirection.+= 1;
            
            
//Strafing move (like Q/E movement    
            
moveDirection.-= Input.GetAxis("Strafing");
                
              
// if moving forward and to the side at the same time, compensate for distance
              
if(Input.GetMouseButton(1) && (Input.GetAxis("Horizontal") != 0) && (Input.GetAxis("Vertical") != 0)) {
                
moveDirection *= 0.7f;
              }
                              
            
//Speedmodification / is moving forward or side/backward
            
speedMod = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1) && (Input.GetAxis("Horizontal")) != 0) || Input.GetAxis("Strafing") != 0) ? walkBackMod 1.0f;
            
            
//Use run or walkspeed
            
moveDirection *= isWalking walkSpeed speedMod runSpeed speedMod;
            
            
//reduce movement by 70% when swimming is toggled   
            
moveDirection*= swimming 0.7f 1;
                      
            
// Jump!
            
if(Input.GetButton("Jump")){
                
jumping true;
                
moveDirection.jumpSpeed;
            }
            
            
//movestatus normal movement (for animations)              
            
if((moveDirection.== ) && (moveDirection.== 0))
                
moveStatus "idle";            
            if(
moveDirection.0)
                
moveStatus isWalking "walking" "running";
            if(
moveDirection.0)
                
moveStatus isWalking "backwalking" "backrunning";        
            if(
moveDirection.0)
                
moveStatus isWalking "sidewalking_r" "siderunning_r";
            if(
moveDirection.0)
                
moveStatus isWalking "sidewalking_l" "siderunning_l";    
            
            
//movestatus swim movement (for animations)              
            
if(swimming){
                if((
moveDirection.== ) && (moveDirection.== 0))
                    
moveStatus "swimidle";            
                if(
moveDirection.0)
                    
moveStatus isWalking "swim" "swimfast";
                if(
moveDirection.0)
                    
moveStatus isWalking "backswim" "backswimfast";        
                if(
moveDirection.0)
                    
moveStatus isWalking "sideswim_r" "sideswimfast_r";
                if(
moveDirection.0)
                    
moveStatus isWalking "sidewswim_l" "sideswimfast_l";    
                if(
jumping)
                    
moveStatus "swimup";                    
            }  
            
            
//transform direction
            
moveDirection transform.TransformDirection(moveDirection);        
        
        }
        
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
        
if(Input.GetMouseButton(1)) {
            
transform.rotation Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
        } else {
            
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed Time.deltaTime0);
        }
        
        
//Apply gravity
        
moveDirection.-= gravity Time.deltaTime;
        
        
//Get CharacterController
        
controller GetComponent<CharacterController>();
        
//Move Charactercontroller and check if grounded
        
grounded = ((controller.Move(moveDirection Time.deltaTime)) & CollisionFlags.Below) != 0;
        
        
//Reset jumping after landing
        
jumping grounded false jumping;
        
        
//movestatus jump/swimup (for animations)      
        
if(jumping)
            
moveStatus "jump";
        if(
jumping && swimming)
            
moveStatus "swimup";    
    }