Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Character Controller - WASD movement relative to the camera - Top Down

Discussion in 'Scripting' started by henmachuca, Feb 5, 2018.

  1. henmachuca

    henmachuca

    Joined:
    Oct 14, 2016
    Posts:
    105
    Hello! I have a Player in my game that moves using via mouse clicks right now.
    I'd like to add WASD movement as well.

    I have some code implemented but my character just flies off the screen when I press any buttons.

    Can I have some assistance please?

    Code (CSharp):
    1.     private Animator anim;
    2.     private CharacterController charController;
    3.  
    4.     private float moveSpeed = 5f;
    5.     private bool canMove;
    6.     private bool finishedMovement = true;
    7.  
    8.     private Vector3 targetPos = Vector3.zero;
    9.     private Vector3 playerMove = Vector3.zero;
    10.     private float playerToPointDistance;
    11.  
    12.     private float gravity = 9.8f;
    13.     private float height;
    14.     private float velocityY = 0;
    15.  
    16.  
    17.     void Start ()
    18.     {
    19.         anim = GetComponent<Animator>();
    20.         charController = GetComponent<CharacterController>();
    21.     }
    22.    
    23.     void Update ()
    24.     {
    25.         velocityY -= gravity * Time.deltaTime;
    26.  
    27.         // Movement with the keyboard
    28.         if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
    29.         {
    30.  
    31.             Vector3 moveDirection = StickToWorldspace(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")));
    32.             // times 3 so that the point it finds is not to close to the player making it stop all the time
    33.             Vector3 destination = transform.position + moveDirection * 1.001f;
    34.  
    35.             if (destination != Vector3.zero)
    36.             {
    37.                 charController.Move(destination);
    38.             }
    39.         }
    40.  
    41.         if (charController.isGrounded)
    42.         {
    43.             velocityY = 0;
    44.         }
    45.  
    46.     }
    47.  
    48. // makes the inputs from keyboard be always relative to the camera
    49.     private Vector3 StickToWorldspace(Vector2 input)
    50.     {
    51.         // Get camera direction
    52.         Vector3 cameraDirection = Camera.main.transform.forward;
    53.         cameraDirection.y = 0; //sets Y to 0 so its on a flat XZ plane (otherwise I would go into the ground since the camera is facing down)
    54.  
    55.         //find the forward direction based on camera direction
    56.         Quaternion referentialShift = Quaternion.FromToRotation(Vector3.forward, cameraDirection);
    57.  
    58.         // Convert joystick input in worldspace coords
    59.         return (referentialShift * new Vector3(input.x, 0, input.y)).normalized;
    60.     }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Your StickToWorldspace function is fine, it's your usage of CharacterController that is flawed. characterController.Move takes an absolute movement delta - in other words, the exact amount that it's moving by this frame, starting at its current position. Your "destination" variable has the transform.position baked into it to start, so if your character starts at (200,100,100), then the second frame he'll be at (400,200,200), and the third he'll be at (800, 400, 400), and so on.

    You also should be multiplying in Time.deltaTime with your moveDirection.
     
    henmachuca likes this.