Search code examples
c#unity-game-enginegame-physicsphysicspacman

Character cannot move after touching a wall


I'm making a pacman clone using an online tutorial. I've just gotten to pacman's movement and when Pacman touches a wall he can no longer move. Here is the movement script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class pacman : MonoBehaviour
{
public int speed;
Vector2 dest;
// Start is called before the first frame update
void Start()
{
    dest = transform.position;
    speed = 5;

}

// Update is called once per frame
void FixedUpdate()
{
    Vector2 p = Vector2.MoveTowards(transform.position, dest, speed);
    GetComponent<Rigidbody2D>().MovePosition(p);

    // Check for Input if not moving
    if ((Vector2)transform.position == dest)
    {
        if (Input.GetKey("w") )
            dest = (Vector2)transform.position + Vector2.up;
        if (Input.GetKey("d"))
            dest = (Vector2)transform.position + Vector2.right;
        if (Input.GetKey("s"))
            dest = (Vector2)transform.position - Vector2.up;
        if (Input.GetKey("a"))
            dest = (Vector2)transform.position - Vector2.right;
    }

}
}

Solution

  • You have a couple of things you should watch out for.

    1) You're never resetting "dest" anywhere in your code. As you're moving based on the calculation being set to "p". I imagine you're character is hitting a wall, which is as close as it can get to "dest", therefore it cannot move any closer. I can't predict what you're trying to get your gameplay to be, but I would imagine you'd want to reset "dest" in your OnCollision() to keep the object moving instead of staring at a wall.

    As a general piece of advice, I wouldn't set PacMac (the player controlled unit) to be going to a destination. You'd want to calculate an offset based on the input, and then attempt to add that to the transform.position (probably safer through the RigidBody system) and then let the simulation take over from there.

    2) You're moving without any reference to gametime. You should really change your offset to be calculated with taking Time.deltaTime into account. This is important for when you're running on a fast computer or a slow computer. With your current code, you'll move a lot faster on a strong computer and slower on a slow computer.

    3) Based on your pacman experience, you might want to change these to else if statements. Even better, but is harder, only accept the last input. This will keep you from moving diagonally (which your current code is susceptible to. If you do the second method, you'll want to keep a stack of all the buttons pressed in case someone tries to hold down multiple buttons at the same time.