You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity中基于C#的网格移动(含碰撞检测)实现及宝可梦风格游戏开发学习资源咨询

Fixing Your Pokémon-Style Grid Movement in Unity + Reliable Learning Tips

Hey there! Let's break down your problem step by step— I know how frustrating it can be when tutorial code doesn't work as expected, especially when you're just starting out with grid-based movement like Pokémon in Unity.

First: Fix Your Broken Code

Looking at your script, there are two critical issues that are making it fail completely:

  1. All directions are set to Vector3.up: You're using the same direction for W/A/S/D—so no matter which key you press, the player only moves up.
  2. Typo in coroutine call: You wrote StartCoroutine/(...) instead of StartCoroutine(...) (slash instead of parentheses).

Here's the corrected base version of your code, with proper direction mapping:

using System.Collections;
using UnityEngine;

public class GridMovement : MonoBehaviour {
    private bool isMoving;
    private Vector3 origPos, targetPos;
    private float timeToMove = 0.2f;
    // Define your grid cell size (usually 1 unit for top-down Pokémon style)
    public float gridCellSize = 1f;

    void Update() {
        if (isMoving) return; // Skip input if already moving

        if (Input.GetKeyDown(KeyCode.W)) StartCoroutine(MovePlayer(Vector3.forward * gridCellSize));
        if (Input.GetKeyDown(KeyCode.A)) StartCoroutine(MovePlayer(Vector3.left * gridCellSize));
        if (Input.GetKeyDown(KeyCode.S)) StartCoroutine(MovePlayer(Vector3.back * gridCellSize));
        if (Input.GetKeyDown(KeyCode.D)) StartCoroutine(MovePlayer(Vector3.right * gridCellSize));
    }

    private IEnumerator MovePlayer(Vector3 direction) {
        isMoving = true;
        float elapsedTime = 0;
        origPos = transform.position;
        targetPos = origPos + direction;

        while (elapsedTime < timeToMove) {
            transform.position = Vector3.Lerp(origPos, targetPos, elapsedTime / timeToMove);
            elapsedTime += Time.deltaTime;
            yield return null;
        }
        transform.position = targetPos;
        isMoving = false;
    }
}

Note: I switched GetKey to GetKeyDown so the player moves once per key press, not continuously—this is more true to Pokémon's movement style.

Adding Collision Detection

To stop the player from moving through walls/obstacles, we need to check if the target position is clear before starting the movement. Here's how to add that:

  1. Set up layers: Create an "Obstacles" layer in Unity and assign all your wall/block objects to it.
  2. Add collision check logic: Modify the script to validate the target position before moving.

Updated code with collision detection:

using System.Collections;
using UnityEngine;

public class GridMovement : MonoBehaviour {
    private bool isMoving;
    private Vector3 origPos, targetPos;
    private float timeToMove = 0.2f;
    public float gridCellSize = 1f;
    // Assign your Obstacles layer here in the Inspector
    public LayerMask obstacleLayer;

    void Update() {
        if (isMoving) return;

        if (Input.GetKeyDown(KeyCode.W)) AttemptMove(Vector3.forward * gridCellSize);
        if (Input.GetKeyDown(KeyCode.A)) AttemptMove(Vector3.left * gridCellSize);
        if (Input.GetKeyDown(KeyCode.S)) AttemptMove(Vector3.back * gridCellSize);
        if (Input.GetKeyDown(KeyCode.D)) AttemptMove(Vector3.right * gridCellSize);
    }

    private void AttemptMove(Vector3 direction) {
        targetPos = transform.position + direction;
        // Check if target position is free of obstacles
        if (IsPositionClear(targetPos)) {
            StartCoroutine(MovePlayer(direction));
        }
    }

    private bool IsPositionClear(Vector3 position) {
        // Use OverlapBox to check for collisions at the target position
        // Adjust the box size to match your player's collider
        Collider[] hitColliders = Physics.OverlapBox(position, transform.localScale / 2, Quaternion.identity, obstacleLayer);
        return hitColliders.Length == 0;
    }

    private IEnumerator MovePlayer(Vector3 direction) {
        isMoving = true;
        float elapsedTime = 0;
        origPos = transform.position;
        targetPos = origPos + direction;

        while (elapsedTime < timeToMove) {
            transform.position = Vector3.Lerp(origPos, targetPos, elapsedTime / timeToMove);
            elapsedTime += Time.deltaTime;
            yield return null;
        }
        transform.position = targetPos;
        isMoving = false;
    }
}

Make sure your player has a collider (like a BoxCollider) and that obstacle objects have colliders set to "Is Trigger" disabled.

Reliable Learning Resources for Pokémon-Style Games

Since you mentioned struggling with unhelpful tutorials, here are some trustworthy places to learn (all within Unity's ecosystem or well-respected developer communities):

  • Unity Learn Official Tutorials: The official Unity Learn platform has a dedicated 2D RPG series that covers grid movement, collision, and other core systems similar to Pokémon. Look for courses tagged "Grid-Based Movement" or "2D RPG".
  • Unity Forums: The official Unity Forums have a dedicated "Game Development" section where you can ask specific questions, and many experienced developers share step-by-step guides for grid movement systems.
  • Unity Asset Store Sample Projects: Some free sample projects on the Asset Store focus on top-down grid-based games—downloading these lets you dissect working code and see how professionals implement movement and collision.
  • Curated YouTube Creator Series: Look for creators who specialize in Unity 2D tutorials and have a track record of clear, tested code (avoid one-off videos with untested scripts). Many creators break down Pokémon-style systems piece by piece, from movement to battle mechanics.

Final Tips for Beginners

  • Start small: Don't try to build the entire Pokémon game at once. Focus on getting movement working first, then add collision, then NPC interactions, etc.
  • Use debug tools: Unity's Debug.DrawRay or Debug.DrawCube can help you visualize your collision checks and make sure your target positions are correct.
  • Read Unity's official documentation: The docs for Physics.OverlapBox, Coroutines, and Vector3 are your best friends—they explain exactly how each function works and give examples.

内容的提问来源于stack exchange,提问作者cireon

火山引擎 最新活动