
比较基本的动态加载卸载Tilemap,适用于沙盒游戏等,加载大地图数据的场景。
生成图格数据类
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class tilemaptest : MonoBehaviour
{
public static tilemaptest instance;
public Tilemap tilemap;
public TileBase tile;
public Dictionary> tileDic = new Dictionary>();//图格数据
public int size = 10;//格子大小
public int X_Min = -100;
public int X_Max = 100;
public int Y_Min = -100;
public int Y_Max = 100;
private void Awake()
{
if (instance == null)
{
instance = this;
}else
{
Destroy(gameObject);
}
}
private void Start()
{
CreateTile();
}
public void CreateTile()
{
for (int x = X_Min; x < X_Max; x++)
{
for (int y = Y_Min; y < Y_Max; y++)
{
if (x % size == 0 && y % size == 0)
{//建立10*10的格子子集节点,此点为节点的索引节点(左下角第一个)
if(tileDic.ContainsKey(new Vector3Int(x, y)))
{//包含
Vector3Int pos = new Vector3Int(x, y);
tileDic[pos].Add(pos, new TileManager(tile, pos));
}
else
{//不包含
Vector3Int pos = new Vector3Int(x, y);
Dictionary point = new Dictionary();//单个格子
point.Add(pos, new TileManager(tile, pos));
tileDic.Add(pos, point);
}
}else
{
Vector3Int suoyin = new Vector3Int(GetIndex(x), GetIndex(y));//获取到索引节点
if (tileDic.ContainsKey(suoyin))
{//包含
Vector3Int pos = new Vector3Int(x, y);
tileDic[suoyin].Add(pos, new TileManager(tile, pos));
}
else
{//不包含
Vector3Int pos = new Vector3Int(x, y);
Dictionary point = new Dictionary();//单个格子
point.Add(pos, new TileManager(tile, pos));
tileDic.Add(suoyin, point);
}
}
}
}
}
///
/// 获得索引
///
///
///
public int GetIndex(int index)
{
if (index < 0)
{
if(index % size == 0)
{
return index - (index % size);
}
else
{
return index - (index % size) - size;
}
}
else
{
return index - (index % size);
}
}
}
public class TileManager
{
public TileManager(TileBase _tileBase,Vector3Int _vector3Int)
{
tile = _tileBase;
pos= _vector3Int;
}
public TileBase tile;
public Vector3Int pos;
public bool isSet;//被生成过,只用于索引节点
}
人物移动类
public class Move : MonoBehaviour
{
public PlayerMove inputActions;
public Rigidbody2D rb;
public float speed = 0.5f;
Vector2 inputVector;
Vector3 moveVector;
[SerializeField]
private Vector3Int _index;
public Vector3Int index {
get { return _index; }
set {
if (value != _index)
{
_index = value;
TileChi.instance.SetTile(index);
}
}
}
private void Awake()
{
inputActions = new PlayerMove();
}
private void OnEnable()
{
inputActions.Enable();
}
private void OnDisable()
{
inputActions.Disable();
}
private void Start()
{
TileChi.instance.SetTile(new Vector3Int(tilemaptest.instance.GetIndex((int)transform.position.x), tilemaptest.instance.GetIndex((int)transform.position.y)));
}
private void Update()
{
inputVector = inputActions.Player.Move.ReadValue();
moveVector = Vector3.right * inputVector.x + Vector3.up * inputVector.y;
transform.position += moveVector*speed;
index = new Vector3Int(tilemaptest.instance.GetIndex((int)transform.position.x), tilemaptest.instance.GetIndex((int)transform.position.y));
}
}
动态加载卸载地图类
public class TileChi : MonoBehaviour
{
public static TileChi instance;
int size;//节点大小
int check=-1;//不合格标志
Vector3Int child1;//子节点
Vector3Int child2;
Vector3Int child3;
Vector3Int child4;
Vector3Int child5;
Vector3Int child6;
Vector3Int child7;
Vector3Int child8;
List OpenList=new List();//需要激活的节点
List CloseList=new List();//需要隐藏的节点
List EnableList=new List();//当前已激活子节点
void Awake()
{
if (instance == null) { instance = this; }
else {Destroy(gameObject); }
}
private void Start()
{
size=tilemaptest.instance.size;
}
///
/// 动态生成Tilemap
///
///
public void SetTile(Vector3Int index)
{
if (CheckChild(index).z == check) return;
SetChild(index, NeedCheck(index));
}
public void SetChild(Vector3Int index,bool NeedCheck)
{
if (NeedCheck)
{
child1 = CheckChild( new Vector3Int(index.x + size, index.y));
child2 = CheckChild(new Vector3Int(index.x + size, index.y + size));
child3 = CheckChild(new Vector3Int(index.x, index.y + size));
child4 = CheckChild(new Vector3Int(index.x - size, index.y + size));
child5 = CheckChild(new Vector3Int(index.x - size, index.y));
child6 = CheckChild(new Vector3Int(index.x - size, index.y - size));
child7 = CheckChild(new Vector3Int(index.x, index.y - size));
child8 = CheckChild(new Vector3Int(index.x + size, index.y - size));
}
else
{
child1 = new Vector3Int(index.x + size, index.y);
child2 = new Vector3Int(index.x + size, index.y + size);
child3 = new Vector3Int(index.x, index.y + size);
child4 = new Vector3Int(index.x - size, index.y + size);
child5 = new Vector3Int(index.x - size, index.y);
child6 = new Vector3Int(index.x - size, index.y - size);
child7 = new Vector3Int(index.x, index.y -size);
child8 = new Vector3Int(index.x + size, index.y - size);
}
OpenList.Clear();
OpenList.Add(index);
AddChild(child1); AddChild(child2); AddChild(child3);
AddChild(child4); AddChild(child5); AddChild(child6);
AddChild(child7);AddChild(child8);
CreateTile(index);
}
///
/// 校验子节点
///
///
///
Vector3Int CheckChild(Vector3Int child)
{
if(child.x>=tilemaptest.instance.X_Min&& child.x < tilemaptest.instance.X_Max&& child.y >= tilemaptest.instance.Y_Min&& child.y < tilemaptest.instance.Y_Max)
{
return child;
}else
{
return new Vector3Int(0, 0, check);
}
}
///
/// 校验父节点是否需要校验子节点
///
///
///
bool NeedCheck(Vector3Int vector3Int)
{
if (vector3Int.x >= tilemaptest.instance.X_Min+size && vector3Int.x < tilemaptest.instance.X_Max-size && vector3Int.y >= tilemaptest.instance.Y_Min+size && vector3Int.y < tilemaptest.instance.Y_Max - size)
return false;
return true;
}
///
/// 生成图格
///
/// 父节点
void CreateTile(Vector3Int parent)
{
CloseList.Clear();
if (!tilemaptest.instance.tileDic[parent][parent].isSet)
{//首次生成或被传送
//Dictionary linshi = new Dictionary();
foreach (var item in tilemaptest.instance.tileDic[parent])
{
tilemaptest.instance.tilemap.SetTile(item.Key, item.Value.tile);
//linshi.Add(item.Key, item.Value.tile);
}
EnableList.Add(parent);
tilemaptest.instance.tileDic[parent][parent].isSet = true;
}
foreach (var item in EnableList)
{//遍历激活List
if (!OpenList.Contains(item))
{//需要隐藏的图格
tilemaptest.instance.tileDic[item][item].isSet = false;//可被重新激活
CloseList.Add(item);//添加到CloseList
DesTile(item);//隐藏图格
}
}
foreach (var item in CloseList)
{//移除需要隐藏的节点
EnableList.Remove(item);
DesTile(item);
}
foreach (var item in OpenList)
{//生成图格
if (item != parent)
{
EnableList.Add(item);
foreach (var dic in tilemaptest.instance.tileDic[item])
{
tilemaptest.instance.tilemap.SetTile(dic.Key, dic.Value.tile);
}
tilemaptest.instance.tileDic[item][item].isSet=true;
}
}
}
///
/// 销毁对应节点的所有图格
///
///
public void DesTile(Vector3Int index)
{
foreach (var item in tilemaptest.instance.tileDic[index])
{
tilemaptest.instance.tilemap.SetTile(item.Key,null);
}
tilemaptest.instance.tileDic[index][index].isSet = false;
}
///
/// 添加子节点
///
///
void AddChild(Vector3Int child)
{
if(child.z!=check)
{
OpenList.Add(child);
}
}
}