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

Unity预制体实例化异常求助:Tilemap道具显示错误

实例化Tilemap预制体时硬币异常消失/动画意外显示的问题

我不确定该将此问题发布到哪个板块,因为它可能涉及脚本编写、Tilemap建模或预制体配置问题。我在每个Tilemap的右侧设置了一个Tilemap生成器,用于实例化包含硬币、苹果等收集道具的Tilemap预制体。但有时生成会出现异常:部分硬币消失,或者收集道具的子对象(收集动画)意外显示。这类问题仅出现在硬币上,我使用了包含2-5个硬币的组预制体,推测问题可能与此相关。请问为何实例化预制体时会出现这类异常?

附相关脚本

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

/**
 * Script para generar Tilemaps dependiendo del objeto padre.
 * Por ejemplo: Tutorial -> Comienzo, Comienzo -> Aleatorio y Aleatorio -> Aleatorio
 **/
public class GeneratorTimelap : MonoBehaviour
{
    [SerializeField] private GameObject[] tilemapAleatorios;
    [SerializeField] private GameObject[] tilemapTutorial;
    [SerializeField] private GameObject[] tilemapComienzo;

    [SerializeField] private Transform localizacionGenerar;
    [SerializeField] private GameObject gridObject;

    private Transform objetoPadre;

    private void Start()
    {
        objetoPadre = transform.parent;
        gridObject = GameObject.FindGameObjectWithTag("Grid");
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Horizonte"))
        {
            if (objetoPadre.CompareTag("TilemapTutorial"))
            {
                int numAleatorio = Random.Range(0, tilemapComienzo.Length);
                GameObject tilemapGenerado = Instantiate(tilemapComienzo[numAleatorio], gridObject.transform);
                tilemapGenerado.transform.position = localizacionGenerar.transform.position;
            }

            if (objetoPadre.CompareTag("TilemapComienzo") || objetoPadre.CompareTag("TilemapAleatorio"))
            {
                int numAleatorio = Random.Range(0, tilemapAleatorios.Length);
                GameObject tilemapGenerado = Instantiate(tilemapAleatorios[numAleatorio], gridObject.transform);
                tilemapGenerado.transform.position = localizacionGenerar.transform.position;
            }
        }
    }
}

补充说明

  • 之前在左侧边缘设置了销毁生成对象的脚本,禁用该对象后问题依旧。
  • 玩家持续向右移动,仅能跳跃,曾怀疑是玩家速度问题,但可能性不大。

问题排查与解决方案

1. 预制体本身的状态异常

  • 检查硬币组预制体内的硬币对象:是否有部分被误设为SetActive(false),或者收集动画组件的PlayOnAwake被错误勾选,导致实例化时直接触发动画。
  • 确认硬币的渲染组件、碰撞体是否在预制体中处于启用状态,排除编辑模式下的误操作。

2. 实例化坐标与层级冲突

  • Tilemap的坐标需要匹配Grid的单元格尺寸,若localizacionGenerar的坐标不是Grid的整数倍,可能导致硬币Tile偏移到不可见区域,或与其他Tilemap重叠被覆盖。建议改用Grid坐标系统设置位置,或调用tilemapGenerado.GetComponent<Tilemap>().RefreshAllTiles()强制刷新。
  • 检查生成的Tilemap排序层,确保其层级高于其他可能遮挡它的对象,避免硬币被其他Tile挡住。

3. 触发逻辑重复执行

OnTriggerEnter2D可能被多次触发,导致同一位置重复实例化Tilemap,新的硬币组覆盖旧的,看起来像硬币消失。可以添加触发标记避免重复:

private bool hasGenerated = false;

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Horizonte") && !hasGenerated)
    {
        hasGenerated = true;
        // 原有生成逻辑...
    }
}

4. 收集脚本的残留状态

如果硬币带有收集逻辑脚本,可能在预制体编辑时误触发了收集流程,导致预制体保存时硬币处于已收集状态。建议:

  • 让收集脚本仅在运行时初始化状态,比如在Start()方法中重置硬币的激活状态和动画状态。
  • 收集逻辑采用对象池或销毁对象的方式,而非直接禁用,避免预制体保存禁用状态。

5. Tilemap渲染批处理问题

Unity批量生成Tilemap时可能出现渲染异常,实例化后强制刷新Tilemap状态:

GameObject tilemapGenerado = Instantiate(/*...*/);
tilemapGenerado.GetComponent<Tilemap>().RefreshAllTiles();

同时检查硬币Sprite的导入设置,确保Read/Write Enabled选项开启,避免渲染丢失。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:54:54