Y3编辑器教程5:触发器进阶使用(镜头、UI、表格、函数库、排行榜、游戏不同步)

文章目录

    • 一、游戏声音设计
    • 二、 游戏镜头设计
      • 2.1 镜头的基本参数
      • 2.2 镜头时间轴动画
    • 三、界面编辑
      • 3.1 界面编辑器设置
      • 3.2 添加按钮事件
      • 3.3 触发编写
    • 四、 表格编辑器(实现对话UI)
      • 4.1 一维表和多维表
      • 4.2 数据验证、搜索、保存与撤销
      • 4.3 Excel导入导出
      • 4.4 使用表格编辑器实现对话UI
      • 4.5 更多示例
    • 五、 函数库
      • 5.1 简介
    • 六、项目:竞技场争霸赛
      • 6.1 项目简介
      • 6.2 地形设置
      • 6.3 游戏初始化
      • 6.4 战斗准备
      • 6.5 战斗中
        • 6.5.1 右键移动
        • 6.5.2 左键攻击
        • 6.5.3 Boss AI
      • 6.6 游戏结束
    • 七、 使用排行榜
    • 八、 不同步问题
      • 8.1 本地配置不同步日志环境
      • 8.2 线上游戏不同步定位
      • 8.3 定位不同步问题
      • 8.4 游戏不同步常见原因

  • Y3编辑器文档1:编辑器简介及菜单栏详解(文件、编辑、窗口、细节、调试)
  • Y3编辑器文档2:场景编辑(地形编辑、物件放置)
  • Y3编辑器文档3:物体编辑器
  • Y3编辑器文档4:触发器1(界面及使用简介、变量作用域、入门案例)
  • Y3编辑器教程5:触发器进阶使用(镜头、UI、表格、函数库、排行榜、游戏不同步)

本文参考官方文档《触发器案例》和《触发器初级教程》

一、游戏声音设计

  声音不仅是玩家接收游戏信息的重要途径,也是游戏开发者传递情感和增强游戏体验的关键工具。游戏中的声音主要分为功能性音乐和背景音乐两大类:

  • 功能性音乐:
    • 游戏信息提示:为玩家提供画面外的游戏信息提示和预警,例如交互物品的存在、环境变化和潜在威胁。
    • 玩家操作反馈:通过声音反馈玩家操作,增强游戏互动性,使玩家获得及时且全面的反馈。
  • 背景音乐:
    • 环境渲染:通过声音对游戏场景进行多感官渲染,增强玩家的沉浸感。
    • 情绪渲染:利用声音表达复杂的情绪,如战斗的激烈、对未知的恐惧和紧迫感。

在物体编辑器中可以进入音效模块,设置音效属性:

  • 淡入::设置声音开始时由无声过渡到有声所经历的时间。
  • 淡出::设置声音结束时由有声过渡到无声所经历的时间。
  • 调整至3D声音模式,我们可以设置声音的衰减距离和静音距离。
    在这里插入图片描述
      点击“+”可以为一个音乐场景添加多个声音,不仅可以调节各个声音的音量,还可以调整各个声音的播放概率,从而使游戏中的音乐变得多样化。还可以为音效添加新的自定义属性并设置其名称、类型、值,后续通过触发器调用。
    在这里插入图片描述
      在物编器-单位-单位固定属性中,我们可以为单位绑定声音事件,比如选择当角色升级时播放升级音效。

二、 游戏镜头设计

2.1 镜头的基本参数

  打开工具栏->放置物件->镜头,可以看到编辑器自带得默认镜头Initial Camera,此镜头的视角为进入游戏之后的默认视角,无法删除,无法重命名。用户可以在场景中的任意位置,点击“以当前视角设置镜头属性”来为当前视角创建镜头。用户创建的镜头可以重命名、删除。
在这里插入图片描述

参数说明
焦点位置及镜头的指向点焦点位置指的是镜头所注视的目标点,它由三维坐标(X、Y、Z)确定。镜头的指向是通过这些坐标来设定的,表示镜头当前所看的位置。
俯仰角镜头与水平线的夹角,平视为零度,仰视为负数,俯视为正数。
导航角镜头在地平面上的方向,通常从参考方向(如正北)开始测量,镜头面向正东时导航角为90度。
滚转角镜头自身的旋转角度,类似于歪头时视角的变化。
距离镜头与焦点之间的三维空间距离。
观察区域(FOV)镜头视野所能覆盖的范围,决定镜头显示细节的区域。
远景裁剪镜头显示参数,超出距离范围的物体不进行渲染(不显示)。
实时观察镜头属性改变勾选后可实时预览镜头的视角变化。
与焦点的最大/最小距离游戏中,玩家可通过鼠标滚轮控制镜头与焦点的距离,设置此参数可进行限制。
例如,当二者设为一样时,玩家视角将被限定,无法使用鼠标滚轮调整距离。

在这里插入图片描述

2.2 镜头时间轴动画

  使用镜头时间轴动画和使用触发器都可以实现镜头动画,二者在最终的画面表现上没有区别,但却各有优势:

  • 镜头时间轴动画:可以在时间轴内,通过设置关键帧的形式,方便快速地制作镜头动画。但每条时间轴镜头动画不能复制,无法复用。
  • 触发器:触发器编写的自定义程度高,语句还可以复制粘贴,具有很强的复用性和扩展性。(相关定义详见触发器-镜头API)
    在这里插入图片描述

  点击新建的“镜头时间轴动画1”右侧的编辑按钮,即使用当前画面视角为初始帧,创建时间轴动画。每条时间轴动画由两个部分组成,分别是 时间轴当前关键帧下镜头的属性面板。

在这里插入图片描述

  我们可以在时间轴上拖动进度条,或是在frame窗口中输入具体帧数,来选择关键帧位置。Y3编辑器使用的刷新率为30帧每秒,所以如果设置关键帧在第60帧,就是在第两秒。点击上方的创建按钮,即可在所处位置为所选参数新建关键帧。

  关键帧分为绝对值(当前关键帧下镜头的具体参数)和相对值(相对于初始帧所改变的取值)。当指针选定一个关键帧时,点击鼠标右键,即可对关键帧进行复制、粘贴、删除(按下delete按键也行)等操作。编辑并保存关键帧之后,在触发器中可以编写镜头触发事件:

在这里插入图片描述

三、界面编辑

  界面编辑器是对软件的人机交互操作逻辑和界面美观进行的整体编辑,我们通常会用到图像、文字、按钮等组件,在界面上与操作者进行互动,从而丰富和增强用户的体验。Y3编辑器中UI编辑器的操作界面主要由五个部分组成:

在这里插入图片描述

  1. 画板区:在开始做一个界面之前,必须先创建一个画板。
  2. 节点区:用于展示每个画板里面的各个控件。所有组件都以树结构来陈列,包含了一组节点,节点之间相互关联,并且具有父节点和子节点关系(节点的任何附属节点都称为子节点)。删除一个节点,其所有子节点也会被一起删除。
  3. 控件栏:展示所有可使用的UI组件,包括按钮、图片、模型、文本输入框、进度条、滑动条列表等。
  4. 画布区:在画布中编辑摆放组件,并查看组件属性。
  5. 属性/事件区:前者用于编辑组件的具体参数,包括大小、位置、外观、动画等;后者配合触发编辑器,去实现一些想要的功能。

接下来,我们实现以下界面UI:

在这里插入图片描述

3.1 界面编辑器设置

  首先在地图上放置一个用于选择的单——探险者,在法师周围绘制一个圆形区域,命名为select _area,,表示进入这个区域会触发宝物选择界面。

  • 创建空白画布:打开界面编辑器,单击+创建一个新的画板,并重命名为select_treasure。缩放画布大小为33%
  • 创建选择框底板:拖动顶部图片按钮到画布中央,在资源库中选择喜欢的图片(弹窗->公告栏)。拖动图片锚点放大图片,或者通过x轴y轴坐标进行放大。
  • 设置界面标题:拖动顶部文本按钮到底板上,调整位置和大小,输入“请选择一个你喜欢的宝物”作为选择框的标题,并明明为title。设置文本的字体颜色和对齐方式,让它们看上去更美观一些。

在这里插入图片描述

  • 设置玩家选项1:拖动一张图片(控件图)到画布上,根据喜好调整位置、尺寸和背景图片,命名为button1。将另外一个图片拖动至button1内,作为奖励的展示图标(icon1),选择文本并将其拖至button1内,作为奖励的名字(name),输入“魔法戒指”并调整字体颜色和位置。
  • 调整父子级关系:以图片为父节点,将title,button1拖动到图片下,作为相互平行的子节点。将icon,name拖动到button1下,作为其子节点。这样icon,name,button1就可以作为一个整体被选择。
  • 设置玩家选项2:复制并粘贴一个新的选项,重命名为button2,调整级别和位置,更改图像和文本,完成第二个按钮。

在这里插入图片描述

3.2 添加按钮事件

  界面组件设置完毕后,我们为按钮添加事件。选中button1,右上角点击事件,点击+添加事件,并命名为choose_ring。点击“空事件->事件设置-点击”。同样的方式为button2选择点击事件并命名为choose cloak

  在事件板块,点击音效可以选择事件的音效,点击界面上方的动画编辑,可通过时间轴管理为事件制作帧动画。时间轴和动作设置板块中的动画效果互相排斥,如果在动作设置板块中选择了一个动画效果,则时间轴不生效。

在这里插入图片描述
  由于整个画板在事件触发前是不可见的,所以选中整个画板select_treasure,选择属性,将是否可见取消勾选,这样我们绘制的整个界面组件,在触发调用前是不可见的。

3.3 触发编写

整个触发分三部分:

  • 当选择单位进入到对应的区域后,会出现选择框
  • 选择按钮A,左侧信息栏提示A内容
  • 选择按钮B,左侧信息栏提示B内容

下面是具体的编写逻辑:

  1. 触发器-进入区域
    • 在物编器的触发器页签下创建任意单位进入select _area区域事件,将此事件命名为“进入区域”。
    • 新建条件->单位类型判断,获取事件中单位的单位类型等于探险者。
    • 新建动作->界面->显示/隐藏控件,对玩家1显示控件。

在这里插入图片描述

  1. 触发器-选择戒指
    • 创建事件:界面->控件事件,参数UI事件选择choose ring
    • 创建动作选择界面->显示/隐藏控件来向玩家1显示控件select_treasure
    • 创建动作选择界面->系统消息提示,来向玩家提示“你选择了魔法戒指”,持续时间设为5秒。
  2. 触发器-选择斗篷
    直接复制上一条触发器重命名为选择斗篷,UI事件改为choose cloak,第二条动作命令信息显示内容修改为“你选择了魔法斗篷”。

在这里插入图片描述

四、 表格编辑器(实现对话UI)

在这里插入图片描述
  在故事中,我们通过对话UI向玩家传达了剧情的重要信息。不同的对话内容需要多个UI来呈现吗?其实不用,在Y3编辑器中,我们可以结合表格编辑器、界面编辑器和触发来实现这个效果。

4.1 一维表和多维表

  表格编辑器是Y3编辑器提供的数据管理工具,我们可以在表格编辑器中以表格的形式保存数据,并之后通过触发来快速调用这些数据,比如怪物的物品掉率,刷怪时怪物种类和数量。

  在表格编辑器中有两种表格:一维表和多维表。一维表中,每一行都是一条独立的数据,包含键名、类型、值和备注。通过键名,也就是索引,我们就能快速获取到对应的值。

  一维表适合定义零散的各种数据,比如游戏初始化时的一些规则和参数。假设你的《练功房》项目中一共会有六个房间,你想分配其中有两个房间产出经验,有两个房间产出金币,并且希望在游戏中时间12时开始刷新怪物,14时之后就停止刷新怪物。由于这些数值关系到项目中设定的经济产出,如果你希望快速地调整这些数值,可以将这些数值保存在一维表格中:

在这里插入图片描述

  假设你正在制作一个《塔防》项目,在第1波次,一共有30只恶魔进攻玩家,玩家需要在60秒内把他们消灭。这里波次有“顺序”、“怪物数量”、“怪物类型”、”消灭时间”四个关键属性,可以使用多维表格管理数据。多维表中,每条数据包含多个属性及其数值,我们需要两个索引才能锁定数据位置。

在这里插入图片描述

  多维表适合定义一个数据对象,表格中的第一行是这个数据对象的属性名称(key),第二行是这个属性的数据类型,第三行及之后的行则是对应的值。如果数据类型选错了,那么你可能没有办法在触发器中正确的拿到你想要的数据。

4.2 数据验证、搜索、保存与撤销

  • 多维表可灵活添加行和列,一维表固定只有三列,不能新增列。
  • 不允许出现相同的主索引值,且主索引只能是整型或字符串类型
  • 数据验证:标红的单元格意味着该数据无法在局内读取到。若是在你配置过程中出现,可能只是因为你的表格还没有编辑完成而系统提前在验证。数据配置后,仍有单元格标红,可把鼠标悬浮在红框上查看具体原因,如关键数据的缺失或不匹配或重复,再予以修复。
    在这里插入图片描述
  • 重命名:右键点击一张表或选中后按F2可进行重命名
  • 表格归类:点击文件夹图标按钮或Ctrl+G可创建文件夹,归类表格。
  • 保存与撤销:保存按钮是保存整个工程,而撤销按钮只针对你在表格编辑器内的操作。

4.3 Excel导入导出

  表格编辑器并不支持如office中公式、填充柄、甚至VBA等一些高级功能的应用。如果要进行高效开发,推荐先使用Excel进行快速编辑,再导入编辑器。表格编辑器用于快速验证调试游戏体验。

  点击导入,你可以选择一个表格文件将其导入至编辑器中,当前支持的表格格式有”.xlsx”,”.xlsm”,”.xls”,”.csv”共四种。

  1. 一维表导入:所有以“kv_”开头的sheet将读取为一维表
    • 标题行:第一行为标题行,限定内容为“Key,Type,Value,Des",大小写允许模糊。
    • 数据行:第二行往后为数据行
  2. 多维表导入:所有"config_"作为前缀的sheet表格将读取为多维表
    • 第一行为注释行,不读取
    • 第二行为数据名,读取后视为列名
    • 第三行为数据格式,支持int,string,float,bool四个类型,支持大小写模糊
    • 第四行为主键标识,格式需要是整型或者字符串类型,以key1,key2,key3进行枚举,支持大小写模糊。最多支持三键表,需有key1,才能有key2,需有key2,才能有key3,否则报错,导入错误。如果没有key,则生成一个”key1“列作为主键,以行号填写值。
    • 第五行之后为表格的数据,涉及到的公式等特殊格式以结果的值进行读取。

4.4 使用表格编辑器实现对话UI

在表格编辑器内定义的表格,在游戏初始化时将会保存在内存中,供你在任意的触发器中调用:

在这里插入图片描述
下面我们就来看一看表格编辑器的具体使用方法。

  1. 绘制UI:绘制一个界面来承载和展示对话内容

    • 打开界面编辑器添加一个新面板,并将其重命名为dialogue。这个界面应包含两个图片,一个作为content(对话内容)背景,一个作为real name(角色)的背景,以及两个分别用于承载real namecontent文本框。
    • 拖动调整这些控件的大小和位置,在文本设置中设置文本的字体样式,调整空间的父子级关系。选择整个面板并取消勾选是否可见,表示直到它被触发才显示对话界面。
      在这里插入图片描述
  2. 创建多维表:创建多维表并将其重命名为scripts。在scripts中将主索引key修改为order(存储对话顺序,整型)。添加两个类型为字符串的属性role namecontent分别存储角色名称和对话内容。
    在这里插入图片描述

  3. 触发编写

    • 新建事件:硬件输入-键盘空格键按下事件
    • 新建动作设置对话顺序:设置一个全局整数变量order,来记录空格键被按下的次数,初始值为零。使用函数->整数间运算,设置变量orderorder+1,这样当我们第一次按下空格键时,order都加1
    • 新建动作显示角色名称:选择界面->设置文本,对玩家一设置dialogue面板下的real name文本,字符串参数选择函数,然后选择第二个多维表中的字符串值。现在当我们第一次按下空格键时,order=1,主索引为1role name数据将读取显示。当我们再次按下空格键时,order=2,主索引为2role name的数据将被读取显示。
    • 新建动作显示角色对话文本:操作同上

在这里插入图片描述

4.5 更多示例

一维表用例:配置了如下的一维表,命名为globalConfig
在这里插入图片描述
可直接通过Type类型对应的参数类型,在获取到Key对应的Value值。

在这里插入图片描述
多维表用例:配置了如下的多维表,命名为Example。
在这里插入图片描述
最基础的使用方式为直接获取表格中的值,如我当前需要获得id为1的数据中的use_money字段数据,将其存入变量a中。可以采用这样的方式:
在这里插入图片描述
常用方式是遍历表格,实现一些逻辑:

在这里插入图片描述

五、 函数库

5.1 简介

在这里插入图片描述
  在之前的章节中,我们使用循环计时器连续生成次元入侵者。那如果需要在多个区域,在不同的时间点生成敌人,是否需要写多个触发器重复设置效果呢?当然不是,Y3编辑器为我们提供了一种更简单的方法来重复实现简单的功能,即函数库。

  你可以将自己常用的触发器语句/功能模块添加到函数库,接着就可以在触发器中找到该函数语句进行重用。与触发器的操作逻辑相同,在左侧创建函数后,在右侧编辑功能库函数。

在这里插入图片描述

初始化玩家技能槽位

函数描述定义了函数在操作列表中的显示方式。 函数描述包括以下内容:

  • 名称:要生成的触发器语句的名称。
  • 描述:要生成的触发器语句的内容和格式。
  • 提示:当前函数的说明。

在这里插入图片描述

函数体包括以下内容:

  • 参数:定义了该函数的输入数据,可设置参数类型,如定时器、单位和整数。
  • 返回值:定义了函数执行后返回的结果(输出数据)。你可以点击 "+"来设置返回值的名称和类型,以方便触发器的后续调用。
  • 动作:显示了函数的具体行动逻辑

  现在我们想要实现的效果是,在三个指定的地点间隔0.3秒,生成一个指定类型的野怪,总共生成五个。我们可以使用函数库简化具体的编写过程。
在这里插入图片描述

  1. 触发组件:我们需要在地形上放置敌对单位、boss和探险者。
    • 在boss周围绘制三个点区域,分别命名为point A、Point B、Point C。
    • 以boss为中心绘制一个圆形区域alert area,作为boss的警戒范围
    • 自定义三个不同的小怪,他们会在三个点生成。
  2. 自定义函数库函数
    • 在函数库中新建函数,命名为“野怪刷新”,参数为Monster(小怪,单位类型)和Point(刷新点)
    • 点击左边的可用参数,使用刚刚创建的参数组成函数描述:“在参数Point处创建参数Monster”
    • 新建一个技数计时器,设定每隔0.3秒运行一次,共运行五次,选择“立即执行”
    • 在动作列表中选择创建单位,单位类型是参数Monster,点是函数参数Point,为单位boss创建,方向是单位boss的方向。
    • 添加一个动作来向怪物发出命令,选择“单位发布命令”,设置命令为“攻击移动”。
      在这里插入图片描述
  3. 触发编写:调用函数库,通过设置不同的参数和计时器来在不同时间和地点生成敌人。
    • 新建“任意单位进入区域事件”
    • 在单玩家位进入BOSO警戒区域两秒、三秒、四秒后,分别使用“野怪刷新”函数,在三个点刷新小怪。
      在这里插入图片描述

六、项目:竞技场争霸赛

6.1 项目简介

在这里插入图片描述

游戏的制作一般分为三大类:

  • 设计:包括游戏的核心玩法和故事背景。
  • 美术:负责游戏的原画,角色、物体和场景的三维建模。
  • 程序设计:通过代码实现游戏玩法。

  本项目“竞技场争霸赛”是一款射击类小游戏,一个人就足以完成开发。核心玩法是玩家控制挑战者挑战怪物,通过移动和射击来躲避怪物攻击和击败怪物。每隔几秒钟怪物就会热身蓄力,然后冲锋,玩家必须使用鼠标右键移动进行躲避,然后使用鼠标左键精瞄准射击,击败怪物,所以游戏两大核心机制是移到和射击
在这里插入图片描述

  另外游戏将从游戏印象和游戏沉浸两个角度进行设计。由于挑战者在攻击时不能移动,所以玩家在何时躲避危险和何时瞄准目标之间保持平衡是很重要的,这带来了挑战和乐趣。在游戏沉浸方面,我们可以通过动画、镜头、角度、滤镜等去创造过程,带来令人印象深刻的游戏体验,玩家将在游戏开始时更加兴奋,在游戏结束时更感到印象深刻。

在这里插入图片描述
在这里插入图片描述

时间有限,下面只展示必要步骤。

6.2 地形设置

  • 新建空白工程,选择小型地图(64×64)和自定义UI模板。
  • 创建生物单位(挑战者、boss、观众)和抛射物(探险者的子弹)。
    • 挑战者模型选择仙人掌人,血条样式为绿色血条,显示模式为不满血显示,取消勾选死亡后销毁单位,取消勾选无法反击时逃跑。最大血量设为30,生命恢复设为0。
      在这里插入图片描述

    • 复制挑战者模板,BOSS模型选择图示小怪物,血条显示红色,单位状态里设置禁止普攻,

    • 观众选择图示小怪物,无血条显示,单位状态选择无效

    • 抛射物选择绿色法阵符文特效,缩放0.6
      在这里插入图片描述

  • 绘制陆地碰撞
    在这里插入图片描述
    在这里插入图片描述
  • 为挑战者、BOSS和观众设置出生点
  • 设置挑战者和BOSS的战斗准备圈
  • 放置一个几乎覆盖整个竞技场的战斗圈,作为boss的攻击区域
    在这里插入图片描述

6.3 游戏初始化

在“竞技场争霸赛”这款游戏中,我们将游戏分为以下四个阶段:

  • 游戏初始化:镜头跟随玩家,设置变量为游戏角色伤害初始值。
  • 战斗准备:挑战者和boss的嘲讽动作,摄像机跟随。
  • 战斗中:实现鼠标操作(右键移动、左键射击),boss的AI逻辑(蓄力和冲锋)。
  • 战斗结束:根据胜者播放不同的动画和滤镜效果,结束游戏。

我们先完成第一阶段:游戏初始化

  • 刷出挑战者,并设置镜头,让玩家以第三人称视角跟随他。
  • 设置一个2s的计时器,给玩家一点缓冲时间,让他们意识到游戏即将开始。
  • 向挑战者发布命令,移动到挑战者准备区
  • 为了提高游戏的沉浸感,邀请观众参加战斗。
    • 点击基础->收纳盒,设置一个存储框,设置一个观众点数组存储所有观众点,设置完后折叠起来,使界面更简洁。
      在这里插入图片描述

    • 设置一个循环来生成观众,并让他们的方向朝着战场中心。最后将每个观众都添加到观众单位组中,这样游戏结束时,我们就可轻易命令单位组成员,播放庆祝或挫折动画了。
      在这里插入图片描述

6.4 战斗准备

当挑战者进入准备圈时,我们需要做三件事:

  • 移除挑战者的准备圈,防止重复挑战者准备逻辑
  • 挑战者停止下来,播放嘲讽动画作为准备战斗的信号
  • boss进入战斗区域,并使用镜头跟随它
    在这里插入图片描述

当BOSS进入它的准备圈时,也有三个工作:

  • 移除boss的准备圈
  • 播放boss嘲讽动画将比赛气氛推向高潮
  • 等待2s后战斗开始,让镜头恢复正常,并允许玩家控制角色。

最后创建一个全局布尔变量battleongoing,默认值为false,现在为true,表示正在战斗中。

在这里插入图片描述

6.5 战斗中

6.5.1 右键移动

  为了在游戏中实现鼠标操作,我们设置了右键移动,左键射击。移动机制为,当玩家按下鼠标右键,并且布尔变量battleongoing为真时,让角色移动到鼠标位置。

在这里插入图片描述

6.5.2 左键攻击
  • 当玩家按下鼠标左键且battleongoing为真时,创建一个局部变量为鼠标的游戏坐标,point为当前玩家坐标
  • 命令挑战者停止(防止可以边移动边攻击),将方向设置为从point朝向clickedPoint的方向,播放攻击动画
  • 完成开枪逻辑:
    • point处创建投射物(设为变量方便移除),添加运动器来设置子弹的直线运动轨迹和造成的伤害
    • 在移动完成后将运动器和抛射物移除
    • 创建碰撞运动器实现子弹的射击伤害,并跳字显示

在这里插入图片描述

6.5.3 Boss AI

Boss的AI逻辑有两个部分:蓄力和冲锋。

  • 每三秒,如果battleongoing为真,怪物将停止移动并播放循环蓄力动画idle2
  • 2秒钟后怪物会播放一个循环冲锋动画,并为自己创造一个线性的移动器,达到高速移动的效果。BOSS移动位置为战斗区中随机位置。
  • 使用碰撞移动器让BOSS冲锋时对碰撞的敌方单位造成真实伤害

在这里插入图片描述

6.6 游戏结束

当任何单位死亡时,战斗结束。我们需要停止玩家的控制权限,播放结束过场动画,并结束游戏。

  • 创建一个触发器,触发事件为任意单位死亡
  • 设置battleongoing为False
  • 将摄像机对准胜者,如果是挑战者,这意味着玩家赢了,让我们为挑战者和所有观众播放赢家动画。设置一个闪闪发光的滤镜效果,使这个庆祝时刻更愉快,并以胜利结束游戏。
  • 如果胜者是boss,播放输家动画,设置对应的滤镜。

在这里插入图片描述

七、 使用排行榜

  1. 点击主界面【细节】-【存档设置】打开存档槽设置

  2. 点击加号创建一个新的存档槽并修改存档槽数据类型为整数
    在这里插入图片描述

  3. 选择确认计入排行榜,这个存档槽位就变成了排行榜存档。可以选择排行榜排序规则(升序降序)与排行榜最大人数。
    在这里插入图片描述

  4. 使用以下eca可以获取排行榜上所有玩家的存档值,配合界面eca让排行榜在界面显示。玩家->整数型增量存档eca可以让整数类型存档保持只增效果。
    在这里插入图片描述

排行榜数据在游戏启动后不会再刷新,使用双槽位可以实现周排行榜

  • 创建两个整数类型存档槽位:A与B,A存储第一周所有玩家的排行榜数据

  • 当一周结束时(通过时间戳判断),使用B榜存储玩家在第二周的排行数据

  • 在第二周开始时通过ECA清除玩家A槽位数据,以备第三周存储玩家排行数据。需通过在作者之家清除A榜数据(权限需找运营申请)。
    在这里插入图片描述

  • 当第二周结束时,将玩家排行榜数据存储在A榜并清除B槽位数据,循环往复

八、 不同步问题

参考《不同步相关》

8.1 本地配置不同步日志环境

  用户由于使用ECA不当,频繁出现游戏逻辑不同步的问题,会影响游戏正常运行。此时可通过在本地多开测试来进行调试。在【通用设置-调试】打开本地多开同步检测。

在这里插入图片描述
  使用Lua文件配置更详细的不同步日志:打开地图路径下Script文件夹下的main.lua文件,在lua文件中配置不同步日志相关API
在这里插入图片描述

GameAPI.api_set_enable_detail_snapshot(true)
GameAPI.api_set_detail_snapshot_enable_tag(0xfffffff)
GameAPI.api_set_enable_eca_snapshot(true)
GameAPI.api_set_snapshot_traceback_level(2)

  配置完毕后,本地多开运行游戏。如遇游戏逻辑不同步,会有弹窗提示,并在本地生成不同步日志以供用户定位不同步问题。
在这里插入图片描述
在这里插入图片描述

不同步日志Lua配置API说明:

API描述参数返回值
api_set_enable_detail_snapshot控制不同步日志记录的总开关。关闭后,其他设置接口将不生效,但可以提升性能。enable(bool):是否开启,默认为false
api_set_snapshot_traceback_level设置日志堆栈记录详细等级,默认0不记录
1:仅记录最近一层堆栈
2:记录完整堆栈(数据压缩)
3:记录完整日志(不压缩,数据量稍大)
记录越完整越有利于定位问题,但开销增大
level(int32):堆栈记录等级,默认值为0
api_set_enable_timer_snapshot开启或关闭计时器不同步检测日志(检测额外创建的ECA计时器),但计时器不一致并不一定意味着游戏内容不同步。enable(bool):默认值为false
api_set_enable_eca_snapshot开启或关闭ECA不同步检测日志,开销较高。可通过参数过滤掉一些安全的API以防止误报,例如创建特效、UI操作等enable(bool):默认值为false
filter_mode(int32):过滤模式,默认为1
1:剔除模式,不记录filter_set中指定的api;
0:包含模式,仅记录filter_set中指定的api;
filter_set(table):过滤集合,默认为"client_only","client_possible"
可传入想要剔除/包含的API(取决于上个参数)
如"GameAPI:print_to_dialog",“GameAPI:get_function_return_value。”
api_set_detail_snapshot_enable_tag设置不同步详细日志级别。越详细越利于定位不同步产生点,但性能消耗会增高tag(UInt64):控制开启哪些日志的mask
1运动器tick;2运动器碰撞检测
4寻路回调;8寻路坐标更新
16血量变化;32坐标瞬变
0xFFFFFFFF全部开启;默认开启16+32
add_detail_log记录自定义日志log(string):日志内容bool,值恒定为true

8.2 线上游戏不同步定位

  1. 在本地配置不同步日志环境
    打开地图路径下Script文件夹下的main.lua文件,在lua文件中配置不同步日志相关API,这样线上游戏发生不同步时,根据配置API玩家客户端会自动上传日志。例如:
GameAPI.api_set_enable_detail_snapshot(true)
GameAPI.api_set_detail_snapshot_enable_tag(0xfffffff)
GameAPI.api_set_enable_eca_snapshot(true)
GameAPI.api_set_snapshot_traceback_level(2)
  1. 下载不同步日志
    使用KK账号登录编辑器,打开任意地图,点击【菜单栏】【调试】【查看不同步日志】查看线上游戏的不同步日志。
    在这里插入图片描述
    查找需要定位问题的对局,下载不同步日志,不同步日志包含对局中所有玩家的对战信息。
    在这里插入图片描述

8.3 定位不同步问题

  不同步日志文件中包含的是出现不同步情况的帧信息,通过对比玩家日志差异,可以大致定位到问题所在。打开不同步日志文件夹,使用第三方文本对比工具进行对比(推荐使用BeyondCompare)。比如在main.lua文件中进行了如下配置:

GameAPI.api_set_enable_detail_snapshot(true);
GameAPI.api_set_enable_timer_snapshot(true);

打开不同步日志,查看逐帧信息:

在这里插入图片描述
将多名玩家日志成对拖放到beyondcompare中进行对比,发现玩家2比玩家1多了一个timer:
在这里插入图片描述
  通过对不同步信息附近的帧信息进行理解,可大致定位问题为某个客户端上多了一个循环计时器,在项目中进行查找可能的问题所在。
在这里插入图片描述

8.4 游戏不同步常见原因

  • 本地值
    • 在单个客户端(即单个玩家的设备)上有效的数据,比如界面显示、特效、镜头位置、声音等,这些数据在不同的客户端之间不需要同步,因为它们只影响单个玩家的体验。
    • 任意值与【本地值】进行逻辑运算后得到的值等价于【本地值】
    • 动作类ECA中,修改【本地值】,不会影响游戏的全局逻辑,因此不会影响游戏的同步性。
  • 本地操作:针对本地值的操作,如【获取本地玩家】、【获取本地控件坐标】、【获取镜头焦点】、【获取滑动条当前值】等,这些获取本地值的ECA函数,在不同客户端得到的结果也是不同的。
  • 全局值:在所有客户端之间需要保持一致的值,比如单位、技能、物品等。这些值的一致性对于游戏的公平性和逻辑一致性至关重要。
  • 全局操作:针对全局值的操作,比如修改单位的状态、技能的效果、物品的数量等。这些操作会影响游戏的全局逻辑,因此需要确保在所有客户端上都能正确同步。

  导致游戏逻辑不同步的一个重要原因就是将【本地值】作为参数,传递到【全局操作】中,或者是使用【本地值】进行逻辑判断后,进行【全局操作】。这会导致不同客户端执行不同的逻辑,最终导致不同客户端上【全局值】不同,即游戏逻辑不同步。更多内容详见文档多人联机同步机制。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高中数学:成对数据的统计分析

文章目录 一、成对数据的统计相关性1、相关关系2、样本相关系数 二、一元线性回归模型及其应用1、一元线性回归模型2、最小二乘估计3、拟合效果比较公式4、注意点5、例题 三、列联表与独立性检验1、分类变量2、分类变量与列联表3、独立性检验4、常用小概率值和临界值5、例题6、…

Python OCR文字识别api接口

一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…

Type-C接口电热毯的创新之旅

在科技日新月异的今天,智能家居产品正逐步渗透到我们生活的每一个角落,从智能灯光到温控系统,无一不展现着科技带来的便捷与舒适。而在这个追求高效与智能化的浪潮中,一款结合了最新科技元素的电热毯——Type-C接口电热毯&#xf…

【Unity3D】实现UGUI高亮引导点击

Unity版本2019.4.0f1 Personal <DX11> using UnityEngine; using UnityEngine.UI;public class GuideMask : MonoBehaviour, ICanvasRaycastFilter {public Canvas canvas;public Transform guideTargetTrans;public Image image;private Vector3 guideTargetWorldPos;pr…

docker启动一个helloworld(公司内网服务器)

这里写目录标题 容易遇到的问题&#xff1a;1、docker连接问题 我来介绍几种启动 Docker Hello World 的方法&#xff1a; 最简单的方式&#xff1a; docker run hello-world这会自动下载并运行官方的 hello-world 镜像。 使用 Nginx 作为 Hello World&#xff1a; docker…

Redisson常用方法

Redisson 参考: 原文链接 定义&#xff1a;Redisson 是一个用于与 Redis 进行交互的 Java 客户端库 优点&#xff1a;很多 1. 入门 1.1 安装 <!--redission--> <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifa…

火焰传感器与C++编程:精准检测火灾的技术实现

火灾是我们日常生活中一个不可忽视的安全隐患&#xff0c;而火灾报警系统的实现可以大大提高我们的安全保障。通过嵌入式技术和传感器&#xff0c;我们能够在第一时间识别火灾隐患并发出警报。火焰传感器作为一种专门用于火灾监测的传感器&#xff0c;能高效地通过红外线&#…

arcGIS使用笔记(无人机tif合并、导出、去除黑边、重采样)

无人机航拍建图之后&#xff0c;通过大疆智图软件可以对所飞行的区域的进行拼图&#xff0c;但是如果需要对拼好的图再次合并&#xff0c;则需要利用到arcGIS软件。下面介绍arcGIS软件在这个过程中常用的操作。 1.导入tif文件并显示的方法&#xff1a;点击“”图标进行导入操作…

VMware Workstation的有线连接消失了

进入/var/lib目录下 cd /var/lib 查看是否存在NetworkManager 文件 ls 将其删除&#xff0c;然后虚拟机reboot一下。 sudo rm -r NetworkManager reboot 解决了&#xff0c;可以联网

算法-动态数组-62.不同路径

一、题目 二、思路解析 1.思路&#xff1a; 对于找到目的地它的来源主要来源于目的地的上一格和目的地的左一格 2.常用方法&#xff1a; 无 3.核心逻辑&#xff1a; 1.处理边界&#xff1a; a.只向右移动&#xff0c;至始至终只有一条路径 for(int i0;i<m;i){dp[i][0]1; } …

C# 探险之旅:第三十节 - 类型class(继承Inheritance) —— 当“儿子”继承“老爸”的遗产

嘿&#xff0c;探险家们&#xff01;欢迎再次踏上我们的C#奇幻旅程。今天&#xff0c;我们要聊一个既有趣又实用的话题——继承&#xff08;Inheritance&#xff09;&#xff01;想象一下&#xff0c;如果你的“儿子”能够继承“老爸”的遗产&#xff0c;那编程世界里的对象们也…

Qt:Q_GLOBAL_STATIC实现单例(附带单例使用和内存管理)

转载 https://blog.csdn.net/m0_71489826/article/details/142288179 前言 本文主要写Q_GLOBAL_STATIC实现单例以及单例的释放&#xff0c;网上很多教程只有单例的创建&#xff0c;但是并没有告诉我们单例的内存管理&#xff0c;这就很头疼。 正文 使用 Qt 的 Q_GLOBAL_STA…

12.5【Java exp4】【DEBUG】

pro1 JwtAuthenticationFilter 类在两个不同的位置被定义了&#xff0c;导致Spring无法确定使用哪个定义。 为了解决这个问题&#xff0c;你可以采取以下几种方法之一&#xff1a; 检查类路径中的重复类&#xff1a; 确保 JwtAuthenticationFilter 类没有在多个地方被定义。检…

C++11语法解析(二)

可变参数模板 基本语法及原理 ・C11 支持可变参数模板&#xff0c;也就是说支持可变数量参数的函数模板和类模板&#xff0c;可变数目的参数被称为参数包&#xff0c;存在两种参数包&#xff1a;模板参数包&#xff0c;表示零或多个模板参数&#xff1b;函数参数包&#xff1…

《知识拓展 · 统一建模语言UML》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

轻量级日志管理平台:Grafana Loki搭建及应用(详细篇)

前言 Grafana Loki是Grafana Lab团队提供的一个水平可扩展、高可用性、多租户的日志聚合系统&#xff0c;与其他日志系统不同的是&#xff0c;Loki最初设计的理念是为了为日志建立标签索引&#xff0c;而非将原日志内容进行索引。 现在目前成熟的方案基本上都是&#xff1a;L…

【原生js案例】如何让你的网页实现图片的按需加载

按需加载&#xff0c;这个词应该都不陌生了。我用到你的时候&#xff0c;你才出现就可以了。对于一个很多图片的网站&#xff0c;按需加载图片是优化网站性能的一个关键点。减少无效的http请求&#xff0c;提升网站加载速度。 感兴趣的可以关注下我的系列课程【webApp之h5端实…

用于卫星影像间接RPC模型精化的通用光束法平差方法

引言 介绍了通用RPC模型的表达式&#xff0c;which has been down to death 描述了RPC模型产生误差的原因——主要与定义传感器方位的姿态角有关。 每个影像都会对应一个三维点云&#xff0c;但是对同一地物拍摄的不同影像对应出来的三维点云是不一样的&#xff0c;所以才需…

搭建Tomcat(一)---SocketServerSocket

目录 引入1 引入2--socket 流程 Socket&#xff08;应用程序之间的通讯保障&#xff09; 网卡(计算机之间的通讯保障) 端口 端口号 实例 client端 解析 server端 解析 相关方法 问题1&#xff1a;ServerSocket和Socket有什么关系&#xff1f; ServerSocket Soc…

玩转个性地图样式!蜂鸟视图蜂鸟云主题编辑器正式上线

当地图不再只是冷冰冰的数据呈现&#xff0c;而是具有美感、适应多场景需求的设计作品时&#xff0c;地图应用的价值也随之提升。 蜂鸟视图推出全新“主题编辑器”功能&#xff0c;助你轻松定制个性化地图样式&#xff0c;赋予地图更多创意与生命力&#xff01; 一、主题编辑器…