Control speed of a rigidbody that move to a fixed distance
Hello
I am quite new to unity and I am having a problem to move my player. My goal is to move my player smoothly one unit to the right if I press the right arrow and same to the left. So my player move this way: (x,x,x) to (x+1,x,x) and it continue to move one more unit(s) if I keep the key pressed.
I finally manage to do it with the player transform (and it works exactly as I wanted) but it has problem with collision with other object, so after reading a bit I decide to switch to use its rigidbody instead of changing its transform.
I manage once again to make it work by using rigidBody.MovePosition() and the player move one unit per one unit, halas it move really really fast, about 10 unit when I touch briefly the key, so I want to slow down it's movement.
The answers I saw on this website about speed change concerns movements in a given direction that were not restrained to a constant distance so I couldn't use them.
This is my code:
 public class PlayerController : MonoBehaviour{
     Vector3 pos = Vector3.zero;
     Transform tr;
     //public float movementspeed = 5.0f;
     CharacterController characterController;
     Rigidbody rigidBody;
 
     void Start(){
         pos = transform.position;
         tr = transform;
         characterController = GetComponent<CharacterController>();
         rigidBody = GetComponent<Rigidbody> ();
     }
 
     void FixedUpdate(){
         Vector3 delta = Vector3.zero;
 
         if (Input.GetKey(KeyCode.RightArrow) && tr.position == pos) 
             delta = Vector3.right;
         else if (Input.GetKey(KeyCode.LeftArrow) && tr.position == pos) 
             delta = Vector3.left;
         pos += delta;
         //transform.position = Vector3.MoveTowards (transform.position, pos, Time.deltaTime * movementspeed);
         //characterController.Move(delta);
         rigidBody.MovePosition (pos);
     }
 }
 
               This line was the First I tried that works but it use the transform and it gives bag collisions.
 //transform.position = Vector3.MoveTowards (transform.position, pos, Time.deltaTime * movementspeed);
 
               These two are my attempt to use the rigidbody but they both gives a result too fast. I don't really care between using a classic rigidbody or a charactercontroler as I don't know which is the most adapted to my grid game.
 //characterController.Move(delta);
 rigidBody.MovePosition (pos);
 
               I also looked at the Rigidbody.MovePosition doc and it says we can smooth the movement by playing with interpolation and isKinematic but I didn't see a difference.
Answer by bateria_260791 · Oct 25, 2016 at 04:15 PM
Some time ago I published in my blog (written in spanish) a script to do this type of movement using Transform. But if you @Epsilonee wish to use it copy and paste this script:
 public class PlayerMovement : MonoBehaviour {
         [Range(1f, 10f)]
         public float speed = 1f;
         public LayerMask unwalkableMask;
         private Vector3 nextPosition;
         private bool isWalking;
  
         void Start(){
              nextPosition = transform.position;
              isWalking = false;
         }
  
         void Update(){
              float horizontalMovement = Input.GetAxisRaw("Horizontal");
              float verticalMovement = Input.GetAxisRaw("Vertical");
  
              // If the player is quiet.
              if(transform.position == nextPosition){
                   isWalking = false;
              }
  
              // If the player wants to move and is not walking.
              // The future position is calculated.
              if(horizontalMovement != 0 && !isWalking){
                   nextPosition += Vector3.right * horizontalMovement;
              }else if(verticalMovement != 0 && !isWalking){
                   nextPosition += Vector3.up * verticalMovement;
              }
  
              // If the future position is different from the current one is because the player wants to move the character ...
              if(nextPosition != transform.position){
                   Vector2 dir = nextPosition - transform.position;
                   Raycasthit2D hit = Physics2D.Raycast(transform.position, dir, dir.sqrMagnitude, unwalkableMask.value);
  
              // It is verified by a raycast that nothing interpose the movement.
              if(hit.collider == null){
                   transform.position = Vector3.MoveTowards(transform.position, nextPosition, Time.deltaTime * speed);
                   if(!isWalking){ isWalking = true; }
              }else{
                   Debug.LogError("There is an obstacle, the player can't move");
                   nextPosition = transform.position;
 }
              }
         }
 }
 
              Answer by Epsilone · Oct 25, 2016 at 08:43 PM
@bateria_260791 Thanks a lot bateria_260791, but I already can do it with the transform. I can't use it because I need a rigidbody to deal with collision easily, and rigidbody seem to have problem with transform based mouvement.
Your answer
 
             Follow this Question
Related Questions
i'm using a code to make my cube walk with character controller but when i play the cube spins. 0 Answers
How to: rigidbody.MovePosition to player's position 2 Answers
i am using a code to make my cube walk with character controller ,but when i play the cube spins. 0 Answers
Help converting a character controller script to rigidbody 1 Answer
Converting my Character Controller Movement to Rigidbody 1 Answer