欢迎光临散文网 会员登陆 & 注册

【Unity俯视角射击】我们来做一个《元气骑士》的完整Demo(三)

2020-10-08 18:21 作者:皮皮关做游戏  | 我要投稿

作者:Yumir


哈喽大家好我的yumir。

惯例先上成果链接:

https://connect.unity.com/mg/other/untitled-9864


本篇相对前面两篇会比较简短啦,但是剩下的内容一篇讲完又太多太复杂,所以还是单独开一片力求把问题将清楚,也欢迎大家多多提出自己的疑惑。

接下来开始制作元气骑士小地图吧。



地图UI

我在元气骑士地图自动生成那篇文章提到过,元气骑士的地图实际上是在5*5的格子里面从中心开始向四周随机衍生房间,没记错的话是五到六个。

比如这次Demo做的地图是这样的:

表现到小地图上就是这样的:

地图整体的UI布局是这样的:

将上图切割成9*9的矩阵可知,该图是由若干方块、横向长方形和纵向长方形组成的,在组成的图形对应位置上放上小房间的图标表示为起点,另外再新建一个红色的小方块作为玩家定位点。

可以利用Grid Layout Group进行排版,制作一个9*9的方块布局,再在方块中设置对应的形状,在Ctrl+D的加持下一两分钟就可以做完了。

需要注意的是,在使用这个UI的时候是需要通过显示隐藏当中的方块来绘制地图的,如果这时候物体身上挂载了Grid Layout Group,就会导致显示出来的格子全都会自动对齐,所以在使用之前需要将Grid Layout Group去掉。


地图逻辑

我想要编写一个用于管理小地图的UI显示的脚本,首先对脚本的需求进行分析,该脚本管理的就是一个小地图UI(上面的9*9格子)和一个用于表示玩家位置的小方块。

所以新建一个用于管理小地图UI的脚本,持有小地图本体和表示玩家位置的小方块,声明一个list用于管理小地图上所有的格子。

在Start方法中进行初始化:

public Transform littlemap;

public Transform playerIndex;

List<Transform> mapItems;

void Start(){

    mapItems = new List<Transform>();

    foreach (Transform item in littlemap){

        mapItems.Add(item);

    }

    for (int i = 0; i < mapItems.Count; i++){

        mapItems[i].gameObject.SetActive(false);

    }

    mapItems[40].gameObject.SetActive(true);

}

 

掐指一算我的小地图需要三个功能,分别是:更新玩家所在的房间、更新可以探索的地方、更新已探索的房间等。除此之外还有一个显示特定某个房间的需求,但是只有在初始房间需要用到,所以就没有提取为方法。

1、更新玩家所在的房间

小地图实现这个功能的任务其实可以简化到两行代码,由调用者输入房间号,小地图根据房间号计算出房间在小地图对应的位置,将玩家方块设置到该位置即可。

public void UpdatePlayerIndex(int num){

    int mapNum = num / 5 * 18 + num % 5 * 2;

    playerIndex.transform.position = mapItems[mapNum].transform.position;

}

 

那么我们需要如何使游戏在合适的时候更新玩家的位置呢?

目前我是这样解决的:

首先在每个房间新建一个触发器覆盖房间范围(省事,后期进行优化)。这样一来我们就能得到一个“玩家进入某房间”的事件,每个房间有各自的管理脚本,我在房间脚本的父类中声明了玩家进入的方法。

public class RoomTrig : MonoBehaviour{

    private void OnTriggerEnter2D(Collider2D collision){

        if (collision.transform.tag == "Player")

            GetComponent<Room>().PlayerEnter();

    }

}

 

虽然本篇只涉及到更新玩家所在位置这一操作,但是后续可以在该事件中对不同房间进行多样化操作。

在游戏管理脚本中声明更新玩家所处房间的方法:

public void UpdatePlayerRoom(Room room){

    this.room = room;

    //更新地图显示

    littleMap.UpdatePlayerIndex(room.roomNum);

    if (!room.isExplored){//如果没有被探索过

        littleMap.UpdateCanExploreInMap(room);

        littleMap.UpdateRoomsExploredInMap(room.roomNum);

    }

}

 

2、更新可以探索的地方

这个操作需要用到一组数据,也就是我之前实现地图自动生成时用到的树状结构的“房间类”,因为制作demo的时候地图并不是动态生成的,所以房间的数据也需要手动添加。

等以后有机会做动态生成的时候再将数据剥离即可。

可以看到目前的数据结构是每个房间持有自己的子节点房间,存放于nextRooms数组中。

在小地图管理脚本中声明一个新的方法:

public void UpdateCanExploreInMap(Room room){

    foreach (Room nextRoom in room.nextRooms){

        int data = nextRoom.roomNum - room.roomNum;

        int roomNum = room.roomNum;

        int roadNum = 0;

        switch (data){

            case -5://上

                roadNum = roomNum / 5 * 18 + roomNum % 5 * 2 - 9;

                break;

            case 5://下

                roadNum = roomNum / 5 * 18 + roomNum % 5 * 2 + 9;

                break;

            case -1://左

                roadNum = roomNum / 5 * 18 + roomNum % 5 * 2 - 1;

                break;

            case 1://右

                roadNum = roomNum / 5 * 18 + roomNum % 5 * 2 + 1;

                break;

            default:

                break;

        }

        int nextRoomNum = nextRoom.roomNum / 5 * 18 + nextRoom.roomNum % 5 * 2;

        mapItems[nextRoomNum].gameObject.SetActive(true);

        mapItems[roadNum].gameObject.SetActive(true);

    }

}

 

该方法遍历传入的房间对象所持有的nextRooms数组,根据房间号的差判断可探索房间位于所处房间的哪一个方位,计算两个房间之间的道路格子的位置。

最后将小地图上房间之间的“道路”和可探索的房间设置显示,就可以了。

3、更新已探索的房间

上文游戏管理脚本中的更新玩家所处房间方法中有一个if判断,当玩家进入一个房间,如果该房间还没有被探索过,是需要执行两个方法的,一个是上文中的更新可以探索的房间,那么玩家当前所处的房间也就可以被标记为已探索。

现在想想这里改成将整个地图隐藏,当玩家探索完毕的时候再调用这个方法会更好,下次一定。

public void UpdateRoomsExploredInMap(int room){

    int mapNum = room / 5 * 18 + room % 5 * 2;

    mapItems[mapNum].GetComponent<Image>().color = new Color(1, 1, 1, 1);

}

 

我事先把所有表示房间的格子的颜色都设置为白色半透明的格子,当玩家探索完之后,改为不透明格子,就是已经探索完了。

一个简单好用的小地图UI就这样制作完成了,文中提到的地图自动生成方法如果没有看过并且感兴趣,传送门在这里:

用uinty实现元气骑士地图的自动生成



欢迎加入游戏开发群欢乐搅基:1082025059

对游戏开发感兴趣的童鞋可戳这里进一步了解:levelpp.com/

【Unity俯视角射击】我们来做一个《元气骑士》的完整Demo(三)的评论 (共 条)

分享到微博请遵守国家法律