[开发者心得] 【开发tips】二十行代码搞定小地图功能 !

[复制链接]
1435 |0
汽水 发表于 2024-1-21 16:40:15 | 显示全部楼层 |阅读模式
本帖最后由 汽水 于 2024-1-21 16:43 编辑

近来接到不少创作者提问,如何制作小地图?那么今天它来了~,接下来我会以最简单快速的方式教会大家如何实现一个小地图功能。


先讲一下思路,小地图其实就是把人物的位置映射到 UI 上,每次人物位置更新就同步更新一下 UI 位置,我在下面画了一幅图帮助理解:




image.png

在上面图中,左边蓝色的代表着小地图,右边黄色的代表着实际地图,中间的小三角形代表着玩家的位置。从图上可以看出假设小地图是 200 * 200,实际地图是 400 * 400,只需要算一下映射关系即可完成显示。






接下来我们来实践一下:


先在编辑器中截图一下场景,将截好的场景图片上传到资源库中。(这里有个小技巧,我们可以将一个物体放在原点,然后右键它选中从上方观察,这样摄像机就与地面平行了)
7090LS2oJz.jpg

关于资源上传可以看这里: UI 贴图基础规格规范 | 教程 (ark.online)


上传好之后,我们来搭建一下小地图 UI,我们大体需要这样一个结构。由一个 Canvas 嵌套两个图片控件,这两个图片控件分别代表小地图背景、玩家 icon (也就是箭头)
image.png

接下来 将 Canvas 的溢出隐藏勾选上,并将上传好的小地图图片赋值给 mapImg 控件,然后把 mapImg 控件的大小设为与原图大小相同,这里我设置为了 800 * 800

image.png

保存之后将这个 UI 拖拽到场景中,接下来我们来编写代码。


创建一个 名为 Map 的 UI 脚本,并将它绑定给我们刚刚创建好的 UI 。具体绑定方式请看:创建游戏界面 (UI) | 产品手册 (ark.online) 方式一。
image.png





export default class Map extends UIScript {


    private _player: Player = null;
    private _mapImage: Image = null;
    private _playerTag: Image = null;


    private _durX: number;
    private _durY: number;
    private _mapImagePosCache: Vector = Vector.zero;


    protected onStart() {
        //设置能否每帧触发onUpdate
        this.canUpdate = true;
        this.layer = UILayerMiddle;


        this._playerTag = this.uiWidgetBase.findChildByPath("RootCanvas/Canvas/playerTag") as Image;
        this._mapImage = this.uiWidgetBase.findChildByPath("RootCanvas/Canvas/mapImg") as Image;



        Player.asyncGetLocalPlayer().then((p) => {
            this._player = p;
        });
    }


    protected onUpdate(dt: number) {
        if (!this._player) return;
        // 获取玩家位置
        const pos = this._player.character.worldTransform.position;
        // 获取玩家控制器旋转角度
        const rot = Player.getControllerRotation();
        // 设置玩家标签的旋转角度
        this._playerTag.renderTransformAngle = rot.z - 90;


        // 计算背景地图位置
        this._durX = (pos.x / 5300) * 800 - 60;
        this._durY = (pos.y / 5300) * 800 - 190;
        // 设置背景地图位置
        this._mapImagePosCache.set(this._durX, this._durY);
        this._mapImage.position = this._mapImagePosCache;


    }


}






核心代码其实只有 update 函数里面的七行代码。计算背景位置时候的 5300 代表着截图时候图片的边长,也就是图片左上角和右下角的位置的差。


大家可以在截图时候先算好,放一些标识物一类的这样后面比较方便。


0.28.0.2 版本:
小地图.zip (443.21 KB, 下载次数: 97)
回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表