浅谈游戏地图中位置实时更新的技术方案

news2024/9/22 23:23:25

7c984ff594a2472202b8346931a09461.gif

地图如今在游戏中发挥的作用越来越重要,随着电子竞技的兴起,地图逐渐成为了为玩家创造体验的直接舞台。希望本文能对有兴趣了解游戏地图背后实现原理的同学一些帮助。

baa20f9e71a2d584c90c93c28a8afd93.png

什么是游戏地图

在游戏中可以通过3D场景虚拟一个完整的世界,当3D场景较为广阔和地形比较复杂时,游戏玩家在场景中漫游行走,往往容易因为陌生的环境而迷失方向。而通过为玩家提供一张场景地图,就可以以一种更加直观的形式向他们呈现整个游戏的世界观。游戏地图通常是为以用户俯视的视角构建出来的描述场景地形环境的地图,例如平原、山地、树林和主干道等,并会显示各处的关键地点。

1ddb94cbe16dd9909032ccad8d5527e6.png

游戏地图的作用

  沉浸式体验

在很多游戏中,地图能够为玩家带来有更加沉浸式的体验。例如像赛车或者奔跑类的游戏,对地图的依赖性很高,游戏的乐趣也往往体现在地图上,通过地图能够唤起、激发玩家对游戏的兴趣,为玩家带来独特的游戏代入感。游戏代入感的一个重要来源就是能够让玩家感同深受,比如玩家控制的角色可以在虚拟的世界里奔跑飞翔,完成一些任务可能需要途径很多地方,在这过程中,设计地图实时更新玩家当前的位置,让游戏本身的设计就与地图的设计相辅相成。

  指路功能

当玩家初次进入复杂且场景范围较大的3D场景中,往往容易迷失方向,对自己当前身处的位置以及场景的全貌没有一个准确的认知。就像现实生活中出远门需要地图导航一样,在3D场景中同样需要为玩家提供一张3D场景对应的地图来承担指路功能,让玩家能清楚地意识到自己前进的方向,以及场景中存在什么建筑物体,就能保证玩家不会在复杂的3D场景地形地貌中迷路。如果是射击类的游戏,在地图中还可以标注出敌人的位置或补给物体的位置,为玩家解锁更多有意思的玩法。

6b9544d7f23416a647e04fd0c38fc68e.png

正俯视视角地图的技术实现

  需求说明
  • 前期准备

一张3D场景的正俯视角度下,与场景XZ平面1:1还原的地图图片素材。

274d3e42e00a0c695d4a59416b00a190.jpeg

图1 正俯视视角地图

  • 实现目标

用户在3D场景内漫游移动时,能够在地图中实时更新用户的位置,并且只展示用户当前位置所对应的地图局部区域,如下图左上角区域所示。

9d381eff35538d66d385028d30108ed5.jpeg

图2 效果展示图

  技术实现
  • 技术方案简述

当我们拥有一张根据3D场景正俯视视角下的地图图片时,用户在3D场景中的实时位置,从俯视视角看下来时就是用户应该位于2D地图所对应的位置。如此,当用户在场景中跑动时,我们计算人物在场景XZ平面上的百分比,即可还原出在2D地图中的百分比。

但是需求里并非简单地将俯视图作为地图进行完全的展示,要求是只展示用户所在位置的局部区域,这样我们可以让地图作为展示区域的背景图,进行局部展示,在人物移动时,移动地图即可形成相对运动的效果。

  • 实现步骤
  1. 绘制地图可见区域框,整张地图图片以canvas元素的形式加载,并作为可见区域背景图

  2. 人物在2D正俯视地图的位置,作为可见区域的中心

  3. 获取场景的AABB包围盒,得到3D场景的XZ平面宽高

  4. 计算人物当前位置在场景XZ平面的百分比

  5. 进而更新人物在地图图片上的百分比

  6. 人物行走,通过移动背景地图图片,更新人物实时位置

  7. 非边缘跑动:地图动,人物不动

  8. 边缘跑动:地图不动,人物动

3b1cb00bdaa839c08894a5464c7f2382.jpeg

图3 计算占比示意图

  • 实现效果说明

有些同学可能会提出疑惑,为何采用canvas绘制地图,而非普通dom元素?

原因是由于IOS机型在使用CSS属性clipPath对可见区域边框裁剪,溢出部分仍可响应触摸事件。改用canvas重新实现,解决了这个问题,并且性能比用dom节点实现更好。

6bda844435ba49a3f17988f2555ca889.jpeg

非正俯视视角地图的技术实现

  需求说明
  • 前期准备

3D场景任意俯视视角下的图片作为场景的大地图,并提供该视角下相机位置、旋转、缩放、远近平面、fov等参数。获得非正俯视视角地图的一个巧妙方法,在unity内查看场景模型时,调整一个合适的位置,截图可得。

a567acafe731453eaea35cd36c804155.jpeg

图4 非正俯视视角地图

c4caa94199d150615e477563f6a96824.jpeg

图5 俯视图相机参数

  • 实现目标

需要实现在相机任意俯视视角下,都能准确还原3D场景中的人物当前位置。

  技术实现
  • 概述

现在终于来到了非正俯视视角地图中,实时更新当前位置的具体技术的实现部分了。

读到这里,有些同学可能会有些疑问了,非正俯视视角地图和正俯视视角地图里都有人物当前位置对应地图的位置,为什么非正俯视视角的地图实现的方式需要赘述一次呢?

其实大家简单想象一下就可以发现,假设人物当前位置静止,当我们以上帝视角(即相机)去俯视3D场景时,从不同角度或位置观察3D场景,得到的如图6、图7所示的俯视图图片是不一样的,人物位置相对地图图片的百分比自然也是不一样的。如此,在非正俯视视角下,我们就不可能采取类似于正俯视视角的按计算百分比的方案去还原人物当前位置。

e0d25e133816486e11a718744b59653b.jpeg

图6 远俯视角度

e718e0c1de2c3b695182ff663216ab29.jpeg

图7 近俯视角度

  • 解决思路

由于所有我们看到的渲染结果,都是视锥体投影到近平面的结果,如果我们把地图的图片放置到近平面上,再从当前相机位置向3D场景中的人物位置发出一条射线,那么该射线与近平面(也就是地图)相交的交点,也就是当前人物的在地图上的实时位置。那么这个方法具体实现起来,可以分成以下这几个步骤。

  1. 定义一个地图所在的平面:法向是相机的朝向,距离是近平面的距离。

    其中相机的朝向在相机坐标系下可以设置为单位方向(0,0,-1),需要将该坐标变换到世界坐标系下,即应用V逆矩阵的变换得到相机朝向在世界坐标系下的表示。

    定义一个平面,除了相机朝向(也就是平面的法向)外,还需要在这个法向上的距离,即近平面的距离0.3。如此,得到世界坐标系下地图所在的平面的定义。

  2. 定义一条射线:世界坐标系下,从相机位置,到人物当前位置,发出一条射线。

  3. 得到一个交点:世界坐标系下,射线与平面的交点,是一个世界坐标系下的3D交点坐标。

  4. 将世界坐标系下的交点坐标,重新转为在相机坐标系下的3D坐标,并去掉不需要的z轴信息。

    世界坐标系转相机坐标系,即将该点做V变换,平移加XYZ轴对齐。

  5. 此时相机坐标系下的点在平面的比例,就是地图中的比例。

    计算近平面的宽高值,宽高值可以通过视锥体的aspect、fov、近平面距离等轻松求出。

    根据unity在相机坐标系是左手系,得到地图的左上角坐标值。

    计算当前交点相对于地图图片的百分比即可。

  • 步骤分解
  1. 定义一个地图所在的平面:法向是相机的朝向,距离是近平面的距离0.3

    const localN = new Vector(0,0,-1)

    const worldN = localN.apply(ModelMatrix)

    const plane = new Plane(worldN.normalize(), near)

  2. 定义一条射线:从相机位置,到人物当前位置,发出一条射线

    const ray = new Ray(ICameraPos, dir.normalize());

  3. 得到平面与射线的一个交点:射线与平面的交点,是一个世界坐标系下的3D坐标 targetPoint

    ray.intersectPlane(plane, targetPoint);

  4. 将世界坐标下的3D坐标转为相机坐标系下的3D坐标 : 相机平移+3个轴对齐--相机坐标系下看向Z轴

    targetPoint = targetPoint.subtract(ICameraPos);

    targetPoint = targetPoint.apply(ModelMatrix.inverse());

  5. 求近平面的宽高

    const halfH = Mat(8)tan(fov*0.5) * near;

    const aspect = imgW / imgH;

    const halfW = halfH * aspect;

    const leftTop = new Vector2(-halfW,halfH);

  6. 此时相机坐标系下的点在平面的比例,就是地图中的比例

    const px = Mat(8)abs(target2DP.x - leftTop.x) / (2 * halfW);

    const py = Mat(8)abs(target2DP.y - leftTop.y) / (2 * halfH);

5eb067263d8fd905295d6175b9927124.jpeg

实现效果

通过视频效果的展示,可以看出,当用户在3D场景中向右走,然后到达右侧交叉路口再向右走时,重新回到地图页,当前位置图标已经更新到对应的正确位置。

a0d0ffa2b78f66d8e956c489be9b2a6c.jpeg

结语

地图如今在游戏中发挥的作用越来越重要,随着电子竞技的兴起,地图逐渐成为了为玩家创造体验的直接舞台。希望本文能对有兴趣了解游戏地图背后实现原理的同学一些帮助。

参考资料:浅谈游戏中的小地图与大地图设计(地址:https://zhuanlan.zhihu.com/p/504211689)

5e56b44d58387fb3ad4a348166a1d954.jpeg

团队介绍

我们是天猫技术品牌线的行业前端团队,目前负责消费电子、3C数码、运动、家装家居、汽车、奢品等行业的线上线下模式的探索,面向淘内淘外,提供商家、门店、消费者最佳用户体验。团队在XR、3D、2D渲染引擎这些创新体验上有不错的沉淀,同时面向全栈领域团队探索了 Serverless 云端研发模式,在消费者前台,通过数据挖掘消费、意图识别提升消费者效率,同样面向工程领域,在跨端、前端工程化、中后台微前端都有一些沉淀,如果你是一位充满想象的终端极客,欢迎你的加入,通过自己的技术想法去改变天猫行业的终端表达。

¤ 拓展阅读 ¤

3DXR技术 | 终端技术 | 音视频技术

服务端技术 | 技术质量 | 数据算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot的大学生租房平台系统

技术:springbootmysqlvue 一、系统背景 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对大学生租房信息管理混乱…

C语言每日一题07

一、题目 二、解析 逻辑与 &&、逻辑或 || 均有“短路”特性: 逻辑与&&“短路”:当逻辑与&&的左操作数为逻辑 “假“ 时,就足以判断该逻辑运算的结果为假了,故右操作数就不再被执行。 逻辑或||“短路”&#xff1a…

使用PLCSIM Advanced仿真博途运动控制

作者顾工首先,添加一个CPU,直接添加一个1518T,反正仿真,不用最好的干嘛呢。是吧。当然,你也可以添加一个你喜欢的PLC,这里不强求。 然后添加工艺对象,我们简单添加一个定位轴。 在工艺对象&am…

GPT-5揭秘:Lex Fridman与Sam Altman播客热议,AGI时代的新变革即将来临!

嘿,朋友们,你们知道吗?Lex Fridman和Sam Altman又聚在一起了,这次是在播客上。 在播客中,他们聊了很多,包括董事会的幕后故事、Elon Musk的诉讼案,甚至还提到了Ilya、Sora这些名字。 但真正让…

跟着官方文档一步一步搭建Elastic Stack(3节点ES集群+Kibana+Filebeat+Metricbeat)

文章目录 源码仓库硬件要求配置文件docker-compose.ymlfilebeat.ymlmetricbeat.yml 配置项解读以及注意事项docker-compose.yml解读filebeat配置解读metricbeat配置解读SSL配置ILM配置 运行运行截图 写在最后 本篇文章是使用Filbeat将产品环境的access_lo同步至Elastic Stack中…

SSTI漏洞详解

目录 前备知识 模块引擎: 模块渲染函数: 继承关系: SSTI漏洞简介 SSTI漏洞成因 SSTI漏洞原理 一些常见模块介绍 php Twig模块引擎 代码演示1 Twig模块引擎代码演示2 python flask模块 代码演示1: python jinja模块 代…

Net安卓app BroadcastReceiver 使用记录一坑

1.背景 由于项目需要,需要对接别的app的广播,就看了看Net 安卓开发的广播接收,看官网的介绍单纯广播和接收都挺简单的,于是上手样板项目弄了两个demo出来,app1用来发,app2用来收。 2.版本 :使…

2024格行VS华为VS飞猫哪个是最值得购买随身WiFi?中兴随身WiFi好用吗?

经常出差旅行,或者户外工作的朋友因为长期在外,手机流量经常不够用,想必都是随身WiFi的忠实用户,但是也都被这款产品割韭菜割的头皮发麻。今天,我们统计了市面上最靠谱的、最热销、口碑最好的几款随身WiFi。排名依据来…

查询表中数据(全列/特定列/表达式,where子句(比较/逻辑运算符),order by子句,limit筛选分页),mysql执行顺序

目录 select 全列查询 特定列查询 用表达式查询 (as) 名字 distinct 去重 where子句 比较运算符 列数据之间的比较 ​编辑 别名不能参与比较 null查询 between and in ( ... , ...) 模糊匹配 逻辑运算符 order by子句 可以使用别名 总结mysql执行顺…

【蓝桥杯选拔赛真题71】python判断字符 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python判断字符 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python判断字符 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

Google colab中如何从kaggle中接入数据?

写在前面 使用google colab进行数据分析和探索时,可引用的数据源包括但不限于:1.可上传的数据文件用本地加载的的方式打开数据资源;2.从网络链接中直接打开后加载到缓存中的文件资源;3.通过API或者外部的开放接口加载数据&#x…

软考 网络工程师 每日学习打卡 2024/3/21

学习内容 第8章 网络安全 本章主要讲解网络安全方面的基础知识和应用技术。针对考试应该掌握诸如数据加密、报文认 证、数字签名等基本理论,在此基础上深入理解网络安全协议的工作原理,并能够针对具体的 网络系统设计和实现简单的安全解决方案。 本章共有…

C语言之strsep用法实例(八十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

除了Confluence,有没有其他工具一样好用?

每个团队都需要一个协同工作工具,以更有效地管理任务、跟踪进度和分享知识。这就是Atlassian的Confluence发挥作用的地方。然而,尽管它相当强大,其昂贵的价格和复杂的界面可能会让某些用户望而却步。所以,还有其他工具可以替代Con…

面试算法-65-二叉树的层平均值

题目 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[3.00000,14.50000,11.00000] 解释:第 0 层的…

python中获取当前项目的目录

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂 今天介绍一下,如何在python中获取当前项目所在的目录,而不是运行脚本的目录。 class ProjectPaths:# 初始化时获取当前脚本的路径staticmethoddef get_script_dir():…

mysql数据库的索引管理

目录 一、索引的概述 1、索引的概念 2、索引的作用 3、索引的副作用 4、创建索引的原则依据 5、索引优化 6、索引的分类 7、数据文件与索引文件 二、管理数据库索引 1、查询索引 2、创建索引 2.1 创建普通索引 2.2 创建唯一索引 2.3 创建主键索引 2.4 创建组合…

java 方法重写

1、方法重写概述 重写发生在两个类中,这两个类必须有继承或实现关系。 子类中出现了和父类中一模一样的方法声明。这一模一样指的是什么? (1)方法名、返回值类型、参数(个数、类型、顺序)与父类一样&…

zabbix6.4报错问题汇总:zabbix server无法连接zabbix agent主机

在配置zabbix server连接本机agent时报错&#xff1a; Get value from agent failed: cannot connect to[[xxx.xxx.xxx.xxx]:10050]: [111] Connection refused 检查10050端口是否开放&#xff0c;以下三种方式都可以查看端口是否开放。 1.nc -zv <服务器IP> <端口号…

【十九】【算法分析与设计】加强训练

目录 杨辉三角 Fibonacci数列 The Biggest Water Problem 数字根&#xff1a; Digit Sum of N! 模的运算性质&#xff1a; [NOIP2005]谁拿了最多奖学金 牛牛的汉诺塔 结尾 杨辉三角 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 时间…