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

Unity Tilemap实现鼠标悬停瓦片透明度变化的问题

解决Unity Tilemap鼠标悬停变淡并恢复的问题

原代码的核心问题

  • 未做空值判断:鼠标移出Tilemap范围时,currentTile为空,直接访问currentTile.color会触发空引用异常
  • 修改共享Tile资源:Tile是全局复用的资源,直接修改其color会导致所有使用该Tile的瓦片同步变透明,而非仅当前 hover 的单个瓦片
  • 缺失原始状态记录:没有保存瓦片初始透明度,鼠标离开后无法恢复原状态
  • 无离开逻辑:Update循环中持续设置透明度,没有判断鼠标是否已离开瓦片的逻辑

修正方案

使用Tilemap.SetColor()方法单独修改指定位置瓦片的显示颜色(不影响原始Tile资源),同时记录上一个 hover 的瓦片位置与初始颜色,实现鼠标离开时的状态恢复。

完整修正代码

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

public class MouseHoverTiles : MonoBehaviour
{
    [Header("组件引用")]
    [SerializeField] private Tilemap groundMap;
    [SerializeField] private Camera mainCam;

    [Header("悬停参数")]
    [SerializeField] private float hoverAlpha = 0.75f;

    private Vector3Int _lastHoveredTilePos;
    private Dictionary<Vector3Int, Color> _originalTileColors = new Dictionary<Vector3Int, Color>();

    void Update()
    {
        // 将鼠标屏幕坐标转换为世界坐标,修正Z轴(Tilemap的Z轴通常为0)
        Vector3 mouseWorldPos = mainCam.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0;

        // 转换为Tilemap的单元格坐标
        Vector3Int currentTilePos = groundMap.WorldToCell(mouseWorldPos);

        // 检查当前位置是否有瓦片,且与上一个hover位置不同
        if (groundMap.HasTile(currentTilePos))
        {
            // 首次hover该瓦片时,记录原始颜色
            if (!_originalTileColors.ContainsKey(currentTilePos))
            {
                _originalTileColors[currentTilePos] = groundMap.GetColor(currentTilePos);
            }

            // 仅当当前瓦片未处于悬停状态时,设置透明效果
            if (currentTilePos != _lastHoveredTilePos)
            {
                // 恢复上一个瓦片的原始颜色
                if (_originalTileColors.ContainsKey(_lastHoveredTilePos))
                {
                    groundMap.SetColor(_lastHoveredTilePos, _originalTileColors[_lastHoveredTilePos]);
                }

                // 设置当前瓦片的悬停透明效果
                Color originalColor = _originalTileColors[currentTilePos];
                groundMap.SetColor(currentTilePos, new Color(originalColor.r, originalColor.g, originalColor.b, hoverAlpha));

                // 更新上一个hover位置
                _lastHoveredTilePos = currentTilePos;
            }
        }
        else
        {
            // 鼠标不在Tilemap范围内时,恢复上一个瓦片的颜色
            if (_originalTileColors.ContainsKey(_lastHoveredTilePos))
            {
                groundMap.SetColor(_lastHoveredTilePos, _originalTileColors[_lastHoveredTilePos]);
                _originalTileColors.Remove(_lastHoveredTilePos);
                _lastHoveredTilePos = Vector3Int.zero;
            }
        }
    }
}

使用说明

  1. 将脚本挂载到场景中任意GameObject上
  2. 在Inspector面板中赋值groundMap(目标Tilemap组件)和mainCam(主相机)
  3. 可通过hoverAlpha参数调整悬停时的透明度(0为完全透明,1为不透明)
  4. 确保Tilemap使用的瓦片支持颜色修改(如Unity内置的Sprite Tile)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:24:27