You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中同标签敌人碰撞墙体后单独转向的问题求助

问题分析与解决方案

问题根源

你的代码里每帧Update都会调用EnemyMoveDirection(),强制将当前敌人的方向设置为EnemySpawner中的全局变量enemyMoveDirection,这就导致所有敌人共享同一个方向值——哪怕某个敌人撞墙后改了自己的enemyMovementDirection,下一秒也会被Spawner的全局值覆盖,最终表现为所有敌人一起转向。

修复步骤

  1. 初始方向只在Start()中从Spawner获取一次,之后每个敌人用自己的enemyMovementDirection独立维护方向
  2. 修改EnemyMoveDirection()逻辑,不再每帧从Spawner拉取全局方向,仅使用当前敌人自身的方向变量计算移动

修改后的完整代码

using UnityEngine;

public class EnemyMovement : MonoBehaviour
{
    [SerializeField]
    private float movementSpeed = 3f;
    public Rigidbody2D enemyRB;
    private EnemySpawner enemySpawner;
    private float timer = 0f;
    private float enemyDestroyTime = 30f;
    private int enemyMovementDirection;

    void Start()
    {
        enemySpawner = FindAnyObjectByType<EnemySpawner>();
        enemyRB = GetComponent<Rigidbody2D>();
        
        // 仅在初始化时从Spawner获取初始方向,之后不再依赖全局变量
        enemyMovementDirection = enemySpawner.enemyMoveDirection;
    }

    void EnemyMoveDirection()
    {   
        // 使用当前敌人自身的方向变量计算移动
        Vector2 movement = new Vector2(movementSpeed * enemyMovementDirection, enemyRB.velocity.y);
        enemyRB.velocity = movement;
    }

    void Update()
    {
        EnemyMoveDirection();
        
        timer += Time.deltaTime;
        if (timer >= enemyDestroyTime)
        {
            DestroyEnemy();
            enemyDestroyTime += 30f;
        }
    }
    
    private void DestroyEnemy()
    {
        if (enemyRB != null)
        {
            Destroy(gameObject);
            enemySpawner.spawnCount--;
        }
    }
    
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("LeftWall"))
        {
            enemyMovementDirection = 1;
        }

        if (collision.gameObject.CompareTag("RightWall"))
        {
            enemyMovementDirection = -1;
        }
    }
}

额外优化建议

可以把EnemySpawner的enemyMoveDirection改成在生成敌人时直接传递给EnemyMovement组件,而不是让敌人自己去FindSpawner获取,这样更高效也更解耦。示例逻辑:
在EnemySpawner的生成代码中:

GameObject newEnemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
EnemyMovement enemyMove = newEnemy.GetComponent<EnemyMovement>();
enemyMove.SetInitialDirection(spawnDirection); // spawnDirection是当前敌人的初始方向(1或-1)

然后在EnemyMovement中添加方法:

public void SetInitialDirection(int direction)
{
    enemyMovementDirection = direction;
}

这样就不需要在EnemyMovement里调用FindAnyObjectByType<EnemySpawner>(),彻底避免全局变量依赖。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:55:26