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

Unity重构破碎墙体脚本后移动功能失效求助

问题分析与修复:拆分移动逻辑后Unity立方体停止移动的原因

咱们先理清楚你遇到的问题:原来的代码里立方体正常移动,但把_WallMovement.initializeMovement()拆到独立的wallMoving()函数后,立方体就不动了,只有在wallMoving()里重新写indizes[0] = x才会部分生效,而且控制台没报错。

核心原因:数组是引用类型,你不小心共享了同一个数组实例

你在newWallMovement()里用的是同一个indizes数组,然后把它赋值给每个WallMovement组件。因为数组是引用类型,所有组件的indizes字段其实指向的是内存里的同一个数组。

当newWallMovement()的循环结束后,这个数组里的x值已经变成了循环的最后一个值(也就是oldWallsizeX-2)。等你在wallMoving()里调用initializeMovement()时,所有立方体拿到的都是这个最后一次循环的x值,自然不会执行正确的移动逻辑。

而当你在wallMoving()里重新加indizes[0] = x时,只有当前循环的x对应的那一批立方体的数组值被临时修改,所以才会部分生效——但这依然是共享数组的问题,不是正确的解决方式。

修复方案:给每个立方体分配独立的数组(或简化数据结构)

这里有两种更可靠的修复方式,你可以选适合自己的:

方案1:为每个立方体创建独立的数组实例

修改newWallMovement(),每次循环都新建一个数组,这样每个WallMovement拿到的都是属于自己的数组,不会被后续循环覆盖:

void newWallMovement() {
    for (int x = 1; x < oldWallsizeX-1; x++) {
        for (int y = 0; y < oldWallsizeY; y++) {
            for (int z = 0; z < oldWallsizeZ; z++) {
                // 为当前立方体创建专属数组
                int[] cubeIndizes = new int[3];
                cubeIndizes[0] = x;
                cubeIndizes[1] = y;
                cubeIndizes[2] = z;
                
                newWall = wallSegments[x,y,z];
                GameObject _wallSegment = newWall.gameObject;
                WallMovement _WallMovement = _wallSegment.GetComponent<WallMovement>();
                _WallMovement.indizes = cubeIndizes;
            }
        }
    }
}

然后你的wallMoving()就可以保持原样,只需要遍历所有立方体调用initializeMovement()就行:

void wallMoving(){
    for (int x = 1; x < oldWallsizeX-1; x++) {
        for (int y = 0; y < oldWallsizeY; y++) {
            for (int z = 0; z < oldWallsizeZ; z++) {
                newWall = wallSegments[x,y,z];
                WallMovement _WallMovement = newWall.GetComponent<WallMovement>();
                _WallMovement.initializeMovement();
            }
        }
    }
}

方案2:简化数据结构,避免使用数组(更推荐)

看你的WallMovement脚本,其实只用到了indizes[0](也就是x索引)来计算modulo,完全没必要用数组。咱们直接把indizes换成单独的字段,更清晰也不会有引用问题:

首先修改WallMovement脚本:

public class WallMovement : MonoBehaviour {
    public int xIndex; // 直接存储需要的x索引
    int modulo;

    public void initializeMovement() {
        modulo = xIndex % 2;
        if (modulo > 0) {
            // 执行奇数x的移动逻辑
        } else {
            // 执行偶数x的移动逻辑
        }
    }
}

然后修改newWallMovement()里的赋值逻辑:

void newWallMovement() {
    for (int x = 1; x < oldWallsizeX-1; x++) {
        for (int y = 0; y < oldWallsizeY; y++) {
            for (int z = 0; z < oldWallsizeZ; z++) {
                newWall = wallSegments[x,y,z];
                WallMovement _WallMovement = newWall.GetComponent<WallMovement>();
                _WallMovement.xIndex = x; // 直接赋值x索引
            }
        }
    }
}

这样不仅解决了问题,代码可读性也更高,还减少了不必要的数组操作。

额外优化:简化wallMoving()的遍历逻辑

你可以用foreach遍历wallSegments数组,避免重复嵌套循环,代码更简洁:

void wallMoving(){
    foreach (Transform segment in wallSegments) {
        if (segment == null) continue; // 跳过空引用
        WallMovement movement = segment.GetComponent<WallMovement>();
        if (movement != null) {
            movement.initializeMovement();
        }
    }
}

这样不管数组的维度是多少,都能遍历到所有立方体,维护起来更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:53:11