Search Unity

Player Movement System

Discussion in 'Physics' started by DerpMerf, Jul 14, 2015.

  1. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    So I'm attempting to make a movement system for the player. I've gotten quite far, with camera rotation and player rotation, but I haven't quite found a good tutorial on creating a movement system that isn't for 2D or utilizes a component such as Rigidbody which is something I don't necessarily want to start experimenting with or having to deal with repercussions or changes in a system that works quite well, just to accommodate something that might end up in me completely rewriting a week's worth of code-writing and musing over what code to write. Before you ask, I HAVE read the unity documentation, and that does require Rigidbody, so I'm just asking if you know of any tutorials that teach me how to create such a system without the use of Rigidbody or other odd components. I'm sort of ok with CharacterController, but if there's a way that I don't have to use even that, I'd prefer it.
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    You should learn to use Rigidbody, because it's basically the main component of unity Physics, and it's not so difficult to learn. The only way (i know) of moving something without rigidbody is transform.Translate, and it just ignores walls.

    Edit:
    Sorry, there's quite a few ways to move things without rigidbody, but every one of them ignores walls
     
  3. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    I'll try that, but I'm just hoping that that doesn't lead to me having to experiment other things.
     
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Here's the z movement code in jscript, it's not that hard, and it's faster and smaller as a transform.Translate code
    Code (JavaScript):
    1. var rb = GetComponent(Rigidbody);
    2.  
    3. function Update () {
    4.    rb.velocity.z = Input.GetAxis("Horizontal");
    5.    if (Input.GetAxis("Horizontal") == 0) {
    6.       rb.velocity.z = 0;
    7.    }
    8. }
    9.  
     
  5. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    When I do that, it says, "Cannot modify a value type return value of `UnityEngine.Rigidbody.velocity'. Consider storing the value in a temporary variable". Not quite sure if I'm doing something since I'm converting code to C#, but the code actually looks exactly the same, so I don't think it's that:

    Code (CSharp):
    1. void Update()  {
    2.     rb.velocity.z = Input.GetAxis ("Horizontal");
    3.  
    4.     if (Input.GetAxis ("Horizontal") == 0) {
    5.         rb.velocity.z = 0;
    6.     }
    7. }  
     
  6. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Ok, here you go, my far-far complicated script from the game i'm working on:
    Code (CSharp):
    1.     if (Input.GetAxis("YAxis") > 0) {
    2.         rb.AddForce(0,0,MoveSpeed,ForceMode.VelocityChange);
    3.     }
    4.     if (Input.GetAxis("YAxis") < 0) {
    5.         rb.AddForce(0,0,-MoveSpeed,ForceMode.VelocityChange);
    6.     }
    7.     if (Input.GetAxis("XAxis") > 0) {
    8.         rb.AddForce(MoveSpeed,0,0,ForceMode.VelocityChange);
    9.     }
    10.     if (Input.GetAxis("XAxis") < 0) {
    11.         rb.AddForce(-MoveSpeed,0,0,ForceMode.VelocityChange);
    12.     }
    13.     if (Input.GetAxis("YAxis") == 0) {
    14.         rb.velocity.z = 0;
    15.     }
    16.     if (Input.GetAxis("XAxis") == 0) {
    17.         rb.velocity.x = 0;
    18.     }
    19.     if (rb.velocity.magnitude > 3f) {
    20.         rb.velocity = rb.velocity.normalized * 3f;
    21.     }
     
  7. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    It's the same as modifying the velocity directly, but it doesn't give any error
     
  8. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Ohh, i see what's the problem you're using C#, my script is in Jscript, and maybe that makes the error. I looked it up, and you can simply solve it by doing this:
    Code (CSharp):
    1. rb.velocity = Vector3(rb.velocity.x,rb.velocity.z,Input.GetAxis("Horizontal"));
    2.  
    3. instead of this:
    4.  
    5. rb.velocity.z = ...
     
  9. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    This is the correct code for C#
    Code (CSharp):
    1. var rb = GetComponent(Rigidbody);
    2. void Update () {
    3.    rb.velocity = Vector3(rb.velocity.x,rb.velocity.y,Input.GetAxis("Horizontal");
    4.    if (Input.GetAxis("Horizontal") == 0) {
    5.       rb.velocity = Vector3(rb.velocity.x,rb.velocity.y,0);
    6.    }
    7. }
     
  10. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    Actually, it seems that for some reason the Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") simply don't work, or they work too well. I've inputted a Debug.Log() into all of the if statements, and they're constantly getting triggered no matter what I do. My console is just getting spammed. However, clickig W, A, S and D may or may not trigger the messages, but my player does not move in the slightest. I'm not quite sure why this is, but I definitely would not like to have to implement specific if statements for all the possible keys.
     
  11. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Go to Edit/Project Settings/Input and there change the Horizontal one to positive button: w negative :s, because it's defaulted to Joystick, my bad
     
  12. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    I've done that, but it still does not work. For me, Input.GetAxis rarely works, I only use it for Mouse X and Mouse Y
     
  13. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Then the other code that I posted should work, I'm tried, and it works, the only thing, that you need to make YAxis(w,s) and XAxis(a,d)
     
  14. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    The other code you posted doesn't really work, the player still doesn't move. To be honest, I'm looking for tutorials here, not really code snippets. That's more a job for Unity Answers. So if you know of any good tutorials that actually work (*cough* docs.unity3d.com *cough*), I'd appreciate that.
     
  15. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350


    This is a great tutorial series, it explain's everything from the basics, there is tutorial for inventory, shops terrain, and what's good for you Movement (I think there's multiple Episodes of that) It even explaines how codes work.
     
  16. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    That tutorial is quite outdated, using Unity 3.6 and from 2012?
     
  17. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    Is there another, more recent tutorial worth looking at?
     
  18. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    Hello. I don't know any tutorials but you can use this if you want.

    Add this to your player
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     private Rigidbody rb;
    8.     private float runSpeed = 5f;
    9.     private float jumpForce = 650f;
    10.     private bool jumping = false;
    11.     private bool ground = false;
    12.  
    13.     private Vector3 speed;
    14.  
    15.     private void Start()
    16.     {
    17.         rb = GetComponent<Rigidbody>();
    18.     }
    19.  
    20.     private void Update()
    21.     {
    22.         GetInput ();
    23.     }
    24.  
    25.     private void FixedUpdate()
    26.     {
    27.         MovePlayer();
    28.     }
    29.  
    30.     private void GetInput()
    31.     {
    32.         speed.x = Input.GetAxis("Horizontal") * runSpeed;
    33.         speed.y = rb.velocity.y;
    34.         speed.z = Input.GetAxis ("Vertical") * runSpeed;
    35.  
    36.         speed = transform.rotation * speed;
    37.      
    38.         if (Input.GetKeyDown(KeyCode.Space) &&
    39.             !jumping &&
    40.             ground)
    41.             jumping = true;
    42.     }
    43.  
    44.     private void MovePlayer()
    45.     {
    46.         rb.velocity = speed;
    47.  
    48.         if (jumping)
    49.         {
    50.             rb.AddForce(new Vector3(0, jumpForce, 0));
    51.             jumping = false;
    52.         }
    53.  
    54.         rb.AddForce(new Vector3(0, -25, 0)); // schneller fallen
    55.     }
    56.  
    57.     private void OnCollisionStay(Collision col)
    58.     {
    59.         foreach (ContactPoint contact in col.contacts)
    60.         {
    61.             if (Vector3.Angle(contact.normal, Vector3.up) < 60)
    62.             {
    63.                 ground = true;
    64.             }
    65.         }
    66.     }
    67.     private void OnCollisionExit()
    68.     {
    69.         ground = false;
    70.     }
    71. }
    72.  
    Add this to your camera.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerCamera : MonoBehaviour
    6. {
    7.     public GameObject player;
    8.  
    9.     private float sensitivity = 1f;
    10.     private float xRot;
    11.     private float yRot;
    12.  
    13.     public CursorLockMode cursorLock;
    14.  
    15.     private void Update()
    16.     {
    17.         GetInput();
    18.     }
    19.  
    20.     private void FixedUpdate()
    21.     {
    22.         Move();
    23.     }
    24.  
    25.     private void GetInput()
    26.     {
    27.         if (xRot > 360)
    28.             xRot -= 360;
    29.         else if (xRot < 0)
    30.             xRot += 360;
    31.  
    32.         xRot += Input.GetAxis("Mouse X") * sensitivity;
    33.         yRot -= Input.GetAxis("Mouse Y") * sensitivity;
    34.  
    35.         yRot = Mathf.Clamp(yRot, -90, 90);
    36.  
    37.         Cursor.lockState = cursorLock;
    38.     }
    39.  
    40.     private void Move()
    41.     {
    42.         transform.localRotation = Quaternion.Euler(new Vector3(yRot, 0, 0));
    43.         player.transform.rotation = Quaternion.Euler(new Vector3(0, xRot, 0));
    44.     }
    45. }
    46.  

    player.jpg

    camera.jpg

    input.jpg
     
  19. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    My axes are working perfectly, but the thing just doesn't want to move. Somehow, printing the Input.GetAxis() returns an actual number, but printing speed.x immediately after setting it to the Input.GetAxis() returns 0. o_O
     
  20. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    Could you maybe send me your project ?
     
  21. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    Ummm... I'll send you a project without sensitive art and code... How's about that. Also, question: how?
     
  22. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    I would only need your player with movement script... you could send it over Dropbox for example..
     
  23. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    As if I HAVE Dropbox... I guess I'll just post it on Mediafire.
     
  24. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    yep ok
     
  25. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    Working on copying the project and removing all the stuff to give to you
     
  26. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
  27. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    For some reason your player is a "missing prefab". Maybe you should try to copy your whole project folder and put it in a .zip archive?
    missing prefab.jpg
     
  28. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Your player is corrupted, you should redo it again, unity does this some time.
     
  29. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    That's because I didn't provide the prefab, but for some reason unity decided to package the player component. The prefab exists and it works fine, but it doesn't make sense that it packaged the gameobjects that I deleted into the thing...

    EDIT

    Here's the updated .unitypackage without all the crazy missing prefab shenanigans: http://www.mediafire.com/download/seylr9ipxpb0zyx/BrokenProject.unitypackage
     
  30. cr4zy

    cr4zy

    Joined:
    Jul 14, 2015
    Posts:
    10
    Hello. You should freeze the rotation of X and Z in your Rigidbody component
    rigidbody.jpg
    I hope I could help :)
     
  31. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33
    Thank you, that fixed the problem.
     
  32. DerpMerf

    DerpMerf

    Joined:
    Jan 1, 2014
    Posts:
    33