Getting maze walls (using 3D meshes) to work?

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.

Just as a suggestion, don't try to detect collision of the pacman with the walls. Instead of that, constrain the movement of pacman to a line segment that runs through the center of the corridor from one fork to the next one.

That way, the pacman should move only while the pacman center stays on the line segment. I don't think Unity brings a ready to use solution for that, you may have to write your own code for it.

If you're going to be doing your movement manually (i.e position += velocity * deltaTime ), you'll want to do a trace to make sure the position you're moving into isn't going to be inside a wall.

You're calculating a positional delta for that frame, and just hammering the position, which means he's intercepting the collider of the wall. When you let up on the input, the physics system pushes him out of the wall, which is why you're seeing the problems you describe.

You really have two options:

1) Use physics, and do something like setting your rigidbody velocity to control movement instead of hammering position directly. That way the internal physics system will know when to stop, and how to react to collisions (i.e. bounce/slide/etc). This is going to be the easiest solution, and also more indicative how how Unity games in general should be made.

2) Bypass physics entirely, and do a trace to make sure your next position isn't going to be in a wall. This is a complicated problem, and if you wanted to do things like slide along walls it will require a lot more math. It's definitely a solvable problem, but I wouldn't recommend it to somebody who doesn't have a firm grasp of collision/vector math. I can go into more detail on that if you really want.

For an actual Pac-Man clone, I'd use an array for the maze, and not bother with physics at all. Then you just translate world positions to array positions, and not allow movement into "wall" array cells. For example, my iPhone maze game has no "real" collision detection, it's just a 3D array. You can also look at this script for 2D grid movement. It would need some modification for this case, such as adding the aforementioned "collision detection", and you'd want to be able to reverse direction immediately rather than only at the grid lines.

There's really nothing specific about this problem that makes it a "2d problem". Doing it this way is just a collision behavior problem. It will also be difficult to provide suggestions without seeing what movement code you're using (i.e. are you moving your rigidbody in Update instead of FixedUpdate).

owned :)