魔兽争霸地图制作零基础大型教程

一、基础篇

参考《魔兽争霸3零基础大型教程》,地图名为:map0-YDWE.w3x,在qq群662122596可以找到。

  1. 点是系统中最容易产生的垃圾,因为一个点被创建就会永久存在,记得及时删除;
  2. Lua中可以使用break语句退出循环,YDWE中也可以使用“退出循环”语句,直接退出当前循环。
  3. 接受和完成任务时,可以使用自定义键值判定任务状态,来避免重复接取任务,以及接受任务之后才可能完成任务
  4. 单位强度:魔兽中,单位强度可以最简单的使用人口来表示。即可以为每个单位类型绑定一个自定义的强度值,也可以直接使用人口属性。
  5. 对战地图中,双方可以使用同一个模板(比如都是人族箭塔),只是模型和名字不一样,方便统一调整,平衡双方强度。
  6. 如果玩家英雄和商店不是一个联盟,那么建筑即使有 共享商店,联盟建筑物 技能,也无法购买物品(商店不显示任何购买物)。此时需要在建筑中添加 选择单位 或者 选择英雄 技能。
  7. 为每个英雄选择分别创建一个触发是可以实现的,但是这容易引起“类爆炸”问题。魔兽本身没有类的多态写法,一个取巧的方式是使用OR条件,并在动作部分将变化部分与不变部分区分开。
  8. 在魔兽中,对死亡单位发布命令或者造成伤害,容易引起魔兽崩溃。一种方式是提前判断单位生命是否大于零,这个在条件->布尔表达式的选项中。
  9. 匹配单位:可用于把单位圈进单位组;选取单位:用于操作单位组里的单位
  10. 直接使用逆天->选取圆形范围单位做动作。此语句不需要写生命值大于零,也不需要在做完动作后清除和删除单位组
  11. 当任意单位进入某个区域时,就在此区域刷出一只小怪。这个简单触发会造成无限刷怪(新生成的单位也会触发此事件),除了排除刷怪单位,另一种解决方式是刷怪前临时怪你触发器,刷怪并等待之后在开启触发器

1.1 跑腿任务(零基础教程)

参考《魔兽争霸3零基础大型教程》3:10:19 触发+物编:跑腿任务,英雄的消耗品和装备(商店)

在这里插入图片描述

  如果玩家英雄和商店不是一个联盟,那么建筑即使有 共享商店,联盟建筑物 技能,也无法购买物品(商店不显示任何购买物)。此时需要在建筑中添加 选择单位 或者 选择英雄 技能。

1.2 单位强度模块(多面板)

这个模块功能在进阶篇视频中,但是刷怪功能会用到单位强度设定,所以提前到这里

  1. 设置联盟和天灾单位的单位强度和价值,以及防御塔强度和价值
    在这里插入图片描述

  2. 收集地图中,每个玩家的强度信息。如果强度不为0,通知玩家他的强度是多少。

    • 非英雄单位的强度utc可以通过自定义值直接获取,所有单位强度累计赋值给变量uc
    • 英雄单位强度通过计算等级sr和血量百分比sh得到,赋值为变量str。我们设置1级满血英雄强度为11,满血满级(10级)的英雄设置强度为20
    • 设置玩家资源强度gc=gold/100
    • 玩家整体强度为:ac=uc+str+gc
      在这里插入图片描述
  3. 设置多面板,循环更新显示玩家的强度信息
    在这里插入图片描述

1.3 刷怪(逻辑更新,见第四章)

在这里插入图片描述

  这里要实现的是,每180秒联盟和天灾进行一次刷怪,双方阵营刷出的怪物有一个强度值上限。在上一节的def触发的单位强度和价值定义部分后面,加入刷怪动作,并显示计时器窗口:

在这里插入图片描述
  注意:计时器窗口不能在游戏初始化时显示,所以设置显示计时器窗口动作时,事件不能是游戏初始化,可以是游戏开始后0秒(多面板也是一样的)。另外,计时器设为显示之后,修改是无效的,自定义修改要放在显示之前完成。

二、进阶篇

参考《魔兽争霸3零基础大型教程(进阶篇)》,地图名为:map1(进阶篇).w3x,在qq群662122596可以找到。

2.1 英雄选择

  为每个英雄选择分别创建一个触发是可以实现的,但是这容易引起“类爆炸”问题。魔兽本身没有类的多态写法,一个取巧的方式是使用OR条件,并在动作部分将变化部分与不变部分区分开。

在这里插入图片描述

2.2 单位组

  在魔兽🀄️,对死亡单位发布命令或者造成伤害,容易引起魔兽崩溃。一种方式是提前判断单位生命是否大于零,这个在条件->布尔表达式的选项中:

在这里插入图片描述

魔兽本身会持续运行一个监听器,当某个单位生命小于等于0时,就会触发单位死亡事件。所以在魔兽中,单位生命值小于0就是死亡了。

选择了单位生命值大于零这个语句之后,接下来就是选择哪个单位。这里有两种选取方式:
在这里插入图片描述

  • 匹配单位:可用于把单位圈进单位组,比如:
  • 选取单位:用于操作单位组里的单位

之后清空并删除单位组,这就是单位组使用的一个标准流程:

在这里插入图片描述
  更推荐的方式,是直接使用逆天->选取圆形范围单位做动作。此语句不需要写生命值大于零,也不需要在做完动作后清除和删除单位组:

在这里插入图片描述

2.3 开启/关闭触发器

下面举一个最经典的例子——当任意单位进入某个区域时,就在此区域刷出一只小怪,此功能可写作:

在这里插入图片描述
结果测试发现玩家英雄进入刷怪区域之后,刷出了一堆小怪。这是因为新生成的怪物,也进入了刷怪区,导致刷怪事件被重复触发:

在这里插入图片描述

  按道理这个逻辑会造成无限触发,魔兽会卡死。但实际是每次进入区域都生成固定数量的小怪,这是因为魔兽底层有一个循环上限(可以简单理解成这样),不会造成无限循环。

要解决这个问题,一种方式是设置触发条件,比如触发单位不能是刷出的小怪:

在这里插入图片描述
另一种方式是,执行刷怪之前关闭当前触发器,并在刷怪之后再次开启,这样不用排除刷怪单位:

在这里插入图片描述

  注意:在开启触发之前,需要加入一个等待时间,否则刷怪之后立马开启,又会造成无限循环(应该是刷怪也有一个很短的时间,完成之前开启等于没有关闭过触发)。

在这里插入图片描述

2.4 变量作用域与排泄

  Lua中有全局变量与局部变量(前缀loc),前者作用于整个游戏过程,可以跨触发器获取;后者只在当前触发器有效,除非使用“触发器-运行”,才可以跨触发器传递。由于全局变量作用域是整个游戏,所以即使变量类型不同,变量名也不能重复:

在这里插入图片描述

  一种提升局部变量作用域的方式是,将其写入一个字符串的简键值中,这样也可以跨触发器获取,达到类似全局变量的效果,比如将一个物品池loc_gp设为字符串GAME“物品奖池”

在这里插入图片描述

  与全局变量不同的是,不同的字符串有不同的作用域,其变量(键值)不会互相冲突。变量在使用完之后进行排泄是一个好习惯,比如清除计时器、清空并删除单位组等等。要特别注意的是,魔兽中点比较特殊,一个点一旦被创建就永久存在,除非你将其删除。下面是一个选择英雄的标准写法:

在这里插入图片描述

  如果创建单位时,点被清除了,那么这个动作就不会被执行。所以当你写了创建单位的触发,但测试时没有任何单位被创建,很可能是提供了不存在在点。

2.5 数据存储

在魔兽中,自定义值、存储与哈希表都可以用存储数据,其创建语句分别是:

在这里插入图片描述
  可以看到,存储语句需要存储目录、标签和存储值;哈希表需要主索引、子索引和存储值,和存储语句很像。但是哈希表多了一个参数——哈希表名,这表示不同哈希表可以保存相同主索引、子索引的不同值。所以存储是一个二维数组,哈希表是一个三维数组。

2.5.1 自定义键值

  自定义值的类型可以看作主索引,属性可以看作子索引,这种方式的好处是书写比较方便。缺点是子索引不能遍历,比如设置字符串GAME的键(子索引)为 物品类型1、物品类型2…,这个键是没法遍历的。而存储的主索引和子索引都是字符串,可以遍历子索引上的属性值。

在这里插入图片描述

2.5.2 存储

下面是一个将游戏信息进行存储,然后随机遍历并提示给玩家的触发:
在这里插入图片描述

2.5.3 哈希表

先新建一个哈希表全局变量test,然后当玩家按下ESC键时,存储地图上的炮塔单位:
在这里插入图片描述
设置游戏每过2秒,读取并打印哈希表中存储单位的名字:
在这里插入图片描述

在这里插入图片描述

2.6 建造与回收防御塔

  为了限制玩家的铺塔速度,设置建造完成之后的塔的血量只有40%,可以通过农民的维修来使其满血(维修消耗少量金钱)。另外设置一个建筑回收功能(给建筑增加一个回收技能),根据塔的建造费用(自定义值:单位价值)及建筑血量,计算回收价格,将其回收(直接删除)。

在这里插入图片描述

2.7 特效制作(dummy马甲)

  作者提供了一个特殊的马甲dummy(模型文件为dummy,在游戏中看不到单位),可实现多种特效效果。马甲文件在教程地图 map1(进阶篇) 中。我们设置马甲同时显示两种特效,每1秒展示一次:

在这里插入图片描述

  • time用于控制特效显示时间,到期删除马甲单位。hero用于提供马甲创建的位置,可以改为点或者坐标。
  • 0号动作是正面,180号动作为单位横过来;尺寸和高度控制特效的大小和高度。比如以下分别是0,90180的效果:
    在这里插入图片描述

2.8 设置守卫军

  为了防止基地被偷袭,当其被攻击时,刷出两个近卫军(防御塔)。但是近卫军也不能太多,所以就创建两个,但可以一直刷新。下面是具体的触发,如果联盟或者天灾没有近卫1或近卫2(生命值判断),那么在被攻击时就会创建;否则不做任何动作。

在这里插入图片描述

2.9 设置玩家可加入天灾阵营

这里通过给开局的小精灵一个技能,来实现加入天灾阵营的效果。玩家可以加入天灾阵营之后,一些逻辑就需要对应更改了。

在这里插入图片描述

  1. 初始阵营设置:
    在这里插入图片描述
    在这里插入图片描述

  2. 自由选择天灾阵营
    在这里插入图片描述

  3. 英雄重选
    在这里插入图片描述

  4. 胜利失败判定
    在这里插入图片描述

三、伤害系统

参考《简单几步,极速搭建伤害系统》

3.1 监听伤害

  伤害系统可用于控制伤害,这包括伤害抵挡、伤害变回血、伤害减免、伤害反弹。要实现这一点,需要在发送和接收伤害中间,加一个监听器,由监听器来发送伤害。
在这里插入图片描述

  还是以这张地图进行测试。地图右侧有两个弓箭手,攻击时会打印出伤害调试信息,并设置在伤害开始和伤害结束之间有0.5秒的间隔,以便于观察。

在这里插入图片描述

具体的伤害测试触发如下,这里只对这两个弓箭手单位进行测试。

  1. hook:当测试单位受到伤害时,打印114弓箭手的当前生命值以及将要受到的伤害值,然后调用callback函数。
    在这里插入图片描述

  2. callback:打印伤害事件结束后,单位剩余生命值,以及实际结算的伤害值
    在这里插入图片描述

3.2 控制伤害

  为了达到控制伤害的效果,就需要一个再写一个触发(这里命名为course),由它来执行伤害的控制和发送;即hook->course->callback。测试前,先设置目标单位生命值为50%(便于观察回血效果),伤害减免系数为0.9,伤害回血次数为1伤害反弹次数为2:
在这里插入图片描述

  course触发如下,其中伤害抵挡实现效果有两种——0秒无敌和[JAPI]-单位-设置伤害值为0。伤害回血时,由于callback中会结算一次伤害,所以在course中增加两倍伤害量的回血。最后,如果反弹的伤害不想计算减伤,就把反弹伤害逻辑写在减伤逻辑前面(伤害回血也是一样)

在这里插入图片描述
对于course函数来说,甚至不需要伤害来源,直接扣除目标单位的生命值,也就是造成一个匿名伤害,比如玩家1按下Esc键:
在这里插入图片描述

四、图解刷兵

参考《图解刷兵(CreateUnit源码解析)+数据收集模块》

  • 中心对象:一个无作用域限制,同时携带了大量引用属性的全局对象创建型模式。比如give触发器中的字符串“联盟”和“天灾”,都具有队伍类型和单位类型两种属性。每个单位类型又有单位强度和单位价值两种自定义属性。
  • 工厂:外界对其提供参数,由工厂来制作商品,通过提供的不同参数,创建不同的样式行为型模式·
  • 中介者:又称调停者模式(Mediator Pattern),能有效的处理某个系统被同时调用时产生的冲突问题,使无法同时执行的全局触发器错峰调用,比如下面的inter触发器。
  1. give触发:给中心对象“联盟”和“天灾”各绑定一个单位池:
    在这里插入图片描述

  2. atk1:设置联盟和天灾的队伍强度,然后在游戏开始、第180秒和第300秒各调用一次inter触发,给联盟和天灾分别刷怪。
    在这里插入图片描述

  3. atk2:在刷怪10秒后,命令联盟和天灾的怪物(存活)向对方大基地进攻,并给每个玩家补助600黄金。
    在这里插入图片描述

  4. inter:中介者,接收玩家、单位池、队伍强度和刷怪点四个参数。因为联盟和天灾都是同时刷怪,且都调用CreatUnit函数进行刷怪,如果不限制,就会造成队伍强度计算错乱(同时刷怪,刷出的怪物强度统计到了对方的队伍)。解决办法是调用CreatUnit函数之前先检查其状态(loc_sts的值,0为正常,1为忙碌),只有状况正常(没有被调用)时才调用它进行刷怪。
    在这里插入图片描述

  5. CreatUnit:执行刷怪,并计算当前队伍强度,直到达到队伍强度上限,停止刷怪。
    在这里插入图片描述

五、技能制作

参考《手把手教你做出复杂的自定义技能》,地图名为:单位回应+字幕系统.w3x。

快捷键技能名cd技能效果技能特点
D无尽黑夜14以自身为中心,跳跃和落地时造成小范围伤害,同时赋予[眩晕]共2hit,技能发动中可移动
E舞动的色彩24以自身为中心,持续给近距离的敌人造成伤害,同时赋予[眩晕]每一次伤害与前范围都比前一次高
共3hit,技能发动中可移动
R梦幻表演30召唤一颗宝石提供援护
宝石存在时:每隔1.8秒会自动锁定一名附近的敌人
并进行攻击(最大300码)[共8次]
宝石存在时:受到的伤害会被宝石吸收(最大生命值的30%)
宝石存在时:移动速度+30%,迟缓无效
伤害护盾发动结束时宝石会提前消失
宝石攻击范围内没有有效目标时宝石也会攻击
请设定宝石标识以获取到宝石生效的效果
该技能最大持续时间是1.6 x 8,持续时间内有移速加成
每隔1.6秒进行一次判定,如果护盾剩余生命值为0
那么就没有宝石伤害,同时移除宝石效果
W梦之光12给小范围的自己和队友的武器赋予水属性效果(30秒/0.3倍)
回复微量生命值,解除控制
被动:95%生命值以上时,迟缓无效
缓速和晕眩请调用框架
缓速本质上是一个标签,按照抗性机制,给予角色缓速抗性为0

5.1 常用语句

  1. 马甲单位:通过马甲单位实现特效是模拟可控特效的核心手段。
  2. 打击感三要素镜头震动单位动画自定义音效(WAV格式)至关重要。
  3. 控制与保护暂停单位设置无敌常用于保证技能动画的完整播放,不被干扰。
  4. 数据存储:多使用哈希表而非全局变量,功能更强且更安全。

5.1.1 事件

  • 任意单位事件:几乎所有技能触发的起点。例如:单位释放技能、单位被攻击、单位死亡等。
  • 指定单位事件:针对地图中特定的单位。

5.1.2 条件

主要用于判断是否执行后续的动作。

触发语句类型功能说明
属性判断判断单位的生命值、魔法值等属性(例如:生命值大于0)
单位技能等级判断单位是否拥有某个技能,以及技能的等级(例如:技能等级 ≥ 1)
拥有魔法效果判断单位身上是否有特定的增益或减益效果(例如:用于触发眩晕、击飞等)
是玩家的敌对/同盟单位判断单位间的阵营关系
两个单位之间的距离常用于范围技能或冲刺技能,判断单位是否进入有效范围(例如:距离 ≤ 100)
地形通行状态判断某个点是否可通行(例如:防止单位卡墙)
5.1.3 动作

1. 单位创建与管理

  • 创建单位:最常用的动作之一,主要用于创建“马甲”单位来模拟特效。
  • 设置马甲生命周期:常用于特效消失,最低可设为0.01秒后马甲效消失。在这0.01秒内,可以瞬间改变马甲尺寸,进而改变特效尺寸。
  • 删除单位组:使用完单位组后必须删除,防止内存泄漏。

2. 单位控制与状态

  • 暂停/恢复单位:让单位无法进行任何操作,实现“眩晕”效果。
  • 设置无敌/可攻击:保护单位在技能期间不受干扰。
  • 设置移动速度:改变单位的移动速度。
  • 允许/禁用技能:控制单位在特定情况下能否使用技能。
  • 立即复活:复活英雄单位。

3. 单位外观与动画

  • 改变单位尺寸:按倍数放大或缩小单位模型,特效也会同步变化。
  • 播放单位动画:播放单位模型的特定动作,增强表现力。
  • 改变单位的颜色:通过调整红、绿、蓝和透明度通道来创造“残影”效果。
  • 设置单位飞行高度:实现“击飞”或空中单位的效果。

4. 运动与位移

  • 移动单位:将单位移动到指定点。
  • 设置单位面向角度:改变单位的朝向目标,使得技能可立即对目标释放,而不是还要慢慢转身。

5. 镜头效果

  • 震停止震动镜头:在技能命中时震动玩家镜头,增强打击感。
  • 平移镜头:将玩家的视角瞬间移动到指定位置(例如:英雄复活时)。

6. 伤害与效果

  • 伤害目标:对单位造成伤害,需要注意伤害类型(法术、混沌、神圣等)对护甲的计算不同。
  • 删除魔法效果:移除单位身上的特定魔法效果。

7. 音效

  • 播放音效:为技能添加音效是提升“打击感”的关键。伞哥强调魔兽原生支持单声道WAV格式
  • 设置音效参数:可以调整音效的持续时间、声道、播放速率和音量,实现更精细的控制。

8. 高级与环境效果

  • 创建地形变化:在目标点创建波纹、弹坑等地形变化,提升视觉效果。
  • 增加属性:为玩家增加金币、木材等。
  • 修改英雄属性:修改英雄的力量、敏捷、智力等属性。

9. 数据存储

  • 哈希表:用于在触发器之间传递和存储数据(如整数、实数、单位等),是比全局变量更优的选择。哈希表还具有一定的防作弊能力,因为其存储在内存中的数据是经过加密的(字符串格式),不像全局变量容易被外挂修改。

5.2 无尽黑夜——跳跃和落地时造成小范围伤害和晕眩

  无尽黑夜的技能文档并没有明确的要求时间,但你必须要看到,这里会有一个隐含的时间差(起跳和落下)。对范围造成伤害的动作,至少会执行2次,且每次执行伤害时,需要顺带给予眩晕。没有明确要求伤害范围、伤害值和晕眩时间。

5.2.1 技能数据层

  技能实现时,将数据层与外观层分开,这样更容易实现。数据层具体实现逻辑:

  • 范围伤害使用语句逆天->范围伤害->选取单位实现,以施法单位为圆心,对施法范围内所有地方存活单位造成伤害。
  • 具体伤害计算与晕眩、减速等效果,跟技能逻辑解耦,单独进行函数调用,更方便调整。
  • 运行一个计时器,再实现一次伤害与晕眩逻辑,达到起跳和落地的2hits效果。第二次要重新获取单位来重新得到施法者位置,伤害和晕眩时间可以调整得与第一次不同。

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

5.1.2 伤害函数与晕眩函数

  1. 伤害函数:YDWE专门有一个用于处理伤害的语句——单位-伤害目标

    在这里插入图片描述

  2. 晕眩函数:上部分是数据层:运行一个计时器,暂停晕眩目标的游戏,达到晕眩效果。quick_df部分是外观层,同步运行一个计时器,给晕眩目标加一个晕眩魔法效果:
    在这里插入图片描述

5.1.3 技能外观层

  • 伤害特效:使用dummy实现伤害特效,持续2秒(tempt=2)。技能施法时释放一次,5秒后再放一次(time=5)
  • 跳跃动作:可通过调整飞行高度来实现。动画-改变单位飞行高度语句,可以直接调整飞行单位的高度。如果不是飞行单位,需要为其先 添加删除乌鸦形态

在这里插入图片描述

如果飞行高度100,飞行速率100,那么跳到最高需要1秒。如果飞行速率200,那么只需要0.5秒。如果设为0,那就是瞬间跳到最高:

在这里插入图片描述

5.2 舞动的色彩——造成三次范围伤害(递增)和晕眩

5.2.1 数据层

  基本逻辑:设置技能的初始伤害值demage、技能范围值range、增长系数count。第一次对半径range以内所有敌对单位造成伤害和晕眩。之后运行两个time秒的计时器(伤害间隔),再次造成范围伤害和晕眩,只是 d e m a g e = d e m a g e × c o u n t demage=demage \times count demage=demage×count r a n g e = r a n g e × c o u n t range=range \times count range=range×count

在这里插入图片描述

5.2.2 外观层

  结构和数据层一样,给目标单位绑定荆棘光环和恐怖嚎叫两个特效,并分别在time秒后执行第二次和第三次。特效尺寸bg也需要增强,也是累乘系数count

在这里插入图片描述

5.3 梦幻表演——召唤宝石护盾

在这里插入图片描述

  1. 主函数

    • 为芙兰添加一个自定义键值——宝石护盾,其生命是芙兰最大生命的30%。当护盾生命和宝石攻击次数都>0时,每隔1.6秒造成一次范围伤害(范围300,伤害值300)
    • 由于宝石会造成8次伤害,所以攻击特效不能再分开写。这里添加的攻击特效是群星坠落。
    • 伤害值、增加30%移速和迟缓无效,都通过调用函数实现,不写到主函数里。
      在这里插入图片描述
      在这里插入图片描述
  2. 宝石护盾:通过单位的自定义键值 宝石护盾 来进行判断与触发。当护盾量≥所受伤害时,伤害全额抵消,并设置护盾值-=伤害值;当护盾量<所受伤害时,抵消部分伤害,护盾值=0,结算伤害=伤害值-护盾值。
    在这里插入图片描述

  3. 增加移速与迟缓无效:目前还没有做出迟缓效果。这里简单设置当对单位造成迟缓时,先判断其是否有迟缓无效标签。
    在这里插入图片描述

5.4 梦之光——范围buff

  1. 主函数:为范围内的单位附加水属性伤害buff(持续30秒),以及微量回血和解控。
    水属性伤害buff也通过添加自定义键值“水属性”来实现。当身上有“水属性”时,结算伤害=原伤害+水属性伤害。另外,这里的buff条件设置的是非敌对单位。如果设为同盟单位,自己享受不到buff。
    在这里插入图片描述
      为了实现血量>95%时迟缓无效,需要注册一个子触发器来实现,但是单位只能有这一个子触发器在身上。为了避免每次使用技能都创建一个子触发器,所以创建后将其设为自定义键值(被动触发器),并在每次使用技能前进行子触发器的重置。对于血量>95%时生效,就需要有一个生命值变化事件。每当生命值变化时,判断单位生命值是否大于95%。
    在这里插入图片描述

六、音效系统

6.1 框架搭建

音效系统由以下3部分组成,各模块协同实现多场景、多人环境下的音效播放控制,重点解决音效冲突、范围选择、异步播放等问题。

  • unitVoicedefine:定义单位的基础语音资源。
  • voiceManager:全局音效管理器,负责最底层的播放逻辑,核心要解决的两个问题:
    1. 音效冲突(顶掉):如何管理多个音效的播放,比如是高优先级的顶掉低优先级的,还是等当前音效播完?
    2. 播放范围:这个音效是只有自己能听见,还是一定范围内的所有玩家都能听见?
  • voiceProxy:代理触发器,处理特定类型音效(标签17、18),支持异步播放。
  1. unitVoicedefine:配置通用AI​​和英雄两种单位类型的语音参数,包括语音ID、命令音效数量、标签(如01-23)和对应的语音文件路径(如01u20702620)。
    在这里插入图片描述

  2. voiceManager:这是整个音效系统的“心脏”,

    1. 获取当前锁状态loc_lock = [单位 loc_u 的 vlock]。每个单位身上都有一个变量 vlock,可以理解为当前正在播放的音效的“优先级锁”。

    2. 冲突判断与处理(关键):如果新音效的优先级 (loc_vlock) 大于 单位当前音效的优先级 (loc_lock),说明新音效更重要,需要中断旧的。

      • 获取旧音效的计时器和声音对象。
      • 停止旧音效停止播放 [loc_str] 立刻
      • 清理旧计时器:暂停并删除旧计时器(这个计时器用于在音效播放后自动解锁)。
    3. 播放新音效(范围判断)

      • 获取音效文件:根据单位的“音效ID”(如 20702620)和传入的“标签”(如 02),从预存的目录中拿到具体的声音文件 loc_sr
      • 判断范围参数 loc_range:
        • 如果 loc_range <= 0(单人音效)
          • 检查 loc_u 的所有者是不是本地玩家。如果是,就为本地玩家播放这个音效。其他玩家听不到
        • 如果 loc_range > 0(范围音效)
          • 选取以单位为中心、指定半径为范围内的所有单位。
          • 遍历这些单位,如果某个单位的所有者本地玩家,就为本地玩家播放这个音效。
          • 这样就实现了:范围内的所有玩家都能听到这个音效。
    4. 上锁与解锁

      • 上锁:播放音效后,立即设置单位的 vlock 为新的优先级 loc_vlock,并记录音效对象 vstart
      • 设置解锁计时器:创建一个计时器,时长 = 音效长度 + 1秒。计时器到期后执行的动作是:将单位的 vlock 设为 0
      • 这就好比说:“我现在开始播一个优先级为6的音效,在播完并留出1秒余量之前,这个锁一直占着。期间只有优先级高于6的音效才能打断我。播完后,自动解锁(设为0),以便播放其他音效。”

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

  1. voiceProxy:音效代理,它的存在是为了处理一些特殊状况:单位所有者 ≠ 目标玩家,或者音效标签是17/18/23之一。将“特定玩家音效”和“特殊标签音效”的处理逻辑从核心管理器分离,使 voiceManager 只关注最通用的“单位+范围”音效播放。
    • 检查玩家锁:它不是检查单位vlock,而是检查目标玩家 (loc_up) 的 vlock。这意味着锁是基于玩家的,更适合处理异步音效。
    • 冲突处理:和 voiceManager 类似,如果新音效优先级更高,就停止该玩家正在播放的旧音效。
    • 播放音效:如果目标玩家是本地玩家,就播放音效。
    • 上锁与解锁:同样会为目标玩家设置 vlock 和计时器,而不是为单位设置。
    • 不满足代理条件时:直接运行 voiceManager,将参数原样传递,交给核心管理器处理。
      在这里插入图片描述
      在这里插入图片描述

6.2 使用场景

6.2.1 英雄选择事件

当玩家选择一个英雄单位,且原属于“中立被动”(这是常见的英雄选择机制)时触发:

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

  1. 处理选择逻辑:如果单位正在被选择(防止重复触发),则:

    • 改变英雄所属为触发玩家。
    • 调整飞行高度。
    • 设置英雄属性(如法术强度)。
  2. 播放音效(关键部分)调用运行 voiceProxy <预设>,并传递的参数:
    - loc_u(单位) = 触发单位(这个英雄)。
    - loc_up(目标玩家) = 触发玩家(选择英雄的玩家)。
    - loc_vlock(优先级) = 10(一个很高的优先级,确保能中断大多数音效)。
    - loc_voice(音效标签) = 02(根据图1,这可能是英雄被选择时的语音)。

  3. 后续处理

    • 创建特效(如复活光效)。
    • 向所有盟友和敌人发送文本消息,通知他们某人选择了某个英雄。

6.2.2 千叶之福技能音效

在这里插入图片描述

  • 调用voiceProxy(loc_vlock=6、loc_voice=W)播放主音效。
  • 在600范围单位内再次调用voiceProxy(loc_voice=12),可能触发范围反馈音效。

6.2.3 通用技能发动音效

调用voiceProxy(loc_vlock=4、loc_voice=01),播放技能准备阶段的提示音效
在这里插入图片描述

6.2.4 英雄死亡音效

在这里插入图片描述

  • 第一次调用voiceProxy(loc_voice=11),播放死亡主音效。
  • 第二次调用voiceProxy(loc_voice=02),可能播放死亡余韵音效。清理计时器,避免音效残留。

6.2.5 命令音效

在这里插入图片描述

6.2.6 单位选择音效

当玩家用鼠标点击选中一个单位时,播放该单位的选中语音(如“请指示!”“我准备好了!”)
在这里插入图片描述

6.2.7 单位移动音效

  当单位收到移动指令时,有概率播放一个移动语音(如“出发!”“跟我来!”),增加游戏的反馈感。触发事件​​:单位 - 任意单位 发布指定点目标指令(这通常包括移动、攻击移动等指令)。
在这里插入图片描述

6.2.8 升级音效

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神洛华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值