- Home /
How to code PlayerController grid movement with RigidBody and Colliders?
I have a "PlayerController" script that allows grid movement (like a chess piece to a open square) and will stop the player on an exact square no matter how long the movement key has been pressed. However this "PlayerController" script uses Transform which clips the player with obstacles when using Rigidbody or colliders. I coded another script using rigidbody.moveposition which does work with colliders without clipping but the movement jumps from point to point instead of a smooth slide and won't stop the player on an exact square if the movement key is released at the wrong time. Is there a way to modify the "PlayerController" script to have grid movement and work with Rigidbody or colliders. I'm aware that using Velocity or addForce are better when using Rigidbody and colliders but I'm a novice to coding and need guidance. Thank you for your time.
CORRECT GRID MOVEMENT---
public class PlayerController : MonoBehaviour { Vector3 pos; // For movement public float speed = 2.0f; // Speed of movement
void Start()
{
pos = transform.position; // Take the initial position
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.A) && transform.position == pos)
{ // Left
pos += Vector3.left;
}
if (Input.GetKey(KeyCode.D) && transform.position == pos)
{ // Right
pos += Vector3.right;
}
if (Input.GetKey(KeyCode.W) && transform.position == pos)
{ // Up
pos += Vector3.forward;
}
if (Input.GetKey(KeyCode.S) && transform.position == pos)
{ // Down
pos += Vector3.back;
}
transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * speed);
} }
CORRECT COLLIDER REACTION---
public class BetterPlayerController : MonoBehaviour { public Rigidbody rb; public float speed = 2.0f; // Speed of movement
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.A))
{ // Left
rb.MovePosition(transform.position += new Vector3(-10.0f, 0.0f, 0.0f) * Time.fixedDeltaTime * speed);
}
if (Input.GetKey(KeyCode.D))
{ // Right
rb.MovePosition(transform.position += new Vector3(10.0f, 0.0f, 0.0f) * Time.fixedDeltaTime * speed);
}
if (Input.GetKeyDown(KeyCode.W))
{ // Up
rb.MovePosition(transform.position += new Vector3(0.0f, 0.0f, 10.0f) * Time.fixedDeltaTime * speed);
}
if (Input.GetKeyDown(KeyCode.S))
{ // Down
rb.MovePosition(transform.position += new Vector3(0.0f, 0.0f, -10.0f) * Time.fixedDeltaTime * speed);
}
}
}
Answer by xxmariofer · Jan 23, 2019 at 08:36 AM
You will not have a good time acomplishing this since rigidbody works with forces rather than just moving towards positions, the easiest hack you can do for accomplish this is give the player a velocityt with a desire direction and after than compare if the player position is equals to the desire position, the problem is that this never be the case since isnt moving to the position so you have to decide if you want to compare if the playe is in a range from the desire position relative to his position or compare if its position is higher than the expected vector
if (Input.GetKey(KeyCode.A))
{ // Left
position = transform.position;
position += new Vector3(-10, 0, 0);
rb.velocity = new Vector3(-1, 0.0f, 0.0f) * Time.fixedDeltaTime * speed;
}
if (Input.GetKey(KeyCode.D))
{ // Right
position = transform.position;
position += new Vector3(10, 0, 0);
rb.velocity = new Vector3(1, 0.0f, 0.0f) * Time.fixedDeltaTime * speed;
}
if (Input.GetKeyDown(KeyCode.W))
{ // Up
position = transform.position;
position += new Vector3(0, 0, 10);
rb.velocity = new Vector3(0.0f, 0.0f, 1) * Time.fixedDeltaTime * speed;
}
if (Input.GetKeyDown(KeyCode.S))
{ // Down
position = transform.position;
position += new Vector3(0, 0, -10);
rb.velocity = new Vector3(0.0f, 0.0f, -1) * Time.fixedDeltaTime * speed;
}
}
you can do somithing like this the problem comes when comparing position, here is an answer of how to do it giving the vector some margin error
https://answers.unity.com/questions/950927/compare-vector3.html
you just have to set velocity to Vector3.zero if that method returns true.