So I'm learning Unity by making a Pac-man clone, and I'm using 3D meshes to make both the walls and the player - but haven't yet been able to make them behave right. :)
I started with two Unity Cube Meshes, with the default box Collider - one Cube is scaled out into a Wall, and the other Cube is given a movement script (and locked to the Z-axis). It doesn't work - the Player goes right through the Wall. :) So after some research, I added a Rigidbody to the Player Cube. I turned gravity off, and freeze rotation.
This mostly works - the Player stops at the wall, but if I keep pressing arrow keys, it keeps trying to move, and vibrates back and forth. When I let go of the keys, it then has a small backwards force on it, going away from the Wall.
What do I need to change, to make it behave more like Pac-man? Are there any options I can adjust, to make the character stop instantly at the wall? Or does it require something like Raycasting to not even touch the wall?
And how do I stop the Cube from retreating from the Wall? Is this an AI problem? ;)
Update: code, changed to FixedUpdate, as per Tetrad:
void FixedUpdate() {
movePlayer();
}
void movePlayer() {
float xMove = Input.GetAxis("Horizontal") * playerSpeed * Time.deltaTime;
float yMove = Input.GetAxis("Vertical") * playerSpeed * Time.deltaTime;
Vector3 pos = this.transform.position;
Vector3 moveTo = new Vector3(pos.x + xMove, pos.y + yMove, origZ);
this.transform.position = moveTo;
}
Changing from Update() to FixedUpdate() stopped the vibrating effect - however the Player still goes slightly into the Wall, rebounding away when I stop pressing the movement keys.
Update 2: Current code (and it almost works) is:
void movePlayer() {
float curAxis = Input.GetAxis("Horizontal");
bool keyLeft = (curAxis < -0.01f);
bool keyRight = (curAxis > 0.01f);
if (curAxis == 0) {
isLeft = false;
isRight = false;
this.gameObject.rigidbody.velocity = Vector3.zero;
return;
}
else if (keyLeft && !isLeft) {
isLeft = true;
isRight = false;
this.gameObject.rigidbody.velocity = new Vector3(-baseSpeed, 0, 0);
// this.gameObject.rigidbody.AddForce(
// new Vector3(-baseSpeed, 0, 0), ForceMode.VelocityChange);
}
else if (keyRight && !isRight) {
isLeft = false;
isRight = true;
this.gameObject.rigidbody.velocity = new Vector3(baseSpeed, 0, 0);
// this.gameObject.rigidbody.AddForce(
// new Vector3(baseSpeed, 0, 0), ForceMode.VelocityChange);
}
}
It has two problems - first, sometimes when the Player collides with the Wall, it drops down a couple of pixels (and stays there). Second, it doesn't stop the instant I release the arrow keys. I don't understand how Forces work, but I would have thought that setting velocity=0 would stop it instantly. I'm also curious if there's a difference in setting velocity directly, versus the (commented out) AddForce(VelocityChange), which seems to behave identically.
Update 3: Apparently it's time to switch to Plan B: disregarding physics. Or as Vaarsuvius would say, "I consider the Laws of Physics as loose guidelines, at best." There were several good suggestions on how to approach the problem, and I wish I could checkmark more than one solution. :) Since I can't, @Tetrad actually gave the best answer (in a comment, no less) to the Question that I originally asked - how to make a Rigidbody behave.