unity动态加载卸载Tilemap
撒日狼
编辑于 2024年12月21日 13:08

比较基本的动态加载卸载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);

       }

   }

}