Search Unity

WOW Camera Movement

Discussion in 'Scripting' started by matrix211v1, Jan 20, 2009.

  1. Flapman

    Flapman

    Joined:
    Aug 15, 2010
    Posts:
    84
    Actually, I am not interested in learning coding. I just need to get pieces together that work so I can put together a demo to pitch.

    When I have more interest and financial support, I can get more of what I need (eg. programmers). :)

    A
     
  2. mikeydoodz49

    mikeydoodz49

    Joined:
    Dec 14, 2009
    Posts:
    24
    Hey guys and gals,


    Sorry if this has been answered already, but I'm having some issues here.

    You see, I'm using what Vimalakirti posted (albeit with some modifications, like Debug.DrawLines and whatnot). The scripts work really well, until I sped up the movement speed of my character. So here's my test scenario:
    1. i walk backwards towards a wall
    2. camera then detects the wall via Physics.Linecast, then readjusts accordingly
    3. I now run forward.

    Glitch now happens on step 3. The screen flickers wildly while the Physics.Linecast is in effect. Now, when I simply walk forward (meaning a slower move speed), then glitch from step3 is non-existent.

    Since I'm still having some problems with this issue (and I'm also coding for other stuff for our games), I was wondering if anyone was able to solve this.

    Thanks for the help in advance! :D
     
  3. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
  4. mikeydoodz49

    mikeydoodz49

    Joined:
    Dec 14, 2009
    Posts:
    24
    oooh. Will give it a go, sir. :D

    Mange Tak (am I saying it right?)
     
  5. kingdutka

    kingdutka

    Joined:
    Feb 1, 2011
    Posts:
    129
    Just a quick question:
    Ever since I started using these scripts, I noticed I am getting some "camera shake" when my player lands from jumping or falling even very short distances. How can I disable the screen shake completely?
     
  6. Roughrider

    Roughrider

    Joined:
    Jul 17, 2011
    Posts:
    73
    Spectacular scripts folks - the sheer amount of talent here is amazing... Hippo - don't chew my ass, even though I deserve it... but...

    How in the name of Hade's bungholio do we kill the camera turn when in first person mode? Or better yet, how do we limit its range so we cannot rotate our head all the way around like the exorcist? :)

    (I know the heads not moving just the camera - though every time I do it, I'm waiting for pea soup to fly all over my screen).

    I'm using cilmeron's camera code:
    Code (csharp):
    1. var target : Transform;
    2. var targetHeight = 2.0;
    3. var distance = 2.8;
    4. var maxDistance = 10;
    5. var minDistance = 0.5;
    6. var xSpeed = 250.0;
    7. var ySpeed = 120.0;
    8. var yMinLimit = -40;
    9. var yMaxLimit = 80;
    10. static var camactive = true;
    11. var zoomRate = 20;
    12. var rotationDampening = 3.0;
    13. private var x = 0.0;
    14. private var y = 0.0;
    15. static var underwater:boolean = false;
    16. var isTalking:boolean = false;
    17.  
    18. @script AddComponentMenu("Camera-Control/WoW Camera")
    19.  
    20. function Start () {
    21.     var angles = transform.eulerAngles;
    22.     x = angles.y;
    23.     y = angles.x;
    24.  
    25.    // Make the rigid body not change rotation
    26.       if (rigidbody)
    27.       rigidbody.freezeRotation = true;
    28. }
    29.  
    30. function Update() {
    31. if(underwater == true)
    32.    {
    33.       color = Color (56.0, 166.0, 198.0, 122.0);        
    34.       RenderSettings.fogColor = color;
    35.       RenderSettings.fogDensity = 0.1;
    36.    }
    37.    
    38.    
    39.    
    40.    }
    41.  
    42. function LateUpdate () {
    43.    if(!target)
    44.       return;
    45.    
    46.    if (Input.GetButtonDown("Camera")){
    47.     camactive = !camactive;
    48.    }
    49.    // If either mouse buttons are down, let them govern camera position
    50.    
    51.    if(camactive == true){
    52.    if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))){
    53.    x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    54.    y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    55.    
    56.    
    57.    // otherwise, ease behind the target if any of the directional keys are pressed
    58.    } else if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")) {
    59.       var targetRotationAngle = target.eulerAngles.y;
    60.       var currentRotationAngle = transform.eulerAngles.y;
    61.       x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    62.      
    63.     }
    64.     }
    65.     else{
    66.     if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))){
    67.    x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    68.    y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    69.    
    70.    
    71.    // otherwise, ease behind the target if any of the directional keys are pressed
    72.    }
    73.    }
    74.    
    75.      
    76.  
    77.    distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
    78.    distance = Mathf.Clamp(distance, minDistance, maxDistance);
    79.    
    80.    y = ClampAngle(y, yMinLimit, yMaxLimit);
    81.    
    82.   // ROTATE CAMERA:
    83.    var rotation:Quaternion = Quaternion.Euler(y, x, 0);
    84.    transform.rotation = rotation;
    85.    
    86.    // POSITION CAMERA:
    87.    var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0));
    88.    transform.position = position;
    89.    
    90.    // IS VIEW BLOCKED?
    91.     var hit : RaycastHit;
    92.     var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
    93.    // Cast the line to check:
    94.     if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {
    95.       // If so, shorten distance so camera is in front of object:
    96.       var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28;
    97.       // Finally, rePOSITION the CAMERA:
    98.       position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0));
    99.       transform.position = position;
    100.    }
    101. }
    102.  
    103. static function ClampAngle (angle : float, min : float, max : float) {
    104.    if (angle < -360)
    105.       angle += 360;
    106.    if (angle > 360)
    107.       angle -= 360;
    108.    return Mathf.Clamp (angle, min, max);
    109.    
    110. }
    Thanks in advance to the super smart coder nerdy types that have made this thread the best on the Unity forums!

    -RR
     
    Last edited: Aug 10, 2011
  7. rahulkathet

    rahulkathet

    Joined:
    Aug 19, 2011
    Posts:
    6
    I am having problem with 2 cameras movement I want both camera should work at a time but with different-2 location one for the front and another for the top view, I have done split screen i can see both the view but If i am giving this script (transform.LookAt(stagemc.position)

    both the cameras are moving same side, I want to move different-2 location as I said before, if there is any help thanks in advance :)

    --
    Rahul Kathet
     
  8. Azaldur

    Azaldur

    Joined:
    Jul 10, 2011
    Posts:
    52
    I tried the ThirdPersonMMOController but the camera goes through walls. How can I prevent it from doing so?
     
  9. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    On the camera controller component, you can set up which layers are obstacles. Put your walls in one of these layers.
     
  10. Spence89

    Spence89

    Joined:
    Jul 13, 2011
    Posts:
    51
    Hi all,

    I love the camera and controller scripts, but I wondered if anyone could help me?

    I currently have the scripts posted in this thread, they work absolutely fine and I have no problems, but can someone tell me how I would go about making my character move with both mouse buttons held down, while at the same time steering him with the mouse?

    @ cilmeron

    I have tried to implement your swimming script into my water3, but unfortunately I get loads of compiler errors. Any help would be appreciated!!!

    THANKS ALL! :)

    Camera Script
    Code (csharp):
    1. var target : Transform;
    2. var targetHeight = 2.0;
    3. var distance = 2.8;
    4. var maxDistance = 10;
    5. var minDistance = 0.5;
    6. var xSpeed = 250.0;
    7. var ySpeed = 1000.0;
    8. var yMinLimit = -40;
    9. var yMaxLimit = 80;
    10. var zoomRate = 20;
    11. var rotationDampening = 3.0;
    12. private var x = 0.0;
    13. private var y = 0.0;
    14. var isTalking:boolean = false;
    15.  
    16. @script AddComponentMenu("Camera-Control/WoW Camera")
    17.  
    18. function Start () {
    19.     var angles = transform.eulerAngles;
    20.     x = angles.y;
    21.     y = angles.x;
    22.  
    23.    // Make the rigid body not change rotation
    24.       if (rigidbody)
    25.       rigidbody.freezeRotation = true;
    26. }
    27.  
    28. function LateUpdate () {
    29.    if(!target)
    30.       return;
    31.    
    32.    // If either mouse buttons are down, let them govern camera position
    33.    if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))){
    34.    x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    35.    y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    36.    
    37.    
    38.    // otherwise, ease behind the target if any of the directional keys are pressed
    39.    } else if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")) {
    40.       var targetRotationAngle = target.eulerAngles.y;
    41.       var currentRotationAngle = transform.eulerAngles.y;
    42.       x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    43.     }
    44.      
    45.  
    46.    distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
    47.    distance = Mathf.Clamp(distance, minDistance, maxDistance);
    48.    
    49.    y = ClampAngle(y, yMinLimit, yMaxLimit);
    50.    
    51.   // ROTATE CAMERA:
    52.    var rotation:Quaternion = Quaternion.Euler(y, x, 0);
    53.    transform.rotation = rotation;
    54.    
    55.    // POSITION CAMERA:
    56.    var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0));
    57.    transform.position = position;
    58.    
    59.     // IS VIEW BLOCKED?
    60.     var hit : RaycastHit;
    61.     var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
    62.     // Cast the line to check:
    63.     if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
    64.         // If so, shorten distance so camera is in front of object:
    65.         var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28;
    66.         // Finally, rePOSITION the CAMERA:
    67.         position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0));
    68.         transform.position = position;
    69.     }
    70. }
    71.  
    72. static function ClampAngle (angle : float, min : float, max : float) {
    73.    if (angle < -360)
    74.       angle += 360;
    75.    if (angle > 360)
    76.       angle -= 360;
    77.    return Mathf.Clamp (angle, min, max);
    78.    
    79. }
    Controller Script
    Code (csharp):
    1. // Movement Variables:
    2. var jumpSpeed:float = 9.0;
    3. private var gravity:float = 20.0;
    4. static var runSpeed:float = 5.0;
    5. static var swimSpeed:float = 2.0;
    6. static var walkSpeed:float = 2;
    7. static var runSpeedsave = 5.0;
    8. static var walkSpeedsave = 2;
    9. static var curSpeed:float = 0.0;
    10. private var rotateSpeed:float = 150.0;
    11. private var grounded:boolean = false;
    12. private var moveDirection:Vector3 = Vector3.zero;
    13. static var isWalking:boolean = false;
    14. private var moveStatus:String = "idle";
    15. private var xSpeed = 250.0;
    16. private var ySpeed = 120.0;
    17. private var yMinLimit = -40;
    18. private var yMaxLimit = 80;
    19. private var x = 0.0;
    20. private var y = 0.0;
    21. static var ddistance:float = 0.0;
    22. static var strafemod:Vector3 = Vector3.zero;
    23. static var strafing = false;
    24. static var animationspeed = 1.0;
    25. var hit : RaycastHit;
    26. static var isSwimming = false;
    27. static var bmove = false;
    28. static var bSpeed = 0.0;
    29.  
    30.  
    31. //UPDATE
    32. //
    33.    
    34. function Update ()
    35. //check if we fell down the world and teleport to a specific location
    36. {
    37. if(transform.position.y < -200)
    38.     {
    39.         transform.position.y = 16.07609;
    40.         transform.position.x = 579.2826;
    41.         transform.position.z = 130.8261;
    42.     }
    43.  
    44. //Move controller
    45. var controller:CharacterController = GetComponent(CharacterController);
    46. var flags = controller.Move(moveDirection * Time.deltaTime);
    47. grounded = (flags  CollisionFlags.Below) != 0; 
    48.  
    49. //check if we're moving backwards
    50.    if(Input.GetAxis("Vertical") < 0){
    51.    bmove = true;
    52.    }
    53.    else{
    54.    bmove = false;
    55.    }
    56. //check if we're swimming
    57. if(isSwimming == true){
    58. swimSpeed = runSpeed/2;
    59.    //reduce speed when moving backwards
    60.      if(bmove == true){
    61.          if(bSpeed > 0){
    62.      bSpeed = bSpeed;
    63.      }
    64.      else{
    65.      bSpeed = swimSpeed;
    66.      swimSpeed = bSpeed * 0.6;
    67.      }
    68.      }
    69.    else{
    70.      if(bSpeed > 0){
    71.      swimSpeed = bSpeed;
    72.      bSpeed = 0.0;
    73.      }
    74.      }
    75.        
    76.       moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
    77.       if(Input.GetMouseButton(1)  Input.GetAxis("Vertical")  Input.GetAxis("Horizontal")) {
    78.          moveDirection *= .7;
    79.          }
    80.     animationspeed = runSpeed/4;
    81.     moveDirection = transform.TransformDirection(moveDirection);
    82.     moveDirection *= swimSpeed;
    83.        
    84.      moveStatus = "swim_idle";
    85.       if(moveDirection != Vector3.zero) {
    86.         moveStatus = "swimming";
    87. //invoke swim animation here        
    88. }
    89.       else {
    90. //swim idle animation
    91.       }
    92.       // Jump (or rather dive upwards)!
    93.       if(Input.GetButton("Jump"))
    94.       {
    95.          // call JUMP animation here
    96.          moveDirection.y = swimSpeed*1.6;
    97.       }
    98.    
    99.    // Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    100.    if(Input.GetMouseButton(1)) {
    101.       transform.rotation = Quaternion.Euler(Camera.main.transform.eulerAngles.x,Camera.main.transform.eulerAngles.y,0);
    102.    }
    103.    else {
    104.      transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    105.    }
    106.    //simple strafing
    107.    //now let's do the quick check if we're walking or running
    108.    //walking goes here
    109.    //left strafe button is pressed -> strafe to the left
    110.    if (Input.GetButton("Strafel")){
    111.    strafemod = new Vector3(-1, 0, 0);
    112.    strafemod = transform.TransformDirection(strafemod);
    113.    strafemod = swimSpeed * strafemod;
    114.    controller.Move (strafemod * Time.deltaTime);
    115.    }
    116. //right strafe button is pressed -> strafe to the right
    117. if (Input.GetButton("Strafer")){
    118.    strafemod = new Vector3(1, 0, 0);
    119.    strafemod = transform.TransformDirection(strafemod);
    120.    strafemod = swimSpeed * strafemod;
    121.    controller.Move (strafemod * Time.deltaTime);
    122.    }
    123.    }
    124.    else{
    125.  
    126. //check if we're moving
    127.    if(Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || Input.GetButton("StrafeL") || Input.GetButton("StrafeR")){
    128.    if(isWalking == true){
    129.    curSpeed = walkSpeed;
    130.    }
    131.    else{
    132.    curSpeed = runSpeed;
    133.    }
    134.    }
    135.    else{
    136.    curSpeed = 0.0;
    137.  
    138. //since the backward slowing can have some permanent effects to our runSpeed and walkSpeed (i.e. the speed will stick to 60%) here's some failsave code making use of the run/walk Speedsave variables
    139.      
    140.    if(runSpeed < runSpeedsave){
    141.    runSpeed = runSpeedsave;
    142.    }
    143.    
    144.  
    145.    if(walkSpeed < walkSpeedsave){
    146.    walkSpeed = walkSpeedsave;
    147.    }
    148.    }
    149.  
    150.    
    151.    //reduce speed when moving backwards
    152.    if(isWalking == true){
    153.    
    154.    if(bmove == true){
    155.         if(bSpeed > 0){
    156.         bSpeed = bSpeed;
    157.         }
    158.         else{
    159.         bSpeed = walkSpeed;
    160.         walkSpeed = bSpeed * 0.6;
    161.         }
    162.                             }
    163.    else{
    164.         if(bSpeed > 0){
    165.         walkSpeed = bSpeed;
    166.         bSpeed = 0.0;
    167.         }
    168.     }
    169.     }
    170.    else{
    171.     if(bmove == true){
    172.    if(bSpeed > 0){
    173.    bSpeed = bSpeed;
    174.    }
    175.    else{
    176.    bSpeed = runSpeed;
    177.    runSpeed = bSpeed * 0.6;
    178.    }
    179.    }
    180.    else{
    181.    if(bSpeed > 0){
    182.    runSpeed = bSpeed;
    183.    bSpeed = 0.0;
    184.    }
    185.    }
    186.    }
    187.    
    188.    //check if we're moving - if we're moving track distance and save to ddistance
    189.    if(curSpeed > 0){
    190.    ddistance = ddistance + (curSpeed * Time.deltaTime);
    191.    }
    192.    //
    193.    // Only allow movement and jumps while -----------------  GROUNDED -------------
    194.    
    195.    if(grounded) {
    196.    moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
    197.       if(Input.GetMouseButton(1)  Input.GetAxis("Vertical")  Input.GetAxis("Horizontal")) {
    198.          moveDirection *= .7;
    199.          }
    200.     animationspeed = runSpeed/4;
    201.     moveDirection = transform.TransformDirection(moveDirection);
    202.       moveDirection *= isWalking ? walkSpeed : runSpeed;
    203.        
    204.       moveStatus = "idle";
    205.       if(moveDirection != Vector3.zero) {
    206.          moveStatus = isWalking ? "walking" : "running";
    207.          if (isWalking){
    208.            // invoke WALK animation here
    209.          } else {
    210.     // call RUN animation here
    211.          }
    212.       } else {
    213.         // call IDLE animation here
    214.       }
    215.       // Jump!
    216.       if(Input.GetButton("Jump"))
    217.       {
    218.          // call JUMP animation here
    219.          moveDirection.y = jumpSpeed;
    220.       }
    221.     }                  
    222.     // END "IS GROUNDED"
    223.    
    224.    // Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    225.    if(Input.GetMouseButton(1)) {
    226.       transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    227.    }
    228.    else {
    229.      transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    230.    }
    231.    
    232.    // Toggle walking/running with the walk/run key
    233.    if(Input.GetButtonDown("Walk"))
    234.          isWalking = !isWalking;
    235.        
    236.    //Apply gravity
    237.    moveDirection.y -= gravity * Time.deltaTime;
    238.    //Move controller
    239.    //var controller:CharacterController = GetComponent(CharacterController);
    240.    //var flags = controller.Move(moveDirection * Time.deltaTime);
    241.    grounded = (flags  CollisionFlags.Below) != 0;
    242.    
    243.    //simple strafing
    244.    //now let's do the quick check if we're walking or running
    245.    //walking goes here
    246.    if(isWalking == true){
    247.    //left strafe button is pressed -> strafe to the left
    248.    if (Input.GetButton("StrafeL")){
    249.    strafemod = new Vector3(-1, 0, 0);
    250.    strafemod = transform.TransformDirection(strafemod);
    251.    strafemod = walkSpeed * strafemod;
    252.    controller.Move (strafemod * Time.deltaTime);
    253.    }
    254. //right strafe button is pressed -> strafe to the right
    255. if (Input.GetButton("StrafeR")){
    256.    strafemod = new Vector3(1, 0, 0);
    257.    strafemod = transform.TransformDirection(strafemod);
    258.    strafemod = walkSpeed * strafemod;
    259.    controller.Move (strafemod * Time.deltaTime);
    260.    }
    261.  
    262.    }
    263.    //running goes here
    264.    else{
    265.    //left strafe button is pressed -> strafe to the left
    266. if (Input.GetButton("StrafeL")){
    267.    strafemod = new Vector3(-1, 0, 0);
    268.    strafemod = transform.TransformDirection(strafemod);
    269.    strafemod = runSpeed * strafemod;
    270.    controller.Move (strafemod * Time.deltaTime);
    271.    }
    272.   //left strafe button is pressed -> strafe to the right
    273. if (Input.GetButton("StrafeR")){
    274.    strafemod = new Vector3(1, 0, 0);
    275.    strafemod = transform.TransformDirection(strafemod);
    276.    strafemod = runSpeed * strafemod;
    277.    controller.Move (strafemod * Time.deltaTime);
    278.    }  
    279.    }
    280.    }
    281.    };
    282.    
    283.    static function ClampAngle (angle : float, min : float, max : float) {
    284.    if (angle < -360)
    285.       angle += 360;
    286.    if (angle > 360)
    287.       angle -= 360;
    288.    return Mathf.Clamp (angle, min, max);
    289. }
    290.  
    291.  
    292. // -------------------------------------------------------------------------------------------------------------
    293. // ----------------------------------------------------------- END UPDATE  --------------------------------
    294. // -------------------------------------------------------------------------------------------------------------
    295.  
    296. @script RequireComponent(CharacterController)
    Adam.
     
  11. Spence89

    Spence89

    Joined:
    Jul 13, 2011
    Posts:
    51
    Anyone? Please? :)
     
  12. Wikened

    Wikened

    Joined:
    Oct 31, 2011
    Posts:
    271
    I think it would be something like:

    if(Input.GetMouseButton(1) + Input.GetMouseButton(2))
    {
    // Your code in here.
    }
     
  13. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
  14. Aohct

    Aohct

    Joined:
    Nov 4, 2011
    Posts:
    4
    Hi Everyone!

    I've also been making a WoW camera-character system! Seems that it's becoming popular (I have plenty of theories on that, although they boil down to how nice WoW's system is mainly). Anyway, here's my crack at it:

    Apply this to the camera:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CameraControl : MonoBehaviour
    6. {
    7.     public GlobalValues.Seperate CameraHeight;
    8.     //change camera height (left-click and mouse y)
    9.     public float MinHeight = 0;
    10.     public float MaxHeight = 0.95f;
    11.     public float HeightSensitivity = 4;
    12.     private float TargetHeight
    13.     {
    14.         get { return _tH; }
    15.         set { _tH = Mathf.Clamp(value, MinHeight, MaxHeight); }
    16.     }
    17.     private float _tH = 5;
    18.  
    19.     public GlobalValues.Seperate CameraZoom;
    20.     //change camera zoom (scroll wheel)
    21.     public float MaxZoom = 10;
    22.     public float MinZoom = 0.1f;
    23.     public float ZoomSensitivity = 4;
    24.     private float TargetZoom
    25.     {
    26.         get { return _tZ; }
    27.         set { _tZ = Mathf.Clamp(value, MinZoom, MaxZoom); }
    28.     }
    29.     private float _tZ = 5;
    30.  
    31.     public GlobalValues.Seperate CameraRotation;
    32.     //change camera rotation (left-click and mouse x)
    33.     public float RotateSensitivity = 4;
    34.     public float RotateBackLerp = 10;
    35.     //angle of the character
    36.     private static float CharacterAngle { get { return RegulateAngle(GlobalValues.CharacterTransform.rotation.eulerAngles.y); } }
    37.     //angle of the camera
    38.     private static Quaternion CameraAngle { get { return Quaternion.Euler(0, GlobalValues.CameraTransform.rotation.eulerAngles.y, 0); } }
    39.     //angle of the camera (left-click)
    40.     private float CustomRotation
    41.     {
    42.         get { return _cR; }
    43.         set { _cR = RegulateAngle(value); }
    44.     }
    45.     private float _cR;
    46.  
    47.     void Start()
    48.     {
    49.         GlobalValues.CameraTransform = transform;
    50.     }
    51.  
    52.     // Update is called once per frame
    53.     void LateUpdate()
    54.     {
    55.         if (GlobalValues.CharacterTransform == null) return;
    56.  
    57.         //obtain axis
    58.         GlobalValues.LeftClickAxis = Input.GetAxis(GlobalValues.LeftMouse);
    59.         GlobalValues.RightClickAxis = Input.GetAxis(GlobalValues.RightMouse);
    60.         GlobalValues.MouseAxisX = Input.GetAxis(GlobalValues.MouseX);
    61.         GlobalValues.MouseAxisY = Input.GetAxis(GlobalValues.MouseY);
    62.         GlobalValues.ScrollWheelAxis = Input.GetAxis(GlobalValues.ScrollWheel);
    63.  
    64.  
    65.         TargetZoom -= GlobalValues.ScrollWheelAxis * ZoomSensitivity;
    66.         Vector3 heightPoint = new Vector3(0, TargetHeight, 1 - TargetHeight).normalized * TargetZoom;
    67.  
    68.         if (GlobalValues.RightClickAxis > 0)
    69.         {
    70.             Debug.Log("look" + CameraAngle);
    71.             GlobalValues.CharacterTransform.LookAt(GlobalValues.CharacterTransform.position + (CameraAngle * Vector3.forward));
    72.             CustomRotation = 0;
    73.         }
    74.         if (GlobalValues.RightClickAxis == 0  GlobalValues.LeftClickAxis == 0)
    75.         {
    76.             //if not locking (left-click) and moving, then slowly shape camera back
    77.             if (GlobalValues.CharacterRigid.velocity.sqrMagnitude > 0) CustomRotation = Mathf.Lerp(CustomRotation, 0, Time.deltaTime * RotateBackLerp);
    78.         }
    79.         else
    80.         {
    81.             //note: unusable feature, disable mouse position while moving
    82.             TargetHeight -= GlobalValues.MouseAxisY * HeightSensitivity;
    83.             CustomRotation += GlobalValues.MouseAxisX * RotateSensitivity;
    84.         }
    85.         GlobalValues.CameraTransform.position = GlobalValues.CharacterTransform.position + (Quaternion.Euler(0, CharacterAngle + CustomRotation + 180, 0) * heightPoint);
    86.         GlobalValues.CameraTransform.LookAt(GlobalValues.CharacterTransform);
    87.     }
    88.  
    89.     private static float RegulateAngle(float value)
    90.     {
    91.         if (value < -360) return value + 360;
    92.         if (value > 360) return value - 360;
    93.         return value;
    94.     }
    95. }
    96.  
    97.  
    And apply this to a capsule collider with a rigidbody (NO CHARACTER CONTROLLER!! Yuck)

    Code (csharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5.  
    6. public class CharacterControl : MonoBehaviour
    7. {
    8.     public GlobalValues.Seperate MovementSpeed;
    9.     //moving forwards and backwards
    10.     public float ForwardSpeed = 10;
    11.     public float BackwardSpeed = 5;
    12.     public float AerialLerpModifier = 2;
    13.     public float MovementLerpSpeed = 0.5f;
    14.     private bool _backPedaling;
    15.  
    16.     public GlobalValues.Seperate RotatingSpeed;
    17.     //moving left and right turning left and right
    18.     public float RotationSpeed = 0.05f;
    19.  
    20.     public GlobalValues.Seperate Gravity;
    21.     public Vector3 GravityDrop = new Vector3(0, -0.3f, 0);
    22.     public float MaximumGravity = 20;
    23.     public bool IsGrounded;
    24.  
    25.     public GlobalValues.Seperate Jump;
    26.     public float JumpSpeed = 10;
    27.     public float ConsideredFloor = 0.5f;
    28.     public float JumpLerpSpeed = 0.1f;
    29.     private bool _jumpWasPressed;
    30.  
    31.     public Vector3 Velocity;
    32.  
    33.     //on the off hand we need to retain movment (air)
    34.     private Vector3 _currentMovement;
    35.     private Vector3 _currentGravity;
    36.     private bool _hasJumped;
    37.  
    38.     void Start()
    39.     {
    40.         GlobalValues.CharacterTransform = transform;
    41.         GlobalValues.CharacterRigid = rigidbody;
    42.         GlobalValues.CharacterRigid.freezeRotation = true;
    43.         GlobalValues.CharacterRigid.useGravity = false;
    44.     }
    45.     void OnCollisionStay(Collision other)
    46.     {
    47.         IsGrounded = false;
    48.         foreach (ContactPoint contact in other.contacts)
    49.         {
    50.             if (contact.normal.y < ConsideredFloor) continue;
    51.             IsGrounded = true;
    52.         }
    53.     }
    54.     void OnCollisionExit(Collision other)
    55.     {
    56.         IsGrounded = false;
    57.     }
    58.  
    59.     void Update()
    60.     {
    61.         GlobalValues.ForwardAxis = Input.GetAxis(GlobalValues.MoveForward);
    62.         GlobalValues.BackwardAxis = Input.GetAxis(GlobalValues.MoveBackward);
    63.         GlobalValues.StrafeAxis = Input.GetAxis(GlobalValues.Strafing);
    64.         GlobalValues.TurningAxis = Input.GetAxis(GlobalValues.Turning);
    65.  
    66.         //is a button (if prev state pressed)
    67.         _jumpWasPressed = GlobalValues.JumpAxis > 0;
    68.         GlobalValues.JumpAxis = Input.GetAxis(GlobalValues.Jump);
    69.  
    70.         Quaternion currentRotation = GlobalValues.CharacterTransform.rotation;
    71.  
    72.         _currentMovement = Vector3.zero;
    73.         //not back pedaling
    74.         _backPedaling = false;
    75.  
    76.         //forward by mouse
    77.         if (GlobalValues.LeftClickAxis > 0  GlobalValues.RightClickAxis > 0)
    78.         {
    79.             _currentMovement += currentRotation * Vector3.forward;
    80.         }
    81.         else if (GlobalValues.ForwardAxis > 0)
    82.         {
    83.             //if moving forward
    84.             _currentMovement += currentRotation * Vector3.forward;
    85.         }
    86.         if (GlobalValues.BackwardAxis > 0)
    87.         {
    88.             _backPedaling = true;
    89.             _currentMovement += currentRotation * Vector3.back;
    90.         }
    91.  
    92.         //if strafing
    93.         if (GlobalValues.StrafeAxis != 0)
    94.         {
    95.             if (GlobalValues.StrafeAxis > 0)
    96.             {
    97.                 _currentMovement += currentRotation * Vector3.right;
    98.             }
    99.             else
    100.             {
    101.                 _currentMovement += currentRotation * Vector3.left;
    102.             }
    103.         }
    104.         //apply final direction
    105.         _currentMovement = _currentMovement.normalized * (_backPedaling ? BackwardSpeed : ForwardSpeed);
    106.         //if in air, we have little control over overall direction
    107.         if (!IsGrounded)
    108.         {
    109.             _currentMovement = Vector3.Lerp(GlobalValues.CharacterRigid.velocity, _currentMovement, Time.deltaTime * AerialLerpModifier);
    110.         }
    111.  
    112.         //if turning
    113.         if (GlobalValues.TurningAxis != 0)
    114.         {
    115.             if (GlobalValues.TurningAxis > 0)
    116.             {
    117.                 Debug.Log("turning");
    118.                 GlobalValues.CharacterTransform.RotateAround(Vector3.up, RotationSpeed);
    119.             }
    120.             else
    121.             {
    122.                 GlobalValues.CharacterTransform.RotateAround(Vector3.up, -RotationSpeed);
    123.  
    124.             }
    125.         }
    126.  
    127.         //if jumping
    128.         if (!_jumpWasPressed  GlobalValues.JumpAxis > 0)
    129.         {
    130.             if (IsGrounded || !IsGrounded)
    131.             {
    132.                 _hasJumped = true;
    133.             }
    134.         }
    135.         if (IsGrounded)
    136.         {
    137.             _currentGravity = Vector3.zero;
    138.         }
    139.         else
    140.         {
    141.             _currentGravity += GravityDrop;
    142.         }
    143.     }
    144.     void FixedUpdate()
    145.     {
    146.         float airVelocity = Mathf.Lerp(GlobalValues.CharacterRigid.velocity.y, _currentGravity.y, JumpLerpSpeed);
    147.         if (_hasJumped)
    148.         {
    149.             _hasJumped = false;
    150.             airVelocity += JumpSpeed;
    151.         }
    152.         if (airVelocity < -MaximumGravity) airVelocity = -MaximumGravity;
    153.         GlobalValues.CharacterRigid.velocity = new Vector3(_currentMovement.x, airVelocity, _currentMovement.z);
    154.         Velocity = GlobalValues.CharacterRigid.velocity;
    155.     }
    156. }
    157.  
    And finally have this in your project (don't apply it anywhere):
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GlobalValues
    5. {
    6.     public enum Seperate
    7.     {
    8.         ___________
    9.     }
    10.  
    11.  
    12.     public static Transform CharacterTransform;
    13.     public static Rigidbody CharacterRigid;
    14.     public static Transform CameraTransform;
    15.  
    16.     public const string MoveForward = "MoveForward";
    17.     public static float ForwardAxis;
    18.     public const string MoveBackward = "MoveBackward";
    19.     public static float BackwardAxis;
    20.  
    21.     public const string Strafing = "Strafing";
    22.     public static float StrafeAxis;
    23.     public const string Turning = "Turning";
    24.     public static float TurningAxis;
    25.     public const string Jump = "Jump";
    26.     public static float JumpAxis;
    27.  
    28.     //accessed by character controls (moving forward) AND camera
    29.     public const string LeftMouse = "LeftMouse";
    30.     public static float LeftClickAxis;
    31.     public const string RightMouse = "RightMouse";
    32.     public static float RightClickAxis;
    33.  
    34.     public const string MouseX = "MouseX";
    35.     public static float MouseAxisX;
    36.     public const string MouseY = "MouseY";
    37.     public static float MouseAxisY;
    38.     public const string ScrollWheel = "ScrollWheel";
    39.     public static float ScrollWheelAxis;
    40. }
    41.  
    This is all C# of course, I spent around 6-7 hours doing it, but it was worthwhile -- I'm probably going to be doing a 'WoW-like' game. I'll see if I can upload a version soon...
     
  15. Aohct

    Aohct

    Joined:
    Nov 4, 2011
    Posts:
    4
    Web Player stuff is hard -- phew..

    Here is a demo of what the code above does:

    http://andrewakkermans.com/

    Enjoy! (The right click is a bit bugged because it's in a browser, sorry about that)
     
    Last edited: Dec 2, 2011
  16. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Hi Guys.

    Please download the attached package.

    Im able to create up to this level a camera that will rotate / orbit around the object follow it as well , But as ul notice in the camera starts flittering when it goes in to the follow mode.

    Can any one guide me on how to fix this problem, if any one can update and upload the package with the fixes that will be great.

    NOTE :
    1.The camera goes in to the follow mode after u click on the "GUITexture"
    2.You have to restart the Game every time (No Reset sorry).

    Thank you
     

    Attached Files:

  17. pixellegolas

    pixellegolas

    Joined:
    Apr 10, 2011
    Posts:
    223
    Aohct, nice demo! The problem is as you say when you right-click and menu pops up the character has force all the time :)
     
  18. Aohct

    Aohct

    Joined:
    Nov 4, 2011
    Posts:
    4
    Hi Pixellegolas,

    I fixed it up, I had to disable right-click contextual menu in the webplayer version of unity.

    Thanks for pointing that out!
     
  19. MTeles

    MTeles

    Joined:
    Mar 16, 2012
    Posts:
    2
    Hey, everyone. I've converted one of the codes in this thread to C#, and it works on the PC so far. The only problem is, when I test it on the PC in the Unity Editor, it works as it should, but when I load the game into my Android device, the camera follows the target, but does not rotate with it.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Camera_That_Follow : MonoBehaviour
    5. {
    6.     public Transform target;
    7.     public float targetHeight = 1;
    8.     public float distance = 3;
    9.     public float maxDistance = 10;
    10.     public float minDistance = 0.5f;
    11.     public float xSpeed = 250;
    12.     public float ySpeed = 120;
    13.     public float yMinLimit = -40;
    14.     public float yMaxLimit = 80;
    15.     public float zoomRate = 50;
    16.     public float rotationDampening = 15;
    17.     private float x = 0f;
    18.     private float y = 0f;
    19. //    bool isTalking = false;
    20.     public float count;
    21.     //AddComponentMenu("Camera-Control/WoW Camera")
    22.     // Use this for initialization
    23.     void Start ()
    24.     {
    25.         Vector3 angles = transform.eulerAngles;
    26.         x = angles.y;
    27.         y = angles.x;
    28.  
    29.         // Make the Rigid Body not change rotation.
    30.         if (rigidbody)
    31.         {
    32.             rigidbody.freezeRotation = true;
    33.         }
    34.     }
    35.    
    36.     // Update is called once per frame
    37.     void Update ()
    38.     {
    39.    
    40.     }
    41.     void LateUpdate()
    42.     {
    43.         if (!target)
    44.         {
    45.             return;
    46.         }
    47.  
    48.         //If either mouse buttons are down, let them govern camera position
    49.         if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
    50.         {
    51.             x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
    52.             y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
    53.         }
    54.         //Otherwise, ease behind the target if any of the directional keys are pressed.
    55.         else if ((Input.GetAxis("Vertical") != 0f )|| (Input.GetAxis("Horizontal") != 0f))
    56.         {
    57.             float targetRotationAngle = target.eulerAngles.y;
    58.             float currentRotationAngle = transform.eulerAngles.y;
    59.             x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    60.         }
    61.        
    62.         distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
    63.         distance = Mathf.Clamp(distance, minDistance, maxDistance);
    64.  
    65.         y = ClampAngle(y, yMinLimit, yMaxLimit);
    66.  
    67.         //Rotate Camera
    68.         Quaternion rotation = Quaternion.Euler(y, x, 0);
    69.         transform.rotation = rotation;
    70.  
    71.         //Position Camera
    72.         var position = target.position - (rotation * Vector3.forward * distance + new Vector3(0, -targetHeight, 0));
    73.         transform.position = position;
    74.  
    75.         //Is view blocked?
    76.         RaycastHit hit;
    77.         Vector3 trueTargetPosition = target.transform.position - new Vector3(0, -targetHeight, 0);
    78.  
    79.         //Cast the line to check:
    80.         //HAL 2011-jan-23 / make sure its not colliding with the original target
    81.         if (Physics.Linecast(trueTargetPosition, transform.position,out hit)  hit.transform != target)
    82.         {
    83.             count += Time.deltaTime;
    84.  
    85.             //If so, shorten distance so camera is in front of object:
    86.             if (count > 0.9)
    87.             {
    88.                 var tempDistance = Vector3.Distance(trueTargetPosition, hit.point) - 0.28f;
    89.  
    90.                 // Finally reposition the camera:
    91.                 position = target.position - (rotation * Vector3.forward * tempDistance + new Vector3(0, -targetHeight, 0));
    92.                 transform.position = position;
    93.             }
    94.         }
    95.         else
    96.         {
    97.             count = 0;
    98.         }
    99.  
    100.     }
    101.  
    102.     static float ClampAngle(float angle, float min, float max)
    103.     {
    104.         if (angle < -360)
    105.         {
    106.             angle += 360;
    107.         }
    108.         if (angle > 360)
    109.         {
    110.             angle -= 360;
    111.         }
    112.         return Mathf.Clamp(angle, min, max);
    113.     }
    114. }
    115.  
    116. }
    I'd be really glad if anyone could help.
     
    Last edited: Mar 16, 2012
  20. yyyusufyyy

    yyyusufyyy

    Joined:
    Mar 16, 2012
    Posts:
    4
    Aohct im getting this error. how can i fix it ? excuse me, this is my first try to adding a script to my project.
    UCE0001: ';' expected. Insert a semicolon at the end.
     
  21. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    He has an extra } at the end.. remove it and it will compile.
     
  22. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
  23. MTeles

    MTeles

    Joined:
    Mar 16, 2012
    Posts:
    2
    Because it needs the camera to be a child of the followed object, which causes it to do exactly what we are trying to avoid: An "unnatural" camera movement where it is fixed behind the character, instead of rotating and repositioning smoothly to follow the character's movement.
     
  24. yyyusufyyy

    yyyusufyyy

    Joined:
    Mar 16, 2012
    Posts:
    4
    thanks for help but i have done it before, i just paste it as c# and that error gone. but its still not working at all. do you guys know any wow kind camera and person controller script which is working. it has not to be perfect.
     
  25. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I don't mean to be rude but the controller and camera in this example is mostly unusable. Controls are slow and buggy. and suffer from all the normal problems rigidbody character controllers do (sometimes slightly lifting of ground, stuttering). The camera has many missing features (auto follow, smoothing, etc.).
     
  26. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Are those features part of the default world of warcraft camera though? It did not seem so when we tried it out.

    Anywho if that is indeed the case, please file a bug report on the issues so we may update the package.
     
  27. Surtaso

    Surtaso

    Joined:
    Jun 9, 2012
    Posts:
    2
    Aohct's controls are PERFECT (exactly like wow, just without the both mouse left+right making it move forward, which I dont really care)

    but I'm having problems making it work... 1st it asks me to create a bunch of inputs that I couldn't do properly (srry I'm new to c# and unity) and 2nd that every time I try to use a capsule I lose my animations... =(

    here is his example again http://andrewakkermans.com/

    it's exactly how the camera/control should work (instant turning with right mouse - no delays, only camera with left mouse, strafing, auto follow if keyboard turning, perfect!)

    could anyone try to make it easier to implement? or maybe modify some of the absolutely amazing codes above to match his? (in c# would be even better =P) I've been trying to mess around and tweak some stuff from the above but my mostly-only-as3 knowledge is not really helping =/

    you guys are great!
     
  28. hyderox

    hyderox

    Joined:
    Aug 12, 2011
    Posts:
    11
    Aohct's demo is awesome! But i think the scripts in this example are diferent then the scripts he gave. I made the inputs in my project, tried it out but the Camera script was total mad. the camera was showing my character's foot, i couldn't rotate the camera like in the example, if i hit W the character was going in wrong direction. And the Right-Click system isn't working :/ I think it needs some fixes. I'm new to these advanced scripts and movement/camera systems so please tell us how can we use these in our own projects.
     
  29. Idahansen

    Idahansen

    Joined:
    Jul 19, 2012
    Posts:
    1
    Is there a way to stop the left-click moving camera WHILE you are dragging your window rects around your screen. I'm using this code, as it was the best of the .js ones I could find on this thread.

    Movement:

    Code (csharp):
    1. // Movement Variables:
    2.  
    3. private var jumpSpeed:float = 9.0;
    4.  
    5. private var gravity:float = 20.0;
    6.  
    7. private var runSpeed:float = 5.0;
    8.  
    9. private var walkSpeed:float = 4.7;
    10.  
    11. private var rotateSpeed:float = 150.0;
    12.  
    13. private var grounded:boolean = false;
    14.  
    15. private var moveDirection:Vector3 = Vector3.zero;
    16.  
    17. private var isWalking:boolean = true;
    18.  
    19. private var moveStatus:String = "idle";
    20.  
    21. private var xSpeed = 250.0;
    22.  
    23. private var ySpeed = 120.0;
    24.  
    25. private var yMinLimit = -40;
    26.  
    27. private var yMaxLimit = 80;
    28.  
    29. private var x = 0.0;
    30.  
    31. private var y = 0.0;
    32.  
    33.  
    34.  
    35.  
    36.  
    37. // -------------------------------------------------------------------------------------------------------------
    38.  
    39. // ----------------------------------------------------------- UPDATE ---------------------------------------
    40.  
    41. // -------------------------------------------------------------------------------------------------------------
    42.  
    43.  
    44.  
    45. function Update () {
    46.  
    47.    //
    48.  
    49.    // Only allow movement and jumps while -----------------  GROUNDED -------------
    50.  
    51.    if(grounded) {
    52.  
    53.         moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
    54.  
    55.        
    56.  
    57.         // if moving forward and to the side at the same time, compensate for distance
    58.  
    59.         // TODO: may be better way to do this?
    60.  
    61.         if(Input.GetMouseButton(1)  Input.GetAxis("Horizontal")  Input.GetAxis("Vertical")) {
    62.  
    63.             moveDirection *= .7;
    64.  
    65.         }
    66.  
    67.        
    68.  
    69.         moveDirection = transform.TransformDirection(moveDirection);
    70.  
    71.         moveDirection *= isWalking ? walkSpeed : runSpeed;
    72.  
    73.        
    74.  
    75.         moveStatus = "idle";
    76.  
    77.         if(moveDirection != Vector3.zero) {
    78.  
    79.             moveStatus = isWalking ? "walking" : "running";
    80.  
    81.             if (isWalking){
    82.  
    83.                 // invoke WALK animation here
    84.  
    85.             } else {
    86.  
    87.                 // call RUN animation here
    88.  
    89.             }
    90.  
    91.         } else {
    92.  
    93.             // call IDLE animation here
    94.  
    95.         }
    96.  
    97.         // Jump!
    98.  
    99.         if(Input.GetButton("Jump"))
    100.  
    101.         {
    102.  
    103.             // call JUMP animation here
    104.  
    105.             moveDirection.y = jumpSpeed;
    106.  
    107.         }
    108.  
    109.     }                                                                   // END "IS GROUNDED"
    110.  
    111.    
    112.  
    113.     // Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    114.  
    115.     if(Input.GetMouseButton(1)) {
    116.  
    117.         transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    118.  
    119.     } else {
    120.  
    121.         transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    122.  
    123.     }
    124.  
    125.    
    126.  
    127.     // Toggle walking/running with the T key
    128.  
    129.     if(Input.GetKeyDown("t"))
    130.  
    131.         isWalking = !isWalking;
    132.  
    133.        
    134.  
    135.     //Apply gravity
    136.  
    137.     moveDirection.y -= gravity * Time.deltaTime;
    138.  
    139.     //Move controller
    140.  
    141.     var controller:CharacterController = GetComponent(CharacterController);
    142.  
    143.     var flags = controller.Move(moveDirection * Time.deltaTime);
    144.  
    145.     grounded = (flags  CollisionFlags.Below) != 0;
    146.  
    147.     };
    148.  
    149.     static function ClampAngle (angle : float, min : float, max : float) {
    150.  
    151.    if (angle < -360)
    152.  
    153.       angle += 360;
    154.  
    155.    if (angle > 360)
    156.  
    157.       angle -= 360;
    158.  
    159.    return Mathf.Clamp (angle, min, max);
    160.  
    161. }
    162.  
    163.  
    164.  
    165. // -------------------------------------------------------------------------------------------------------------
    166.  
    167. // ----------------------------------------------------------- END UPDATE  --------------------------------
    168.  
    169. // -------------------------------------------------------------------------------------------------------------
    170.  
    171.  
    172.  
    173. @script RequireComponent(CharacterController)




    Camera.js
    Code (csharp):
    1. var target : Transform;
    2.  
    3. var targetHeight = 2.0;
    4.  
    5. var distance = 2.8;
    6.  
    7. var maxDistance = 10;
    8.  
    9. var minDistance = 0.5;
    10.  
    11. var xSpeed = 250.0;
    12.  
    13. var ySpeed = 120.0;
    14.  
    15. var yMinLimit = -40;
    16.  
    17. var yMaxLimit = 80;
    18.  
    19. var zoomRate = 20;
    20.  
    21. var rotationDampening = 3.0;
    22.  
    23. private var x = 0.0;
    24.  
    25. private var y = 0.0;
    26.  
    27. var isTalking:boolean = false;
    28.  
    29.  
    30.  
    31.  
    32.  
    33.  
    34. function Start () {
    35.  
    36.     var angles = transform.eulerAngles;
    37.  
    38.     x = angles.y;
    39.  
    40.     y = angles.x;
    41.  
    42.  
    43.  
    44.    // Make the rigid body not change rotation
    45.  
    46.       if (rigidbody)
    47.  
    48.       rigidbody.freezeRotation = true;
    49.  
    50. }
    51.  
    52.  
    53.  
    54. function LateUpdate () {
    55.  
    56.    if(!target)
    57.  
    58.       return;
    59.  
    60.    
    61.  
    62.    // If either mouse buttons are down, let them govern camera position
    63.  
    64.    if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))){
    65.  
    66.    x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    67.  
    68.    y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    69.  
    70.    
    71.  
    72.    
    73.  
    74.    // otherwise, ease behind the target if any of the directional keys are pressed
    75.  
    76.    } else if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")) {
    77.  
    78.       var targetRotationAngle = target.eulerAngles.y;
    79.  
    80.       var currentRotationAngle = transform.eulerAngles.y;
    81.  
    82.       x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    83.  
    84.     }
    85.  
    86.      
    87.  
    88.  
    89.  
    90.    distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
    91.  
    92.    distance = Mathf.Clamp(distance, minDistance, maxDistance);
    93.  
    94.    
    95.  
    96.    y = ClampAngle(y, yMinLimit, yMaxLimit);
    97.  
    98.    
    99.  
    100.   // ROTATE CAMERA:
    101.  
    102.    var rotation:Quaternion = Quaternion.Euler(y, x, 0);
    103.  
    104.    transform.rotation = rotation;
    105.  
    106.    
    107.  
    108.    // POSITION CAMERA:
    109.  
    110.    var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0));
    111.  
    112.    transform.position = position;
    113.  
    114.    
    115.  
    116.     // IS VIEW BLOCKED?
    117.  
    118.     var hit : RaycastHit;
    119.  
    120.     var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
    121.  
    122.     // Cast the line to check:
    123.  
    124.     if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
    125.  
    126.         // If so, shorten distance so camera is in front of object:
    127.  
    128.         var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28;
    129.  
    130.         // Finally, rePOSITION the CAMERA:
    131.  
    132.         position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0));
    133.  
    134.         transform.position = position;
    135.  
    136.     }
    137.  
    138. }
    139.  
    140.  
    141.  
    142. static function ClampAngle (angle : float, min : float, max : float) {
    143.  
    144.    if (angle < -360)
    145.  
    146.       angle += 360;
    147.  
    148.    if (angle > 360)
    149.  
    150.       angle -= 360;
    151.  
    152.    return Mathf.Clamp (angle, min, max);
    153.  
    154.    
    155.  
    156. }
     
  30. BlackMantis

    BlackMantis

    Joined:
    Feb 7, 2010
    Posts:
    1,475
    @Idahansen

    Try changing this
    Code (csharp):
    1.  
    2. if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))) {
    3.   x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    4.   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    5. }
    6.  
    To this
    Code (csharp):
    1.  
    2. if (Input.GetMouseButton(1)) {
    3.   x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
    4.   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
    5. }
    6.  
    Try out my Duel View CamSystem.
     
    Last edited: Jul 21, 2012
  31. BlackMantis

    BlackMantis

    Joined:
    Feb 7, 2010
    Posts:
    1,475
    One problem I have with the WOW scripts is how in js to get the cam to slowly lerp back to its original pos.

    Code (csharp):
    1.  
    2. var hit : RaycastHit;
    3. var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
    4. //Cast the line to check:
    5. if(Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
    6.   //If so, shorten distance so camera is in front of object:
    7.   var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28;
    8.   //Finally, rePOSITION the CAMERA:
    9.   position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0));
    10.   transform.position = position;
    11. }
    12.  
    There is a little flickering when dragging the camera along the ground while moving.
    Also flickering while moving the player behind a collider.
     
  32. Menog

    Menog

    Joined:
    Oct 2, 2012
    Posts:
    23
    Hello,

    i will keep this piece of code up-to-date
    every time i change the code, i will add the change it to the list

    -->> http://forum.unity3d.com/threads/154150-Camera-Movement-(MMORPG-WoW-Like)
    pls use the link above, i do not keep this reply up to date

    i read the whole thread and tryed to combine the best from all and do some improvements

    here is what i get so far.
    - 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")
    - run just on hold key (need to setup Input as "Run")
    - public var "swimming" to reduce movementspeed by 70% when triggert
    - left right mousebutton moving, also sidebutton movetoggel (like wow) (need to setup Input as "Toggle Move" ("mouse 3" for my mx518 )
    - playerlayer avoid
    - camera softreturn while moving with mousesidebutton // 09.Oct.2012

    what i didn't get running is that the camera didn't move under the terrain :/... maybe someone can help on this

    btw the code is mixed .js and .cs (CharacterController is .js and CameraController is .cs) don't want to spend time to translate each ^^
    what u need to setup to get this running.
    - the MainCamera needs to be tagged as MainCamera
    - the Player/whatever u want to move needs to be tagged as Player
    - the player needs to be added to a seperate layer
    - on the attached CameraController script u need to deselect "Player Layer" at "collisionLayers"
    - the CharacterController script needs to be attached at the Player/whatever u want to move
    - the CameraController script needs to be attached at the Main Camera

    !! have fun with it and thx to all the other ppl who are working on this scripts !!
    and here is the code :)

    CharacterController.js (JavaScript)
    Code (csharp):
    1.         public var swimming:boolean = false;
    2.    
    3.     private var jumpSpeed:float = 8.0;
    4.     private var gravity:float = 20.0;
    5.     private var runSpeed:float = 10.0;
    6.     private var walkSpeed:float = 4.0;
    7.     private var rotateSpeed:float = 250.0;
    8.     private var walkBackSpeed:float = 3.0;
    9.     private var speedforwalk:float = 0.0;
    10.      
    11.     private var grounded:boolean = false;
    12.     private var moveDirection:Vector3 = Vector3.zero;
    13.     private var isWalking:boolean = false;
    14.     private var moveStatus:String = "idle";
    15.     private var jumping:boolean = false;
    16.     private var moveSpeed:float = 0.0;
    17.     private var mouseSideButton:boolean = false;
    18.     private var pbuffer:float = 0.0;        //Cooldownpuffer for SideButtons
    19.     private var coolDown:float = 0.5;       //Cooldowntime for SideButtons
    20.      
    21.     function Update ()
    22.     {
    23.        // Only allow movement and jumps while grounded
    24.        if(grounded) {
    25.        
    26.         moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
    27.        
    28.         //pushbuffer
    29.         if(pbuffer>0)
    30.             pbuffer -=Time.deltaTime;
    31.         if(pbuffer<0)pbuffer=0;
    32.                        
    33.         //Sidebuttonmovement
    34.         if(Input.GetAxis("Toggle Move")  pbuffer == 0){
    35.                 pbuffer=coolDown;
    36.                 mouseSideButton = !mouseSideButton;
    37.         }
    38.         //L+R MouseButton Movement
    39.          if (Input.GetMouseButton(0)  Input.GetMouseButton(1) || mouseSideButton)
    40.             moveDirection.z += 1;
    41.          if(Input.GetAxis("Strafing") != 0)
    42.             moveDirection.x -= Input.GetAxis("Strafing");
    43.            
    44.           // if moving forward and to the side at the same time, compensate for distance
    45.           // TODO: may be better way to do this?
    46.           if(Input.GetMouseButton(1)  Input.GetAxis("Horizontal")  Input.GetAxis("Vertical")) {
    47.              moveDirection *= .7;
    48.           }
    49.            
    50.           moveDirection = transform.TransformDirection(moveDirection);
    51.        
    52.         //Slow down back and sidemovements
    53.         speedforwalk = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1)  Input.GetAxis("Horizontal"))) ? walkBackSpeed : walkSpeed;
    54.                          
    55.           moveDirection *= isWalking ? speedforwalk : runSpeed;
    56.            
    57.           moveDirection*= swimming ? 0.7 : 1;
    58.            
    59.           moveStatus = "idle";
    60.           if(moveDirection != Vector3.zero)
    61.              moveStatus = isWalking ? "walking" : "running";
    62.            
    63.           // Jump!
    64.           if(Input.GetButton("Jump"))
    65.              moveDirection.y = jumpSpeed;
    66.        }
    67.        
    68.        // Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    69.        if(Input.GetMouseButton(1)) {
    70.           transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    71.        } else {
    72.           transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    73.        }
    74.        
    75.        // Hold "Run" to run
    76.        isWalking = Input.GetAxis("Run") ? false : true;
    77.  
    78.        //Apply gravity
    79.        moveDirection.y -= gravity * Time.deltaTime;
    80.        
    81.        //Move controller
    82.        var controller:CharacterController = GetComponent(CharacterController);
    83.        var flags = controller.Move(moveDirection * Time.deltaTime);
    84.        grounded = (flags  CollisionFlags.Below) != 0;
    85.     }
    and the CameraController.cs (CSharp)
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CameraController : MonoBehaviour {  
    6.     public GameObject target;                           // Target to follow
    7.     public float targetHeight = 1.7f;                         // Vertical offset adjustment
    8.     public float distance = 12.0f;                            // Default Distance
    9.     public float offsetFromWall = 0.1f;                       // Bring camera away from any colliding objects
    10.     public float maxDistance = 20f;                       // Maximum zoom Distance
    11.     public float minDistance = 0.6f;                      // Minimum zoom Distance
    12.     public float xSpeed = 200.0f;                             // Orbit speed (Left/Right)
    13.     public float ySpeed = 200.0f;                             // Orbit speed (Up/Down)
    14.     public float yMinLimit = -80f;                            // Looking up limit
    15.     public float yMaxLimit = 80f;                             // Looking down limit
    16.     public float zoomRate = 40f;                          // Zoom Speed
    17.     public float rotationDampening = 3.0f;                // Auto Rotation speed (higher = faster)
    18.     public float zoomDampening = 5.0f;                    // Auto Zoom speed (Higher = faster)
    19.     public LayerMask collisionLayers = -1;     // What the camera will collide with
    20.     public bool lockToRearOfTarget = false;             // Lock camera to rear of target
    21.     public bool allowMouseInputX = true;                // Allow player to control camera angle on the X axis (Left/Right)
    22.     public bool allowMouseInputY = true;                // Allow player to control camera angle on the Y axis (Up/Down)
    23.      
    24.     private float xDeg = 0.0f;
    25.     private float yDeg = 0.0f;
    26.     private float currentDistance;
    27.     private float desiredDistance;
    28.     private float correctedDistance;
    29.     private bool rotateBehind = false;
    30.     private bool mouseSideButton = false;  
    31.     private float pbuffer = 0.0f;       //Cooldownpuffer for SideButtons
    32.     private float coolDown = 0.5f;      //Cooldowntime for SideButtons 
    33.          
    34.     void Start ()
    35.     {      
    36.         Vector3 angles = transform.eulerAngles;
    37.         xDeg = angles.x;
    38.         yDeg = angles.y;
    39.         currentDistance = distance;
    40.         desiredDistance = distance;
    41.         correctedDistance = distance;
    42.        
    43.         // Make the rigid body not change rotation
    44.         if (rigidbody)
    45.             rigidbody.freezeRotation = true;
    46.            
    47.         if (lockToRearOfTarget)
    48.             rotateBehind = true;
    49.      }
    50.     void Update(){
    51.         if (target == null){
    52.             target = GameObject.FindGameObjectWithTag("Player") as GameObject;
    53.             Debug.Log("Looking for Player");
    54.         }
    55.  
    56.     }
    57.          
    58.     //Only Move camera after everything else has been updated
    59.     void LateUpdate ()
    60.     {
    61.         // Don't do anything if target is not defined
    62.         if (target == null)
    63.             return;
    64.             //pushbuffer
    65.         if(pbuffer>0)
    66.             pbuffer -=Time.deltaTime;
    67.         if(pbuffer<0)pbuffer=0;
    68.            
    69.         //Sidebuttonmovement
    70.         if((Input.GetAxis("Toggle Move")!=0)  (pbuffer == 0)){
    71.                 pbuffer=coolDown;
    72.                 mouseSideButton = !mouseSideButton;
    73.         }
    74.        
    75.         Vector3 vTargetOffset;
    76.                    
    77.         // If either mouse buttons are down, let the mouse govern camera position
    78.         if (GUIUtility.hotControl == 0)
    79.         {
    80.             if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
    81.             {
    82.                 //Check to see if mouse input is allowed on the axis
    83.                 if (allowMouseInputX)
    84.                     xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
    85.                 else
    86.                     RotateBehindTarget();
    87.                 if (allowMouseInputY)
    88.                     yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
    89.                
    90.                 //Interrupt rotating behind if mouse wants to control rotation
    91.                 if (!lockToRearOfTarget)
    92.                     rotateBehind = false;
    93.             }
    94.  
    95.             // otherwise, ease behind the target if any of the directional keys are pressed
    96.             else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || rotateBehind || mouseSideButton)
    97.             {
    98.                 RotateBehindTarget();
    99.             }
    100.         }
    101.         yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
    102.      
    103.         // Set camera rotation
    104.         Quaternion rotation = Quaternion.Euler (yDeg, xDeg, 0);
    105.      
    106.         // Calculate the desired distance
    107.         desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance);
    108.         desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
    109.         correctedDistance = desiredDistance;
    110.      
    111.         // Calculate desired camera position
    112.         vTargetOffset = new Vector3 (0, -targetHeight, 0);
    113.         Vector3 position = target.transform.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
    114.      
    115.         // Check for collision using the true target's desired registration point as set by user using height
    116.         RaycastHit collisionHit;
    117.         Vector3 trueTargetPosition = new Vector3 (target.transform.position.x, target.transform.position.y + targetHeight, target.transform.position.z);
    118.      
    119.         // If there was a collision, correct the camera position and calculate the corrected distance
    120.         var isCorrected = false;
    121.         if (Physics.Linecast (trueTargetPosition, position, out collisionHit, collisionLayers))
    122.         {
    123.             // Calculate the distance from the original estimated position to the collision location,
    124.             // subtracting out a safety "offset" distance from the object we hit.  The offset will help
    125.             // keep the camera from being right on top of the surface we hit, which usually shows up as
    126.             // the surface geometry getting partially clipped by the camera's front clipping plane.
    127.             correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall;
    128.             isCorrected = true;
    129.         }
    130.      
    131.         // For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    132.         currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
    133.      
    134.         // Keep within limits
    135.         currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
    136.      
    137.         // Recalculate position based on the new currentDistance
    138.         position = target.transform.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
    139.        
    140.         //Finally Set rotation and position of camera
    141.         transform.rotation = rotation;
    142.         transform.position = position;
    143.     }
    144.      
    145.     private void RotateBehindTarget()
    146.     {
    147.         float targetRotationAngle = target.transform.eulerAngles.y;
    148.         float currentRotationAngle = transform.eulerAngles.y;
    149.         xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    150.        
    151.         // Stop rotating behind if not completed
    152.         if (targetRotationAngle == currentRotationAngle)
    153.         {
    154.             if (!lockToRearOfTarget)
    155.                 rotateBehind = false;
    156.         }
    157.         else
    158.             rotateBehind = true;
    159.      
    160.     }
    161.      
    162.      
    163.      private float ClampAngle (float angle, float min, float max)
    164.     {
    165.        if (angle < -360f)
    166.           angle += 360f;
    167.        if (angle > 360f)
    168.           angle -= 360f;
    169.        return Mathf.Clamp (angle, min, max);
    170.     }
    171.    
    172. }
    173.  
     
    Last edited: Oct 9, 2012
  33. madmike6537

    madmike6537

    Joined:
    Aug 20, 2012
    Posts:
    49
    Figured it out lol - my "eyes" that I added to my cylendar had colliders that I couldnt move through. hah.

    **Update2**
    And Now I can do everything but move forward.. lol, I am closing in!!*

    **Update**

    I was able to fix the below error by renaming the script characterController1, unity said the name was conflicting with an in game function. However, I still cant move. I can move an inch at a time left or right but thats it. Something is definitely off, just cant figure out what. :(

    ***

    Hi Menog,

    Thanks for the script - looks good and its almost working for me. The camera piece is working great. The only error I am getting is "MissingMethodException: Method not found: 'CharacterControllerMove'.

    Any ideas? I have a character controller on my mesh of course. Not sure what I am missing. All inputs are set up, etc. I created a new layer: "Player" and put my mesh on it as you mentioned.
     
    Last edited: Oct 18, 2012
  34. Pato707

    Pato707

    Joined:
    Nov 9, 2012
    Posts:
    3
    Where should I copy the script? Thanks for it.
     
  35. javanoob

    javanoob

    Joined:
    Aug 15, 2012
    Posts:
    64
    Wierd issue lol ,this works perfectly on my Pc but when i send it to android the camera stops staying behind my character ? strange
     
  36. HelloKity1231

    HelloKity1231

    Joined:
    Nov 25, 2012
    Posts:
    121
    Last edited: Dec 4, 2012
  37. javanoob

    javanoob

    Joined:
    Aug 15, 2012
    Posts:
    64
    Has anyone got any idea why all these scripts fail to follow the character when ported to Android tablet please ? its driving me insane lol ........
     
  38. HelloKity1231

    HelloKity1231

    Joined:
    Nov 25, 2012
    Posts:
    121

    these scripts are created for pc, the event handlers are diferrent in Android
    as you can see in these scripts we use

    Code (csharp):
    1. Input.GetMouseButtonDown(id)
    Does android have mouse? does android support GetMouseButton(id) ? the answer is NO

    well, your solution is here
    http://docs.unity3d.com/Documentation/ScriptReference/Input.GetTouch.html

    and dont forget Android/IOS dont have mouse/kb so we cant use actions like

    Code (csharp):
    1.  
    2. if (Input.GetKey(keycode));
    3. if (Input.GetButtonDown(id))
    4. if (Input.GetMouseButton(id));
    5. .....
    6.  
     
  39. javanoob

    javanoob

    Joined:
    Aug 15, 2012
    Posts:
    64
    Ah lol ! it was obvious once pointed out ,thanks Kitty :) sometimes the obvious needs to be pointed out ,especially to a Javanoob lol :p


    Removed the three control references and it works perfectly :) (only wanted a terrain aware chase camera for a car ) :)
     
    Last edited: Dec 5, 2012
  40. javanoob

    javanoob

    Joined:
    Aug 15, 2012
    Posts:
    64
    I ended up with this small chase camera script :)

    var target : Transform;
    var targetHeight = 2.0;
    var distance = 2.8;
    var maxDistance = 10;
    var minDistance = 5; //was 0.5
    var xSpeed = 250.0;
    var ySpeed = 120.0;
    var yMinLimit = -40;
    var yMaxLimit = 80;
    var zoomRate = 20;
    var rotationDampening = 3.0;
    private var x = 0.0;
    private var y = 0.0;
    var isTalking:boolean = false;

    function Start () {

    var angles = transform.eulerAngles;

    x = angles.y;
    y = angles.x;

    // Make the rigid body not change rotation
    if (rigidbody)

    rigidbody.freezeRotation = true;

    }

    function LateUpdate () {

    if(!target)

    return;

    var targetRotationAngle = target.eulerAngles.y;
    var currentRotationAngle = transform.eulerAngles.y;

    x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);

    //distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
    distance = Mathf.Clamp(distance, minDistance, maxDistance);

    y = ClampAngle(y, yMinLimit, yMaxLimit);

    // ROTATE CAMERA:
    var rotation:Quaternion = Quaternion.Euler(y, x, 0);

    transform.rotation = rotation;

    // POSITION CAMERA:
    var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0));

    transform.position = position;

    // IS VIEW BLOCKED?
    var hit : RaycastHit;
    var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);

    // Cast the line to check:
    if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {

    // If so, shorten distance so camera is in front of object:
    var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - .28;

    // Finally, rePOSITION the CAMERA:
    // position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(8,-targetHeight,0)); // This line i changed to the one below position = transform.position +(Vector3(0,10,0));


    transform.position = position;

    }

    }

    static function ClampAngle (angle : float, min : float, max : float) {

    if (angle < -360)

    angle += 360;

    if (angle > 360)

    angle -= 360;

    return Mathf.Clamp (angle, min, max);

    }

    This works nicely if the camera hits terrain or object behind it jumps up to above the car // position = transform.position +(Vector3(0,10,0)); // :)
    Quick question ;p can I do the transform smoothly instead of instant ? is that an easy fix ? Would make it a perfect chase camera then :)

    position = transform.position +(Vector3.Lerp(0,10,0));

    This gives me this error :( im trying but failing guys lol ,anything ?
    The best overload for the method 'UnityEngine.Vector3.Lerp(UnityEngine.Vector3, UnityEngine.Vector3, float)' is not compatible with the argument list '(int, int, int)'.

    Im lost now no errors with this but then again the camera doesnt move anymore :p


    private var velocity = Vector3.zero;
    var smoothTime = 0.3;
    transform.localPosition = Vector3.SmoothDamp(transform.localPosition, Vector3(0,10,0), velocity, smoothTime);

    transform.localPosition = position;

    An 'In car view' is starting to look like my best option now ,because a chase camera that is terrain aware is just escaping me :( (I just noticed the camera still goes under the terrain lol ....Hair officially pulled out :(



    http://wiki.unity3d.com/index.php/SmoothFollowWithCameraBumper


    LOL sorry for asking now ,how the hell I never spotted this before I'll never know :) ,All I have to modify is a slower camera follow when car goes left and right BUT it NEVER goes under terrain etc ...

    I need to work out how to get it so the camera lets me see the sides of the car on fast turns instead of the fixed view ,but as I say everything else is perfect :)
     
    Last edited: Dec 9, 2012
  41. conversestar107

    conversestar107

    Joined:
    Apr 2, 2013
    Posts:
    1
    Hi matrix211v1,

    I'm trying to use your scripts but my character can only move forward. It can face backward but it still moves forward. Do you have a fix for this?
     
  42. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    I I wanted to simply implement the collision chamber of the tutorial Petey the Hack and Slash Tutorial and in the end I managed to create the perfect code for me (or almost), which is why I decided to share it with you. Because I'm Italian several comments are in my language but if you follow the tutorial BurgZergArcade you can comment out the code in English.

    I wish it could help. If you want to improve free to do so, I just hope you share your findings with everyone.
    Code (csharp):
    1. /// Questa camera agisce come una moderna camera degli RPG
    2. ///
    3. /// <TODO>
    4. /// InputManager
    5. /// </summary>
    6. using UnityEngine;
    7. using System.Collections;
    8.  
    9. [AddComponentMenu("Camera-Control/Hack And Slash Camera")]
    10. public class HackAndSlashCamera : MonoBehaviour {
    11.     public Transform target;
    12.     public string cameraTagName = "Camera Target";
    13.     public float walkDistance;
    14.     public float runDistance;
    15.     public float height;
    16.     public float xSpeed = 250.0f;
    17.     public float ySpeed = 120.0f;
    18.     public float heightDamping = 2.0f;
    19.     public float rotationDamping = 3.0f;
    20.     public float count;
    21.     private Transform _myTransform;
    22.     private float _x;
    23.     private float _y;
    24.     private bool _camButtonDown = false;
    25.     private bool _rotateCameraKeyPressed = false;
    26. //  public Transform cameraTransform;
    27. //  public float lookSpeed = 1.0f;
    28.     void Awake(){
    29.         _myTransform=transform;    
    30.     }
    31.  
    32.     // Use this for initialization
    33.     void Start () {
    34.         CameraSetUp();         
    35.     }
    36.    
    37.     void Update(){
    38.         if(Input.GetButtonDown("Rotate Camera Button")){
    39.             _camButtonDown = true;
    40.         }
    41.         if(Input.GetButtonUp("Rotate Camera Button")){
    42.             _x = 0;
    43.             _y = 0;
    44.             _camButtonDown = false;
    45.         }
    46.         if(Input.GetButtonDown("Rotate Camera Horizontal Button") || Input.GetButtonDown("Rotate Camera Vertical Button"))
    47.             _rotateCameraKeyPressed = true;
    48.         if(Input.GetButtonUp("Rotate Camera Horizontal Button") || Input.GetButtonUp("Rotate Camera Vertical Button")){
    49.             _x = 0;
    50.             _y = 0;
    51.             _rotateCameraKeyPressed = false;
    52.             _camButtonDown = false;
    53.         }
    54. }
    55.    
    56.     void LateUpdate(){
    57. //      _myTransform.position= new Vector3(target.position.x, target.position.y +height, target.position.z -walkDistance);
    58. //      _myTransform.LookAt (target);  
    59.         if(target != null){
    60.             if(_rotateCameraKeyPressed){
    61.                 _x += Input.GetAxis("Rotate Camera Horizontal Button") * xSpeed * 0.02f;
    62.                 _y -= Input.GetAxis("Rotate Camera Vertical Button") * ySpeed * 0.02f;
    63.                
    64.                 RotateCamera();
    65.                
    66.             }else if(_camButtonDown){      
    67.                 _x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
    68.                 _y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
    69.                
    70.                 RotateCamera();
    71.  
    72.             }else{
    73. //              _myTransform.position= new Vector3(target.position.x, target.position.y +height, target.position.z -walkDistance);
    74. //              _myTransform.LookAt (target);
    75.                
    76.                 //Calcola l'angolo di rotazione attuale
    77.                 float wantedRotationAngle = target.eulerAngles.y;
    78.                 float wantedHeight = target.position.y + height;
    79.                
    80.                 float currentRotationAngle = _myTransform.eulerAngles.y;
    81.                 float currentHeight = _myTransform.position.y;
    82.                
    83.                 //La rotazione sul y-axis
    84.                 currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
    85.                
    86.                 //L'altezza
    87.                 currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
    88.                
    89.                 //Converte l'angolo in rotazione
    90.                 Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
    91.                
    92.                 //Setta la posizione della camera nei piani x-z a:
    93.                 //distanza in metri dietro il target
    94.                 _myTransform.position = target.position;
    95.                 _myTransform.position -= currentRotation * Vector3.forward * walkDistance;
    96.                
    97.                 //Setta l'altezza della camera
    98.                 _myTransform.position = new Vector3(_myTransform.position.x, currentHeight, _myTransform.position.z);
    99.                
    100.                 //Guarda sempre il target
    101.                 _myTransform.LookAt(target);
    102.                
    103.                 //Is view blocked?
    104.  
    105.         RaycastHit hit;
    106.  
    107.         Vector3 trueTargetPosition = target.transform.position - new Vector3(0, -height, 0);
    108.  
    109.  
    110.  
    111.         //Cast the line to check:
    112.  
    113.         //HAL 2011-jan-23 / make sure its not colliding with the original target
    114.  
    115.         if (Physics.Linecast(trueTargetPosition, _myTransform.position,out hit)  hit.transform != target)
    116.  
    117.         {
    118.  
    119.             count += Time.deltaTime;
    120.  
    121.  
    122.  
    123.             //If so, shorten distance so camera is in front of object:
    124.  
    125.             if (count > 0.01)
    126.  
    127.             {
    128.  
    129.                 var tempDistance = Vector3.Distance(trueTargetPosition, hit.point) - 0.28f;
    130.  
    131.  
    132.  
    133.                 // Finally reposition the camera:
    134.  
    135.                 _myTransform.position = target.position - (currentRotation * Vector3.forward * tempDistance + new Vector3(0, -height, 0));
    136.  
    137.                 transform.position = _myTransform.position;
    138.  
    139.             }
    140.  
    141.         }
    142.  
    143.         else
    144.  
    145.         {
    146.  
    147.             count = 0;
    148.  
    149.         }
    150.  
    151.  
    152.                
    153.             }
    154.         }else{
    155.             GameObject go = GameObject.FindGameObjectWithTag(cameraTagName);
    156.            
    157.             if(go == null)
    158.                 return;
    159.            
    160.             target = go.transform;
    161.         }
    162.     }
    163.    
    164.     private void RotateCamera(){           
    165.         Quaternion rotation = Quaternion.Euler(_y, _x, 0);
    166.        
    167.         Vector3 position = rotation * new Vector3(0.0f, 0.0f, -walkDistance) + target.position;
    168.                
    169.         _myTransform.rotation = rotation;
    170.         _myTransform.position = position;
    171.        
    172.     }
    173.     public void CameraSetUp(){
    174.         _myTransform.position= new Vector3(target.position.x, target.position.y + height, target.position.z -walkDistance);
    175.         _myTransform.LookAt (target);      
    176.     }
    177. }
     
    Last edited: May 1, 2013
  43. Ofx360

    Ofx360

    Joined:
    Apr 30, 2013
    Posts:
    155
    Thanks a lot guys! All this stuff really helped me figure out an effective 3rd person camera. Keep up the awesome work!
     
  44. cjacobwade

    cjacobwade

    Joined:
    Jun 8, 2013
    Posts:
    10
    4 years later and this is still the best script I've found for a 3rd person camera script. Thanks!
     
  45. tomi-trescak

    tomi-trescak

    Joined:
    Jul 31, 2013
    Posts:
    78
    I am experiencing the issue where when using the 3rd person camera script from this thread, the movement is a bit jagged. I have found that the reason is that camera movement is performed in LateUpdate. When I moved code to FixedUpdate, my environment is moving smoothly, but now player movement is quite jagged.

    Any ideas please?

    Thanks
     
  46. Menog

    Menog

    Joined:
    Oct 2, 2012
    Posts:
    23
  47. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    I've been trying to get a character controller like this to work for days now with very little sleep. I've tried every last bit of script in this thread and while some of it works to one degree or another, none of it can do everything I want it to do. Using script I've pieced together from various sources and a lot of tinkering I've come up with a script that does everything I want it to do.

    The script has a problem however. Jumping causes the character to teleport into the air and then be dropped instead of a smooth acceleration into the air and then back down again.

    The things this script should do:
    Forward/Reverse with W/S Up/Down arrow keys.
    Rotate with A/D keys and with Right Mouse Button.
    Strafe with Q/E keys.
    Jump with Space key.
    Ability to control movement direction while in a jump, both from a moving start and from a standing still position.
    Movement control when both left and right mouse buttons are held down.

    I've got a perfect camera script, but this movement script is blowing my mind. If anyone has any suggestions on how to fix the jumping problem you'd be a hero to me.

    Here's the script:

    Code (csharp):
    1. //  Perfect except for teleport jumping
    2.  
    3. var walkSpeed = 6.0;                            //How fast can the character walk
    4. var runSpeed = 11.0;                            //How fast can the character run
    5. var limitDiagonalSpeed = true;                  //If true, diagonal speed (when strafing + moving forward or back) can't exceed normal move speed; otherwise it's about 1.4 times faster
    6. var toggleRun = false;                          //If checked, the run key toggles between running and walking. Otherwise player runs if the key is held down and walks otherwise.  There must be a button set up in the Input Manager called "Run"
    7. var jumpSpeed = 8.0;                            //How high can the character jump
    8. var gravity = 20.0;                             //How strong is gravity for the character
    9. var slideWhenOverSlopeLimit = false;            //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
    10. var slideOnTaggedObjects = false;               //If checked and the player is on an object tagged "Slide", he will slide down it regardless of the slope limit
    11. var slideSpeed = 12.0;                          //Speed the character can slide
    12. var airControl = false;                         //If checked, then the player can change direction while in the air
    13. var antiBumpFactor = .75;                       //Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
    14. var antiBunnyHopFactor = 1;                     //Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
    15. private var moveDirection = Vector3.zero;       //The direction of movement
    16. private var grounded = false;                   //Is the character on the ground
    17. private var controller : CharacterController;   //Reference to the character controller
    18. private var myTransform : Transform;            //Reference to the transform
    19. private var speed : float;                      //Internal speed variable
    20. private var slideLimit : float;                 //Internal slide speed variable
    21. private var hit : RaycastHit;                   //For checking distance to the ground
    22. private var rayDistance : float;                //For checking distance to the ground
    23. private var contactPoint : Vector3;             //For checking distance to the ground
    24. private var playerControl = false;              //Can the player control the character while in the air
    25. private var jumpTimer : int;                    //How long has the player been in the air
    26. private var mouseSideButton:boolean = false;    //temp var for mouse side buttons
    27. private var pbuffer:float = 0.0;                //Cooldownpuffer for SideButtons
    28. private var coolDown:float = 0.5;               //Cooldowntime for SideButtons
    29. private var rotateSpeed:float = 250.0;          //Rotationspeed of the Character
    30. private var walkBackMod:float = 0.75;           //Speed in Percent for walk backwards and sidewalk
    31. private var speedMod:float = 0.0;               //temp Var for Speedcalculation
    32. private var isWalking:boolean = false;          //toggle var between move and run
    33. private var jumping:boolean = false;            //temp var for jumping
    34.  
    35. //****************************************************************************************************//
    36. //*******************************************START FUNCTION*******************************************//
    37. //****************************************************************************************************//
    38.  
    39. function Start () {
    40.  
    41.     controller = GetComponent(CharacterController);
    42.     myTransform = transform;
    43.     speed = walkSpeed;
    44.     rayDistance = controller.height * .5 + controller.radius;
    45.     slideLimit = controller.slopeLimit - .1;
    46.     jumpTimer = antiBunnyHopFactor;
    47.     oldPos = transform.position;
    48.    
    49. }
    50.  
    51. //****************************************************************************************************//
    52. //****************************************FIXED UPDATE FUNCTION***************************************//
    53. //****************************************************************************************************//
    54.  
    55. function FixedUpdate() {
    56.  
    57.     // Get horizontal and vertical input axis and assign to variables
    58.     var inputX = Input.GetAxis("Horizontal");
    59.     var inputY = Input.GetAxis("Vertical");
    60.    
    61.     // If both horizontal and vertical are used simultaneously, limit speed (if allowed), so the total doesn't exceed normal move speed
    62.     var inputModifyFactor = (inputX != 0.0  inputY != 0.0  limitDiagonalSpeed)? .7071 : 1.0;
    63.  
    64.     // If the character is on the ground
    65.     if (grounded) {
    66.                
    67.         var sliding = false;
    68.         // See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point,
    69.         // because that interferes with step climbing amongst other annoyances
    70.         if (Physics.Raycast(myTransform.position, -Vector3.up, hit, rayDistance)) {
    71.             if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    72.                 sliding = true;
    73.         }
    74.         // However, just raycasting straight down from the center can fail when on steep slopes
    75.         // So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
    76.         else {
    77.             Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, hit);
    78.             if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    79.                 sliding = true;
    80.         }
    81.  
    82.         // If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
    83.         if (!toggleRun)
    84.             speed = Input.GetButton("Run")? runSpeed : walkSpeed;
    85.  
    86.         // 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
    87.         if ( (sliding  slideWhenOverSlopeLimit) || (slideOnTaggedObjects  hit.collider.tag == "Slide") ) {
    88.             var hitNormal = hit.normal;
    89.             moveDirection = Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
    90.             Vector3.OrthoNormalize (hitNormal, moveDirection);
    91.             moveDirection *= slideSpeed;
    92.             playerControl = false;
    93.         }
    94.     }
    95.    
    96.     // If the character is not on the ground
    97.     else {
    98.  
    99.         // If air control is allowed, check movement but don't touch the y component
    100.         if (airControl  playerControl) {
    101.             moveDirection.x = inputX * speed * inputModifyFactor;
    102.             moveDirection.z = inputY * speed * inputModifyFactor;
    103.             moveDirection = myTransform.TransformDirection(moveDirection);
    104.         }
    105.     }
    106.    
    107.     // Move the controller, and set grounded true or false depending on whether we're standing on something
    108.     grounded = (controller.Move(moveDirection * Time.deltaTime)  CollisionFlags.Below) != 0;
    109.    
    110. }
    111.  
    112. //*****************************************************************************************************//
    113. //*******************************************UPDATE FUNCTION*******************************************//
    114. //*****************************************************************************************************//
    115.  
    116. function Update () {
    117.  
    118.         // If the run button is set to toggle, then switch between walk/run speed.
    119.         if (toggleRun  grounded  Input.GetButtonDown("Run"))
    120.             speed = (speed == walkSpeed? runSpeed : walkSpeed);
    121.        
    122.         // Change moveDirection value to reflect the current direction of movement
    123.         moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
    124.        
    125.         // If the character is on the ground
    126.         if (grounded){
    127.             // Jump! But only if the jump button has been released and player has been grounded for a given number of frames
    128.             if (!Input.GetButton("Jump"))
    129.                 jumpTimer++;
    130.             else if (jumpTimer >= antiBunnyHopFactor) {
    131.                 moveDirection.y = jumpSpeed;
    132.                 jumpTimer = 0;
    133.                 jumping = true;
    134.             }
    135.         }
    136.        
    137.         // If the character is not on the ground
    138.         else {
    139.             // Apply gravity
    140.             moveDirection.y -= gravity * Time.deltaTime;
    141.         }
    142.        
    143.         // Pushbuffer to avoid on/off flipping
    144.         if(pbuffer>0)
    145.             pbuffer -=Time.deltaTime;
    146.         if(pbuffer<0)pbuffer=0;
    147.                        
    148.         // Automove Sidebuttonmovement
    149.         if(Input.GetAxis("Toggle Move")  pbuffer == 0){
    150.             pbuffer=coolDown;
    151.             mouseSideButton = !mouseSideButton;
    152.         }
    153.         if(mouseSideButton  ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump") || (Input.GetMouseButton(0)  Input.GetMouseButton(1)) ))
    154.             mouseSideButton = false;        
    155.        
    156.         // L+R MouseButton Movement
    157.         if (Input.GetMouseButton(0)  Input.GetMouseButton(1) || mouseSideButton)
    158.             moveDirection.z += 1;
    159.         if (moveDirection.z > 1)
    160.             moveDirection.z = 1;
    161.        
    162.         // Strafing movement (like Q/E movement)
    163.         moveDirection.x -= Input.GetAxis("Strafing");
    164.            
    165.         // If moving forward and to the side at the same time, compensate for distance
    166.         if(Input.GetMouseButton(1)  Input.GetAxis("Horizontal")  Input.GetAxis("Vertical")) {
    167.             moveDirection *= .7;
    168.         }
    169.        
    170.         // Speed Modification - is movement forward or side/backward?
    171.         speedMod = ((Input.GetAxis("Vertical") < 0) || (Input.GetMouseButton(1)  Input.GetAxis("Horizontal")) || Input.GetAxis("Strafing") != 0) ? walkBackMod : 1.0;
    172.        
    173.         // Use run or walkspeed
    174.         moveDirection *= isWalking ? walkSpeed * speedMod : runSpeed * speedMod;
    175.        
    176.         // Transform direction
    177.         moveDirection = transform.TransformDirection(moveDirection);        
    178.  
    179.         // Allow turning at any time. Keep the character facing in the same direction as the Camera if the right mouse button is down.
    180.         if(Input.GetMouseButton(1)) {
    181.             transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    182.         }
    183.         else {
    184.             transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    185.         }
    186.        
    187.         //Move controller
    188.         var controller:CharacterController = GetComponent(CharacterController);
    189.         var flags = controller.Move(moveDirection * Time.deltaTime);
    190.         grounded = (flags  CollisionFlags.Below) != 0;
    191.        
    192. }
    193.  
    194. @script RequireComponent(CharacterController)
     
  48. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    After a week of tinkering with it on and off I've gotten the script nearly perfect. There are a few oddities but none that are detrimental.

    The only real problem is if the character is grounded and moving forward with L+R mouse buttons, if the W key (forward) is pressed the character stops moving forward if it's facing (South?) of the spawn point and moves faster than normal if it's facing (North?) of the spawn point. The opposite is also true, using the S key.

    I've included the camera controller script I'm using, though it's not of my own making, just for anyone who might want to use it with the character controller since they work together to achieve what my overall goal was.

    And once again, if anyone would care to help me figure out the few oddities left in the character script I would greatly appreciate it. Once I get this thing fully bug free I'll put it in the asset store as a free download so nobody else has to go through the hassle I've gone through getting a functioning modern mmorpg controller setup.

    Character Controller:
    Code (csharp):
    1. //Quinn's (Near) Perfect MMORPG Style Character Controller
    2.  
    3. //Oddity #1: If the character is grounded and moving forward with L+R mouse buttons, if the W key (forward) is pressed the character stops if it's facing (South?) of the spawn point and moves fast if it's facing (North?) of the spawn point.  The opposite is also true, using the S key
    4. //Oddity #2: If the character is in the air and moving forward with the L+R mouse buttons, if the W key (forward) is pressed the character will move forward at a faster rate.  Not necessarily a bad thing but the source of this has yet to be located
    5. //Oddity #3: If a certain camera angle is achieved while moving with the L+R mouse buttons the character will vibrate and rotate quickly back and forth.  This only happens when the camera angle is to the (West / South-West?) of the spawn point.  Seems to lag the game and causes audio to vibrate
    6.  
    7. //Inputs:
    8. //Horizontal (Rotate left/right) (Negative "left" Positive "right" Alt Negative "a" Alt Positive "d")
    9. //Vertical (Move backward/forward) (Negative "down" Positive "up" Alt Negative "s" Alt Positive "w")
    10. //Strafing (Move left/right) (Negative "q" Positive "e")
    11. //Jump (Positive "space")
    12. //Mouse X (Mouse Movement X Axis)
    13. //Mouse Y (Mouse Movement Y Axis)
    14. //Mouse ScrollWheel (Zoom) (Mouse Movement 3rd Axis)
    15. //Toggle Move (Toggle Autorun) (Positive "r")
    16. //Run (Toggle walk/run) (Positive "left shift")
    17.  
    18. var walkSpeed = 6.0;                            //How fast can the character walk
    19. var runSpeed = 10.0;                            //How fast can the character run
    20. var toggleRun = false;                          //If checked, the run key toggles between running and walking. Otherwise character runs if the key is held down and walks otherwise.  There must be a button set up in the Input Manager called "Run"
    21. var limitDiagonalSpeed = true;                  //If true, diagonal speed (when strafing + moving forward or back) can't exceed normal move speed; otherwise it's about 1.4 times faster
    22. var jumpSpeed = 8.0;                            //How high can the character jump
    23. var gravity = 20.0;                             //How strong is gravity for the character
    24. var fallingDamageThreshold = 10.0;              //Units that character can fall before a falling damage function is run. To disable, type "infinity" in the inspector
    25. var slideWhenOverSlopeLimit = false;            //If checked, if the character ends up on a slope which is at least the slope limit as set on the character controller, then he will slide down
    26. var slideOnTaggedObjects = false;               //If checked and the character is on an object tagged "Slide", he will slide down it regardless of the slope limit
    27. var slideSpeed = 12.0;                          //Speed the character can slide
    28. var airControl = false;                         //If checked, then the player can change direction while in the air
    29. var antiBumpFactor = .75;                       //Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
    30. var antiBunnyHopFactor = 1;                     //Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
    31. var rotateSpeed:float = 250.0;                  //Rotation speed of the character
    32. private var moveDirection = Vector3.zero;       //The direction of movement
    33. private var grounded = false;                   //Is the character on the ground
    34. private var controller : CharacterController;   //Reference to the character controller
    35. private var myTransform : Transform;            //Reference to the transform
    36. private var speed : float;                      //Internal speed variable
    37. private var slideLimit : float;                 //Internal slide speed variable
    38. private var fallStartLevel : float;             //Height the character started to fall from
    39. private var falling = false;                    //Is the character falling
    40. private var hit : RaycastHit;                   //For checking distance to the ground
    41. private var rayDistance : float;                //For checking distance to the ground
    42. private var contactPoint : Vector3;             //For checking distance to the ground
    43. private var playerControl = false;              //Can the player control the character while in the air
    44. private var jumpTimer : int;                    //How long has the character been in the air
    45. private var mouseSideButton:boolean = false;    //Are the mouse side buttons being pressed
    46. private var pbuffer:float = 0.0;                //Cooldown pbuffer for mouse side buttons
    47. private var coolDown:float = 0.5;               //Cooldown time for mouse side buttons
    48.  
    49. //****************************************************************************************************//
    50. //*******************************************START FUNCTION*******************************************//
    51. //****************************************************************************************************//
    52.  
    53. function Start () {
    54.     controller = GetComponent(CharacterController);
    55.     myTransform = transform;
    56.     speed = walkSpeed;
    57.     rayDistance = controller.height * .5 + controller.radius;
    58.     slideLimit = controller.slopeLimit - .1;
    59.     jumpTimer = antiBunnyHopFactor;
    60.     oldPos = transform.position;
    61. }
    62.  
    63. function FixedUpdate() {
    64.  
    65.     //Get horizontal and vertical input axis and assign to variables
    66.     var inputX = Input.GetAxis("Strafing");
    67.     var inputY = Input.GetAxis("Vertical");
    68.    
    69.     //If both horizontal and vertical are used simultaneously, limit speed (if allowed), so the total doesn't exceed normal move speed
    70.     var inputModifyFactor = (inputX != 0.0  inputY != 0.0  limitDiagonalSpeed)? .7071 : 1.0;
    71.    
    72.     //If the character is on the ground
    73.     if (grounded) {
    74.    
    75.         //By default the character is not sliding
    76.         var sliding = false;
    77.        
    78.         //Change moveDirection value to reflect the current direction of movement
    79.         moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Strafing") : 0),0,Input.GetAxis("Vertical"));
    80.  
    81.         //Pushbuffer to avoid on/off flipping
    82.         if(pbuffer>0)
    83.             pbuffer -=Time.deltaTime;
    84.         if(pbuffer<0)pbuffer=0;
    85.                        
    86.         //Automove mouse side button movement
    87.         if(Input.GetAxis("Toggle Move")  pbuffer == 0){
    88.             pbuffer=coolDown;
    89.             mouseSideButton = !mouseSideButton;
    90.         }
    91.         if(mouseSideButton  ((Input.GetAxis("Vertical") != 0) || Input.GetButton("Jump") || (Input.GetMouseButton(0)  Input.GetMouseButton(1)) ))
    92.             mouseSideButton = false;
    93.        
    94.         //Strafing movement (like Q/E movement)
    95.         moveDirection.x -= Input.GetAxis("Strafing");
    96.        
    97.         //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
    98.         if (Physics.Raycast(myTransform.position, -Vector3.up, hit, rayDistance)) {
    99.             if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    100.                 sliding = true;
    101.         }
    102.         //However, just raycasting straight down from the center can fail when on steep slopes
    103.         //So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
    104.         else {
    105.             Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, hit);
    106.             if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    107.                 sliding = true;
    108.         }
    109.  
    110.         //If character was falling and fell a vertical distance greater than the threshold, run a falling damage routine
    111.         if (falling) {
    112.             falling = false;
    113.             if (myTransform.position.y < fallStartLevel - fallingDamageThreshold)
    114.                 FallingDamageAlert (fallStartLevel - myTransform.position.y);
    115.         }
    116.  
    117.         //If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
    118.         //if (!toggleRun)
    119.         //  speed = Input.GetButton("Run")? runSpeed : walkSpeed;
    120.  
    121.         //If sliding (and it's allowed), or if character is on an object tagged "Slide", get a vector pointing down the slope the character is on
    122.         if ( (sliding  slideWhenOverSlopeLimit) || (slideOnTaggedObjects  hit.collider.tag == "Slide") ) {
    123.             var hitNormal = hit.normal;
    124.             moveDirection = Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
    125.             Vector3.OrthoNormalize (hitNormal, moveDirection);
    126.             moveDirection *= slideSpeed;
    127.             playerControl = false;
    128.         }
    129.         //Otherwise recalculate moveDirection directly from axes, adding a bit of -y to avoid bumping down inclines
    130.         else {
    131.             moveDirection = Vector3(inputX * inputModifyFactor, -antiBumpFactor, inputY * inputModifyFactor);
    132.             moveDirection = myTransform.TransformDirection(moveDirection) * speed;
    133.             playerControl = true;
    134.         }
    135.        
    136.         //L+R Mouse button movement
    137.         if (Input.GetMouseButton(0)  Input.GetMouseButton(1) || mouseSideButton) {
    138.             moveDirection.x = inputX * speed * inputModifyFactor;  //Strafe in the correct direction if Q/E are used
    139.             moveDirection.z +=1 * speed;  //Move forward at the correct speed
    140.             moveDirection = myTransform.TransformDirection(moveDirection);
    141.             Screen.lockCursor = true;  //Lock the mouse cursor
    142.         }
    143.         else {
    144.             Screen.lockCursor = false;  //Unlock the mouse cursor
    145.         }
    146.  
    147.         //Jump, but only if the jump button has been released and the character has been grounded for a given number of frames
    148.         if (!Input.GetButton("Jump"))
    149.             jumpTimer++;
    150.         else if (jumpTimer >= antiBunnyHopFactor) {
    151.             moveDirection.y = jumpSpeed;
    152.             jumpTimer = 0;
    153.         }
    154.     }
    155.    
    156.     //If the character is not on the ground
    157.     else {
    158.    
    159.         //If the character stepped over a cliff or something, set the height at which the character started falling
    160.         if (!falling) {
    161.             falling = true;
    162.             fallStartLevel = myTransform.position.y;
    163.         }
    164.  
    165.         //If air control is allowed, check movement but don't touch the y component
    166.         if (airControl  playerControl) {
    167.             moveDirection.x = inputX * speed * inputModifyFactor;
    168.             moveDirection.z = inputY * speed * inputModifyFactor;
    169.                 // Give ability to jump forward while using both mouse buttons to move
    170.                 if (Input.GetMouseButton(0)  Input.GetMouseButton(1) || mouseSideButton) {
    171.                     moveDirection.z +=1 * speed;
    172.                     Screen.lockCursor = true;  //Lock the mouse cursor.
    173.                 }
    174.                 else {
    175.                     Screen.lockCursor = false;  //Unlock the mouse Cursor.
    176.                 }
    177.             moveDirection = myTransform.TransformDirection(moveDirection);
    178.         }
    179.     }
    180.  
    181.     //Allow turning at any time. Keep the character facing in the same direction as the camera if the right mouse button is down.
    182.     if(Input.GetMouseButton(1)) {
    183.         transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
    184.     } else {
    185.         transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
    186.     }
    187.  
    188.     //Apply gravity
    189.     moveDirection.y -= gravity * Time.deltaTime;
    190.  
    191.     //Move the controller and set grounded to true or false depending on whether the character is standing on something
    192.     grounded = (controller.Move(moveDirection * Time.deltaTime)  CollisionFlags.Below) != 0;
    193.  
    194. }
    195.  
    196. //*****************************************************************************************************//
    197. //*******************************************UPDATE FUNCTION*******************************************//
    198. //*****************************************************************************************************//
    199.  
    200. function Update () {
    201.  
    202.     //If the run button is set to toggle then switch between walk/run speed
    203.     if (toggleRun  grounded  Input.GetButtonDown("Run"))
    204.         speed = (speed == walkSpeed? runSpeed : walkSpeed);
    205.  
    206. }
    207.  
    208. //*****************************************************************************************************//
    209. //*********************************ON CONTROLLER COLLIDER HIT FUNCTION*********************************//
    210. //*****************************************************************************************************//
    211.  
    212. //Store point that character is in contact with for use in FixedUpdate if needed
    213. function OnControllerColliderHit (hit : ControllerColliderHit) {
    214.     contactPoint = hit.point;
    215. }
    216.  
    217. //*****************************************************************************************************//
    218. //************************************FALLING DAMAGE ALERT FUNCTION************************************//
    219. //*****************************************************************************************************//
    220.  
    221. //If falling damage occured, this is the place to do something about it. You can make the character
    222. //have hitpoints and remove some of them based on the distance fallen, add sound effects, etc.
    223. function FallingDamageAlert (fallDistance : float) {
    224.     Debug.Log ("Ouch! Fell " + fallDistance + " units!");  
    225. }
    226.  
    227. @script RequireComponent(CharacterController)
    Camera Controller:
    Code (csharp):
    1. //Camera Controller in JS v2.1
    2.  
    3. public var target:GameObject;                   //Target to follow
    4. public var targetHeight:float = 1.7;            //Vertical offset adjustment
    5. public var distance:float = 12;                 //Default Distance
    6. public var offsetFromWall:float = 0.1;          //Bring camera away from any colliding objects
    7. public var maxDistance:float = 20;              //Maximum zoom Distance
    8. public var minDistance:float = 0.6;             //Minimum zoom Distance
    9. public var xSpeed:float = 200;                  //Orbit speed (Left/Right)
    10. public var ySpeed:float = 200;                  //Orbit speed (Up/Down)
    11. public var yMinLimit:float = -80;               //Looking up limit
    12. public var yMaxLimit:float = 80;                //Looking down limit
    13. public var zoomRate:float = 40;                 //Zoom Speed
    14. public var rotationDampening:float = 3;         //Auto Rotation speed (higher = faster)
    15. public var zoomDampening:float = 5;             //Auto Zoom speed (Higher = faster)
    16. public var collisionLayers:LayerMask = -1;      //What the camera will collide with
    17. public var lockToRearOfTarget:boolean = false;  //Lock camera to rear of target
    18. public var allowMouseInputX:boolean = true;     //Allow player to control camera angle on the X axis (Left/Right)
    19. public var allowMouseInputY:boolean = true;     //Allow player to control camera angle on the Y axis (Up/Down)
    20.  
    21. private var xDeg:float = 0;                     //Temp var
    22. private var yDeg:float = 0;                     //Temp var
    23. private var currentDistance:float;              //Temp var
    24. private var desiredDistance:float;              //Temp var
    25. private var correctedDistance:float;            //Temp var
    26. private var rotateBehind:boolean = false;       //Temp var
    27. private var mouseSideButton:boolean = false;    //Temp var
    28. private var pbuffer:float = 0;                  //Cooldownpuffer for SideButtons
    29. private var coolDown:float = 0.5;               //Cooldowntime for SideButtons
    30.  
    31. function Start ()
    32. {      
    33.     var angles:Vector3 = transform.eulerAngles;
    34.     xDeg = angles.x;
    35.     yDeg = angles.y;
    36.     currentDistance = distance;
    37.     desiredDistance = distance;
    38.     correctedDistance = distance;
    39.    
    40.     //Make the rigid body not change rotation
    41.     if (rigidbody)
    42.         rigidbody.freezeRotation = true;
    43.        
    44.     if (lockToRearOfTarget)
    45.         rotateBehind = true;
    46.  }
    47.  
    48. function Update(){
    49.     if (target == null){
    50.         target = GameObject.FindGameObjectWithTag("Player") as GameObject;
    51.         Debug.Log("Looking for Player");
    52.     }
    53.  
    54. }
    55.      
    56. //Only Move camera after everything else has been updated
    57. function LateUpdate ()
    58. {
    59.     //Don't do anything if target is not defined
    60.     if (target == null)
    61.         return;
    62.    
    63.     //Pushbuffer
    64.     if(pbuffer>0)
    65.         pbuffer -=Time.deltaTime;
    66.     if(pbuffer<0)pbuffer=0;
    67.        
    68.     //Side button movement
    69.     if((Input.GetAxis("Toggle Move")!=0)  (pbuffer == 0)){
    70.             pbuffer=coolDown;
    71.             mouseSideButton = !mouseSideButton;
    72.     }
    73.     if(mouseSideButton  Input.GetAxis("Vertical") != 0)
    74.         mouseSideButton = false;
    75.    
    76.     var vTargetOffset:Vector3;
    77.                
    78.     //If either mouse buttons are down, let the mouse govern camera position
    79.     if (GUIUtility.hotControl == 0)
    80.     {
    81.         if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
    82.         {
    83.             //Check to see if mouse input is allowed on the axis
    84.             if (allowMouseInputX)
    85.                 xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02;
    86.             else
    87.                 RotateBehindTarget();
    88.             if (allowMouseInputY)
    89.                 yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02;
    90.            
    91.             //Interrupt rotating behind if mouse wants to control rotation
    92.             if (!lockToRearOfTarget)
    93.                 rotateBehind = false;
    94.         }
    95.  
    96.         //Otherwise, ease behind the target if any of the directional keys are pressed
    97.         else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || rotateBehind || mouseSideButton)
    98.         {
    99.             RotateBehindTarget();
    100.         }
    101.     }
    102.     yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
    103.  
    104.     //Set camera rotation
    105.     var rotation:Quaternion = Quaternion.Euler (yDeg, xDeg, 0);
    106.  
    107.     //Calculate the desired distance
    108.     desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance);
    109.     desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
    110.     correctedDistance = desiredDistance;
    111.  
    112.     //Calculate desired camera position
    113.     vTargetOffset = new Vector3 (0, -targetHeight, 0);
    114.     var position:Vector3 = target.transform.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
    115.  
    116.     //Check for collision using the true target's desired registration point as set by user using height
    117.     var collisionHit:RaycastHit;
    118.     var trueTargetPosition:Vector3 = new Vector3 (target.transform.position.x, target.transform.position.y + targetHeight, target.transform.position.z);
    119.  
    120.     //If there was a collision, correct the camera position and calculate the corrected distance
    121.     var isCorrected:boolean = false;
    122.     if (Physics.Linecast (trueTargetPosition, position, collisionHit, collisionLayers))
    123.     {
    124.         //Calculate the distance from the original estimated position to the collision location,
    125.         //subtracting out a safety "offset" distance from the object we hit.  The offset will help
    126.         //keep the camera from being right on top of the surface we hit, which usually shows up as
    127.         //the surface geometry getting partially clipped by the camera's front clipping plane.
    128.         correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall;
    129.         isCorrected = true;
    130.     }
    131.  
    132.     //For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    133.     currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
    134.  
    135.     //Keep within limits
    136.     currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
    137.  
    138.     //Recalculate position based on the new currentDistance
    139.     position = target.transform.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
    140.    
    141.     //Finally set rotation and position of camera
    142.     transform.rotation = rotation;
    143.     transform.position = position;
    144. }
    145.  
    146. function RotateBehindTarget()
    147. {
    148.     var targetRotationAngle:float = target.transform.eulerAngles.y;
    149.     var currentRotationAngle:float = transform.eulerAngles.y;
    150.     xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    151.    
    152.     //Stop rotating behind if not completed
    153.     if (targetRotationAngle == currentRotationAngle)
    154.     {
    155.         if (!lockToRearOfTarget)
    156.             rotateBehind = false;
    157.     }
    158.     else
    159.         rotateBehind = true;
    160. }
    161.  
    162. function ClampAngle(angle:float, min:float, max:float)
    163. {
    164.    if (angle < -360)
    165.       angle += 360;
    166.    if (angle > 360)
    167.       angle -= 360;
    168.    return Mathf.Clamp (angle, min, max);
    169. }
     
    Last edited: Jan 16, 2014
  49. CantUnderstandJS

    CantUnderstandJS

    Joined:
    Jan 23, 2013
    Posts:
    19
    What about animations of player? :)
     
  50. saito0892

    saito0892

    Joined:
    Jan 4, 2014
    Posts:
    3
    Hello everyone.

    A few months ago I’ve been working on a project, I'm still a newbie on Unity and I have a camera issue that I haven’t could solve.

    It is a 3D game and I have an object (player) moving through a long tube using the keyboard (WASD). The player can’t get out of the tube, of course. The tube is a 3D mesh (with a mesh collider).

    I am using the WOW Camera Movement script and works pretty well when the object is at the center of the tube as the camera shows what is "inside the tube" ( Figure 1).

    The problem appears when the object is on the right or left and collides with the tube walls. The camera also collides and does not pass through the walls of the tube, but when the camera collides part of what is "out of the tube" is shown (Figure 2 sky- blue region) and this should not happen (only what is “inside” must be shown).

    I have tried using raycast to rotate the camera when is close to a wall but I cannot make it work, I've tried several approaches but still cannot find a good result.

    Can anyone help me?

    PD: On the figure C is Camera (red) and P is Player (blue).

    Thank you in advance.

    $Camera issue.jpg