Unity | Tilemap系统

目录

一、准备工作

1.插件导入

2.资源导入

 二、相关组件介绍

1.Grid组件

2.Tilemap组件

3.Tile

4.Tile Palette

5.Brushes

三、动态创建地图

四、其他功能

1.移动网格上物体

2.拖拽缩放地图


        Unity Tilemap系统为2D游戏开发提供了一个直观且功能强大的平台,使得创建复杂且美观的游戏世界变得更加容易,Unity的Tilemap系统经过优化,能够高效地处理大量Tiles,确保游戏在各种设备上都能流畅运行。

一、准备工作

1.插件导入

2.资源导入

        提供一个我找了半天才找到的tile图像资源。因为我要做等距透视地图,所以需要是菱形,并且图片长=宽。

        当最终绘制的地图不合适时,可以调整图像的Pivot:

 二、相关组件介绍

1.Grid组件

        Grid组件是Unity中用于创建和管理网格(Grid)的基础组件,特别适用于2D游戏开发中的Tilemap系统。网格布局可以是矩形、六边形等。

  • Cell Size

        开发者可以定义每个网格单元的大小。这对于确保Tiles和其他元素在正确的位置上显示非常重要。

  • Cell Gap

        允许开发者在网格单元之间设置间隙,从而调整元素之间的距离。这样可以创建更复杂的布局效果。

  • CellLayout 

        枚举包括以下几种布局类型:

  1. Rectangle:矩形布局。单元格以矩形的形式排列,这是最常见的一种布局方式。
  2. Hexagon:六边形布局。单元格以六边形的形式排列,通常用于需要六边形网格的游戏或应用。
  3. Isometric:等距菱形布局。单元格以等距(菱形)的形式排列,常用于等距视角的游戏,例如模拟类游戏。
  4. IsometricZAsY:等距Z轴作为Y轴布局。这种布局类似于等距布局,但Z轴值将被添加为Y值。这种布局通常用于需要特殊等距视角效果的场景。
  • cellSwizzle

        用于重新排列网格单元格的坐标。具体来说, 允许将默认的 XYZ 单元格坐标重新排序为不同的排列方式。以下是一些可能的重排选项:

  1. XYZ:保持单元格位置不变。
  2. XZY:将单元格位置从 XYZ 重排为 XZY。
  3. YXZ:将单元格位置从 XYZ 重排为 YXZ。
  4. YZX:将单元格位置从 XYZ 重排为 YZX。
  5. ZXY:将单元格位置从 XYZ 重排为 ZXY。
  6. ZYX:将单元格位置从 XYZ 重排为 ZYX。

        Grid组件通常与Tilemap组件一起使用,以实现复杂的2D场景设计。Tilemap会自动对齐到Grid定义的网格上,使得绘制和管理Tiles变得更加容易。Grid组件提供了一些方便的方法,用于在世界坐标、局部坐标和网格坐标之间进行转换。这使得在网格上定位对象变得更加简单和直观。

        总结来说,Grid组件为Unity中的2D游戏开发提供了一个强大且灵活的基础结构,使得创建和管理基于网格的场景变得更加简单和高效。

2.Tilemap组件

        Unity的Tilemap系统是一个强大的工具,用于在2D游戏开发中创建和管理网格化的游戏世界。Tilemap组件是用于在场景中绘制瓦片(Tiles)的基础组件。它可以与Grid组件一起使用,以定义网格的大小和形状。

3.Tile

        Tilemap系统中的基本构建块。每个Tile代表一个小的图像或动画,可以重复使用来创建更大的图案或场景。Tiles可以包含碰撞信息、颜色等属性。

4.Tile Palette

        一个用户界面工具,允许开发者创建、编辑和管理Tiles。开发者可以将Tiles拖放到Tile Palette中,然后使用画笔工具将它们绘制到Tilemap上。

5.Brushes

        Brushes是用于在Tilemap上绘制Tiles的工具。Unity提供了多种预定义的Brushes,例如普通画笔、随机画笔等,开发者也可以创建自定义Brushes以满足特定需求。

  • Default Brush:默认的绘画刷,用于基本的Tile绘制操作。
  • GameObject Brush:用于在Tilemap上绘制GameObjects,而不仅仅是Tiles。
  • Group Brush:允许用户将多个Tiles组合在一起,并作为一个整体进行绘制。
  • Random Brush:可以随机选择预定义的Tiles进行绘制,适合创建更自然和多样化的Tilemap。
  • Line Brush:用于绘制直线形状的Tiles,方便创建路径或直线结构。

        总之,Unity Tilemap系统为2D游戏开发提供了一个直观且功能强大的平台,使得创建复杂且美观的游戏世界变得更加容易,Unity的Tilemap系统经过优化,能够高效地处理大量Tiles,确保游戏在各种设备上都能流畅运行。

三、动态创建地图

1.创建空物体Grid,添加Grid组件。

2.创建Grid的子物体Tilemap,添加Tilemap及Tilemap Renderer组件。

3.代码展示。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;public class CreatTail : MonoBehaviour
{public Tilemap tilemap;public TileBase[] tiles; // 一个包含多个不同类型瓦片的数组int tileIndex = 0;private void Start(){GenerateMap();}void GenerateMap(){for (int x = 0; x < 20; x++){for (int y = 0; y < 21; y++){tileIndex = tileIndex == 0 ? 1 : 0;SetTile(new Vector3Int(x - 10, -y + 10, 0), tiles[tileIndex]);}}#if UNITY_EDITORstring prefabPath = "Assets/Prefabs/Tilemap.prefab";//动态制作预制体UnityEditor.PrefabUtility.SaveAsPrefabAsset(tilemap.gameObject, prefabPath);#endif}void SetTile(Vector3Int position, TileBase tile){tilemap.SetTile(position, tile);}
}

4.效果展示

四、其他功能

1.移动网格上物体

        可移动的物体设置layer为第7层,并将下方代码拖到该物体身上。当移动物体时,如果目标格子有物体,则不能放置。

using UnityEngine;
using UnityEngine.Tilemaps;public class DragManager : MonoBehaviour
{private bool isDragging = false;private Vector3 offset;private Camera mainCamera;private Vector3 lastPos;void Start(){mainCamera = Camera.main;}void OnMouseDown(){isDragging = true;offset = transform.position - GetMouseWorldPosition();lastPos=transform.position;}void OnMouseUp(){isDragging = false;// 获取鼠标位置对应的Tilemap位置Tilemap tilemap = FindObjectOfType<Tilemap>();Vector3Int cellPosition = tilemap.WorldToCell(GetMouseWorldPosition());// 将物体放置到格子中心//transform.position = tilemap.GetCellCenterWorld(cellPosition);//transform.position=new Vector3 (transform.position.x,transform.position.y,0);Vector3 targetPosition = tilemap.GetCellCenterWorld(cellPosition);targetPosition.z = 0;Collider2D[] hitCollider = Physics2D.OverlapPointAll((Vector2)targetPosition);if (hitCollider.Length<=0){transform.position = targetPosition;}else{Debug.Log("Target position already occupied by another object.");foreach (var item in hitCollider){Debug.Log(item.name);}if (hitCollider.Length==1&& hitCollider[0].name==transform.name){transform.position = targetPosition;}else{transform.position = lastPos;}}}void Update(){if (isDragging){Vector3 targetPosition = GetMouseWorldPosition() + offset;targetPosition.z = -1;transform.position = targetPosition;}}private Vector3 GetMouseWorldPosition(){Vector3 mouseScreenPosition = Input.mousePosition;mouseScreenPosition.z = -9;// mainCamera.nearClipPlane; // 确保z轴值正确return mainCamera.ScreenToWorldPoint(mouseScreenPosition);}
}

2.拖拽缩放地图

        拖拽地图时,如果焦点在物体身上,则不拖拽。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameController : MonoBehaviour
{public float zoomSpeed = 0.1f;  // 缩放速度public float minZoom = 1f;    // 最小缩放值public float maxZoom = 3f;      // 最大缩放值private Vector2 dragOrigin;private Camera mainCamera;public bool drag;public float mapLength = 10f;   public float mapWidth = 10f;private void Start(){mainCamera = Camera.main;maxZoom = mainCamera.orthographicSize;}void Update(){
#if UNITY_EDITOR || UNITY_STANDALONEHandleMouseInput();
#elif UNITY_ANDROID || UNITY_IOSHandleTouchInput();
#endif}#if UNITY_EDITOR || UNITY_STANDALONEprivate void HandleMouseInput(){// 放大/缩小if (Input.mouseScrollDelta.y != 0){//Debug.Log(Input.mouseScrollDelta.y);Zoom(Input.mouseScrollDelta.y * zoomSpeed);}// 拖拽屏幕if (Input.GetMouseButtonDown(0)){Vector3 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition);RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero, 100, 1 << 7);// 检查是否有物体被射线击中if (hit.collider != null){Debug.Log("Hit " + hit.collider.gameObject.name);}else{dragOrigin = Input.mousePosition;drag = true;}return;}//if (Input.GetMouseButtonDown(0))//{//    dragOrigin = Input.mousePosition;//    return;//}if (!Input.GetMouseButton(0)) { drag = false;return; }if (drag){Vector3 difference = mainCamera.ScreenToViewportPoint((Vector2)Input.mousePosition - dragOrigin);Vector3 move = new Vector3(difference.x * mainCamera.orthographicSize, difference.y * mainCamera.orthographicSize, 0);mainCamera.transform.Translate(-move, Space.World);dragOrigin = Input.mousePosition;}}
#endif#if UNITY_ANDROID || UNITY_IOSprivate void HandleTouchInput(){if (Input.touchCount == 2){Touch touchZero = Input.GetTouch(0);Touch touchOne = Input.GetTouch(1);Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;float prevMagnitude = (touchZeroPrevPos - touchOnePrevPos).magnitude;float currentMagnitude = (touchZero.position - touchOne.position).magnitude;float difference = currentMagnitude - prevMagnitude;Zoom(difference * zoomSpeed);}if (Input.touchCount == 1){Touch touch = Input.GetTouch(0);if (touch.phase == TouchPhase.Began){Vector3 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition);RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero, 100, 1 << 7);//只检测可拖拽的物体层if (hit.collider != null){Debug.Log("Hit " + hit.collider.gameObject.name);}else //没有点击到物体,则拖拽屏幕{dragOrigin = touch.position;drag = true;}return;}if (touch.phase != TouchPhase.Moved){drag = false;return;}if (drag){Vector3 difference = mainCamera.ScreenToViewportPoint(touch.position - dragOrigin);Vector3 move = new Vector3(difference.x * mainCamera.orthographicSize, difference.y * Camera.main.orthographicSize, 0);mainCamera.transform.Translate(-move, Space.World);dragOrigin = touch.position;}}}
#endifprivate void Zoom(float increment){
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_ANDROID || UNITY_IOSCamera.main.orthographicSize = Mathf.Clamp(mainCamera.orthographicSize - increment, minZoom, maxZoom);
#endif}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【知识点】std::thread::detach std::lock_guard std::unique_lock

在 C11 中&#xff0c;std::thread 提供了并发编程的基础设施&#xff0c;使得我们可以创建和管理线程。std::thread 的 detach 方法是一种常用的线程管理方式&#xff0c;允许线程在后台独立运行&#xff0c;而不必与主线程同步或等待其完成。 std::thread::detach 方法 当你…

【LeetCode最详尽解答】125-验证回文串 Valid-Palindrome

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 链接: 125-验证回文串 直觉 这个问题需要使用一些内置函数&#xff0c;比如 s[l].isalnum() 和 s[l].…

springboot整合security

整合Spring Security到Spring Boot项目中可以帮助你实现认证&#xff08;Authentication&#xff09;和授权&#xff08;Authorization&#xff09;&#xff0c;从而保护你的应用程序资源和数据。下面是一个基本的步骤指南&#xff0c;帮助你在Spring Boot项目中整合和配置Spri…

Docker运行 Redis、Mysql、Nginx、MongoDB、Minio等

Redis 挂载文件&#xff0c;自行选择 wget http://download.redis.io/redis-stable/redis.conf 创建对应的文件 mkdir -p /docker/redis/data mkdir -p /docker/redis/conf touch /docker/redis/conf/redis.conf # redis.conf什么的都不能是空docker pull redis:6.0.8dock…

Web前端真实简历:深入解析关键要点与技巧

Web前端真实简历&#xff1a;深入解析关键要点与技巧 在数字化快速发展的今天&#xff0c;Web前端技术已成为互联网行业的核心领域之一。一份真实而引人注目的Web前端简历&#xff0c;对于求职者来说至关重要。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入…

C++ 55 之 多继承

#include <iostream> #include <string> using namespace std;class Base08_1{ public:int m_a;Base08_1(){this->m_a 10;} };class Base08_2{ public:// int m_b;int m_a;Base08_2(){// this->m_b 20;this->m_a 30;} };// 多继承 继承的类型都要…

GenICam标准(一)

系列文章目录 GenICam标准&#xff08;一&#xff09; GenICam标准&#xff08;二&#xff09; GenICam标准&#xff08;三&#xff09; GenICam标准&#xff08;四&#xff09; GenICam标准&#xff08;五&#xff09; GenICam标准&#xff08;六&#xff09; 文章目录 系列文…

非对称加密系统解析

目录 1. 概述 2. 非对称加密标准 2.1 RSA 2.2 SM2 2.2.1 SM2私钥 2.2.2 SM2公钥 2.2.3 加密数据格式 2.2.4 签名数据格式 1. 概述 非对称加密中&#xff0c;密钥分为加密密钥和解密密钥两种。发送者用加密密钥对消息进行加密&#xff0c;接收者用解密密钥对密文进行解密…

Zookeeper:客户端命令行操作

文章目录 一、help二、ls path三、create四、get path五、set六、stat七、delete八、deleteall 一、help 显示所有操作命令。 二、ls path 使用ls命令来查看当前znode的子节点[可监听] w&#xff1a;监听子节点变化。s&#xff1a;附加次级信息。 三、create 普通创建&am…

DOM的概念?获取html元素的方法有哪些?

Dom文档对象模型&#xff0c;对js的HTML具有操作能力。 获取HTML的方法&#xff1a; Document.getElementById(‘’) 通过元素 id 来查找元素&#xff1b; Document.getElementsByClassName(‘’) 通过类名来查找元素; Document.getElementsByName(‘’) 通过表单元素中 na…

element--el-table添加合计后固定列x轴滚动条无法滚动问题

效果图 改变固定列滚轮高度问题 解决文章 解决方案 使用到的参数 pointer-events 属性用来控制一个元素能否响应鼠标操作&#xff0c;常用的关键字有 auto 和 none pointer-events: none; 让一个元素忽略鼠标操作 pointer-events: auto; 还原浏览器设定的默认行为 代码演示 添…

web前端网上私活:探索、挑战与成长的独特之旅

web前端网上私活&#xff1a;探索、挑战与成长的独特之旅 在这个数字化飞速发展的时代&#xff0c;Web前端网上私活成为了越来越多开发者的选择。它不仅仅是一种获取额外收入的方式&#xff0c;更是一种挑战自我、提升技能、拓宽视野的独特旅程。接下来&#xff0c;我将从四个…

JVM-GC-基础知识

JVM-GC-基础知识 前言 JVM中的GC使用Root Searching寻找垃圾单独方式&#xff0c;并结合mark-sweep、copying、mark-compact三种清除算法形成了各有特点的垃圾回收器&#xff0c;且垃圾回收器的演变过程是因为内存空间的不断增大的必然原因。 JVM-GC的发展史 JVM垃圾回收分…

解释时间复杂度和空间复杂度的概念

在算法和数据结构的学习中&#xff0c;时间复杂度和空间复杂度是两个至关重要的概念。它们用于衡量算法在执行过程中所需要的时间和空间资源。下面我将从技术难点、面试官关注点、回答吸引力以及代码举例四个方面来详细解释这两个概念。 一、技术难点 时间复杂度 定义与理解…

Python文本处理:初探《三国演义》

Python文本处理&#xff1a;初探《三国演义》 三国演义获取文本文本预处理分词与词频统计引入停用词后进行词频统计分析人物出场次数结果可视化完整代码 三国演义 《三国演义》是中国古代四大名著之一&#xff0c;它以东汉末年到晋朝统一之间的历史为背景&#xff0c;讲述了魏…

Mongodb使用$pop删除数组中的元素

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第67篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…

使用PyTorch实现LSTM生成ai诗

最近学习torch的一个小demo。 什么是LSTM&#xff1f; 长短时记忆网络&#xff08;Long Short-Term Memory&#xff0c;LSTM&#xff09;是一种循环神经网络&#xff08;RNN&#xff09;的变体&#xff0c;旨在解决传统RNN在处理长序列时的梯度消失和梯度爆炸问题。LSTM引入了…

vue格网图

先看效果 再看代码 <n-gridv-elsex-gap"20":y-gap"20"cols"2 s:2 m:3 l:3 xl:3 2xl:4"responsive"screen" ><n-grid-itemv-for"(item,index) in newSongList":key"item.id"class"cursor-pointer …

C# OpenCvSharp Mat操作-创建Mat-ones

ones 函数用于创建一个全为“1”的矩阵&#xff08;Mat&#xff09;&#xff0c;可以用于各种图像处理和计算机视觉任务。下面我将详细解释每个重载版本的 ones 函数&#xff0c;并提供相应的示例代码。&#x1f4f8; 1️⃣ ones(int rows, int cols, int type) 这个重载函数…

VS - regsvr32.exe的官方工程

文章目录 VS - regsvr32.exe的官方工程概述笔记官方原版实现自己封装一个函数来干活(注册/反注册 COM DLL)END VS - regsvr32.exe的官方工程 概述 如果是要使用COM DLL&#xff0c; 必须先注册。 一般手工注册就要调用regsvr32.exe xx.dll 但是控制的不够细&#xff0c;且一般…