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; } } } }
使用说明
- 将脚本挂载到场景中任意GameObject上
- 在Inspector面板中赋值
groundMap(目标Tilemap组件)和mainCam(主相机) - 可通过
hoverAlpha参数调整悬停时的透明度(0为完全透明,1为不透明) - 确保Tilemap使用的瓦片支持颜色修改(如Unity内置的
Sprite Tile)
内容的提问来源于stack exchange,提问作者Sam_003
相关产品推荐
相关产品推荐

