该工具已上传个人仓库,预计未来会添加更多辅助游戏开发的工具,敬请关注IceinNorth/Ice-Game-Development-Toolkit: 自制的一些方便游戏开发的工具 (github.com)
目录
前言
一直想做一个非线性的2D探索解谜游戏,不过unity自带的Scene Manager其实更适合拿来做一些线性关卡结构或者选关结构的游戏,所以趁着还没开学自己尝试写了一个工具来辅助管理关卡。
一开始是打算在Scene Manager的基础上来制作这个工具,不过scene在异步加载上存在一些限制导致不能实现我原有的想法,所以后来也是换成prefab来制作这个工具。
功能演示
该工具可以根据关卡的命名自动进行四个方向上关卡的切换
无需手动设置关卡的出入口,使用时只需要在关卡预制体的名字中添加坐标形式的数字即可
命名时只需要包含两组数字即可,对格式没有太多要求(两组数字中间必须用其他符号隔开,建议数字在前方便Project内关卡的排序)
效果如下(注意观察Hierarchy面板中的关卡的状态)
源码
部分内容需要根据项目自行更改,具体详见代码内注释
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;//正则表达式命名空间
using UnityEngine;
//------------------------------------------------------------
// 作者名:一冰在北
// GitHub项目地址:https://github.com/IceinNorth/Ice-Game-Development-Toolkit
// 邮箱:wu2687180662@icloud.com
//------------------------------------------------------------
public class LevelManager : MonoBehaviour
{
public Transform PlayerTr;
public Camera Camera;
public GameObject ActiveLevel; //启用的关卡
private Action ActiveAction; //关卡切换事件
private List<GameObject> loadedLevelList; //已加载关卡列表
private GameObject[] levels; //文件中的所有关卡
private Vector2Int oldIndex; //上一个关卡索引:用于防止切换后上一个关卡被卸载
private Vector2Int nowIndex; //以坐标为形式的当前关卡索引
public Vector2Int NowIndex
{
get
{
return nowIndex;
}
}
private bool IsNotVisableInCamera; //玩家是否离开视线范围
public bool Asynchronous; //开启预加载
void OnEnable()
{
//事件订阅
ActiveAction += UnloadLevels;
ActiveAction += Asynchronous? LoadLevels : null; //根据Asynchronous判断是否采用预加载
ActiveAction += SetLevelActive;
}
void Start()
{
//DontDestroyOnLoad(this); //非必须
//实例化
Camera =Camera == null? Camera.main:Camera; //获取主摄像机,也可以通过Inspector面板拖拽获取
PlayerTr = PlayerTr == null? GameObject.FindWithTag("Player").transform:PlayerTr; //这里使用名为“Player”的标签来获取玩家的transform组件,也可以通过Inspector面板拖拽获取
ActiveLevel = ActiveLevel == null? GameObject.FindWithTag("Levels"):ActiveLevel; //这里会获取场景中标签为“Level”的物体,也可以通过Inspector面板拖拽获取
levels = Resources.LoadAll<GameObject>("Levels"); //需要在Assets中创建Resource文件夹并在其中创建关卡文件夹,关卡文件夹名字自定,这里使用“Levels”
loadedLevelList = new List<GameObject>();
//初始化
loadedLevelList.Add(ActiveLevel); //列表添加当前关卡
nowIndex = GetIndex(ActiveLevel); //获取当前关卡索引
ActiveAction(); //初始化
}
void Update()
{
nowIndex = SwitchPlayer(PlayerTr,nowIndex); //更新当前索引
if (IsNotVisableInCamera)
{
//玩家离开视线后