Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Rigidbody2d.moveposition makes player jump to random position.

Discussion in 'Scripting' started by JustaDuck97, Jul 10, 2020.

  1. JustaDuck97

    JustaDuck97

    Joined:
    Jul 31, 2019
    Posts:
    45
    Attached is a video so you can better understand my issue.



    I have a pointer Indicator that rotates around my player to face the mouse, and my intention is to make the player move in the direction it's facing. I thought that since the pointer indicator is a child of the player object the player could never actual catch up since the indicator moves with the player, but instead of the player moving in the direction of the indicator it jumps to a position on the right. The player has no gravity force being applied as the intention is for it to fly where the player's cursor is when the input 'w' is received. What is causing this behavior?

    here is the script:
    Code (CSharp):
    1. public class PlayerBallMovement : MonoBehaviour
    2. {  
    3.     public float moveSpeed;
    4.     Rigidbody2D rb;
    5.     Vector3 lookDir;
    6.     public Transform pointerIndicator;
    7.     void Start()
    8.     {
    9.         rb = GetComponent<Rigidbody2D>();
    10.         lookDir = new Vector3(pointerIndicator.transform.position.x, pointerIndicator.transform.position.y, 0);
    11.        
    12.     }
    13.    
    14.     void FixedUpdate()
    15.     {        
    16.         if (Input.GetKey("w"))
    17.         {
    18.             rb.MovePosition(transform.position + lookDir * moveSpeed * Time.deltaTime);
    19.      
    20.         }
    21.  
    22.         if (Input.GetKey("a"))
    23.         {
    24.             rb.MovePosition(transform.position + (transform.right - transform.right * 2) * moveSpeed * Time.deltaTime);
    25.        
    26.         }
    27.     }
    28. }
     
  2. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    At a first step try to use Time.fixedDeltaTime, because you are in a fixed update frame step while you move the rb. At a second step try to read the player input in the Update method and pass the results to the FixedUpdate.
    Also you only read the lookDir in the Start method but as i readed you want to read out the direction each frame.
     
    Last edited: Jul 10, 2020
  3. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Code (CSharp):
    1. public class PlayerBallMovement : MonoBehaviour
    2. {
    3.     public float moveSpeed;
    4.     Rigidbody2D rb;
    5.     Vector3 lookDir;
    6.     public Transform pointerIndicator;
    7.     private bool keyAPressed;
    8.     private bool keyWPressed;
    9.  
    10.     void Start()
    11.     {
    12.         rb = GetComponent<Rigidbody2D>();
    13.         lookDir = new Vector3(pointerIndicator.transform.position.x, pointerIndicator.transform.position.y, 0);      
    14.     }
    15.  
    16.     void Update()
    17.     {      
    18.        keyAPressed = Input.GetKey("a");
    19.        keyWPressed = Input.GetKey("w");
    20.     }
    21.  
    22.     void FixedUpdate()
    23.     {      
    24.         lookDir = new Vector3(pointerIndicator.transform.position.x, pointerIndicator.transform.position.y, 0);
    25.  
    26.         if (keyWPressed)
    27.         {
    28.             rb.MovePosition(transform.position + lookDir * moveSpeed * Time.fixedDeltaTime);
    29.  
    30.         }
    31.  
    32.         if (keyAPressed)
    33.         {
    34.             rb.MovePosition(transform.position + (transform.right - transform.right * 2) * moveSpeed * Time.fixedDeltaTime);      
    35.         }
    36.     }
    37. }
     
    Last edited: Jul 10, 2020
  4. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    At the end i dont know if to mix the pointer indicator and the rb of the player into one gameobject is a good idea, i fear not (because the rb is driven by the physics and the pointer by your mouse and both systems are fighting against each other)
     
  5. JustaDuck97

    JustaDuck97

    Joined:
    Jul 31, 2019
    Posts:
    45
    After going back an changing my code I see a few horribly obvious mistakes. I know how I should do input, but have continuously looked over that mistake, and the fact that I wasn't actually updating the indicator position because it's value was being assigned during the start method.

    Could you explain how these systems are fighting each other? Just to clarify, I'm sure you already know, but I just want to be sure. The pointer indicator is a separate game object and the scripts are being handled seperately.

    How would you suggest I change this to improve it? instead of moving towards the indicator add a force on the rigidbody in the direction its pointing?
     
  6. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    The problem could be that when moving the player to the pointer that in this case the pointer will be moved too because its a child of the player and therefore the player's movement is not "clean" (not continuous) at all.

    After looking your video again it looks like your player cant move up and down and will be reseted to it original position (in the center) at a certain point.

    How its looking at the moment with the code changes and how looks your pointer movement class?

    I assume it would help if the pointer isnt a child of the player or more better if you dont move in direction of the pointer but in the direction of for instance the mouse (depends on your game). So let the pointer do his job and only indicate visually the direction and determine the direction of the player by another "more fixed" target (mouse position in 2D space).
     
    Last edited: Jul 10, 2020