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

为何设置Scale为1时GameObject方块的实际缩放比例却接近6?

问题:Unity瓦片网格创建后全部重叠

我尝试用GameObject方块制作游戏瓦片网格,但进入Play Mode后所有方块都重叠在一起。我调整了第一个瓦片的X、Y位置来展示缩放问题。

测试网格用的示例PNG精灵

我只用到了Create.cs和Node.cs两个脚本,Create.cs挂载在WorldContinent对象上,这个对象位置是(0,0,0)、缩放(1,1,1)且没有渲染器。我额外加了设置localScale的代码试图解决问题,但Node类完全不影响缩放。

下面是Create.cs代码:

using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;

public class Create : MonoBehaviour
{
    //tile found in assets/prefabs/world/tile
    public GameObject gameTile;

    int rows;
    int columns;
    List<Node[]> rowsList = new List<Node[]>();
    Node node;
    int _row;
    int _column;
    float spacing = 1.0f;


    void Start()
    {
        rows = 3;
        columns = 3;

        TurnRowsAndColumnsIntoTilesAndNodes();
    }

    private void TurnRowsAndColumnsIntoTilesAndNodes()
    {
        for (int row = 0; row < rows; row++)
        {
            rowsList.Add(new Node[columns]);

            for (int column = 0; column < columns; column++)
            {
                _row = row;
                _column = column;
                GameObject newTile = NodeAndTileInstatiator();
                rowsList[_row][_column] = node;
                MakeConnectionsToNeighborNodes();
                newTile.transform.localScale = new Vector3(1, 1, 1);
            }
        }
    }

    private GameObject NodeAndTileInstatiator()
    {
        float row = _row * spacing;
        float column = _column * spacing;

        Vector3 position = new Vector3(row, column, 0);


        GameObject newTIle = Instantiate(gameTile, position, Quaternion.identity);

        node = new Node(newTIle);
        return newTIle;
    }
}

问题原因及修复方案

核心问题

  1. 位置计算未考虑瓦片自身尺寸:仅用固定spacing=1.0f计算位置,若瓦片实际尺寸大于1,必然导致重叠。
  2. 依赖类成员变量传递循环索引:_row和_column作为类成员,虽当前逻辑未出时序问题,但易引发潜在bug。
  3. 预制体可能存在缩放异常:若gameTile预制体缩放非(1,1,1),会导致位置计算基准错误。

修复步骤

1. 基于瓦片尺寸动态计算位置

先获取瓦片的实际尺寸,再结合索引计算每个瓦片的位置,确保间距足够避免重叠:

// 在NodeAndTileInstatiator方法中添加尺寸获取逻辑
private GameObject NodeAndTileInstatiator(int row, int column)
{
    // 获取瓦片SpriteRenderer的边界尺寸(若用Collider则替换为对应组件)
    SpriteRenderer tileRenderer = gameTile.GetComponent<SpriteRenderer>();
    float tileWidth = tileRenderer.bounds.size.x;
    float tileHeight = tileRenderer.bounds.size.y;

    // 计算位置:索引 × (瓦片尺寸 + 额外间距),可根据需求调整行/列对应X/Y轴的关系
    float posX = column * (tileWidth + spacing);
    float posY = row * (tileHeight + spacing);
    Vector3 position = new Vector3(posX, posY, 0);

    GameObject newTile = Instantiate(gameTile, position, Quaternion.identity);
    // 将瓦片设为当前对象的子物体,优化场景层级
    newTile.transform.parent = transform;
    node = new Node(newTile);
    return newTile;
}

2. 直接传递循环索引参数

修改循环内的方法调用,避免依赖类成员变量:

// 在TurnRowsAndColumnsIntoTilesAndNodes的内层循环中修改
GameObject newTile = NodeAndTileInstatiator(row, column);

3. 重置预制体缩放

检查gameTile预制体的缩放属性,确保其localScale为(1,1,1),若有缩放偏差先重置,再通过调整Sprite尺寸来修改瓦片大小。

4. 完善邻接节点连接逻辑

若后续实现MakeConnectionsToNeighborNodes方法,需基于当前循环的row和column参数去查找相邻节点,避免使用类成员变量导致的索引混乱。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:12:22