ARMA3 炮火支援脚本的使用方法——编辑器新手教学向

      观看这篇专栏前推荐先把演示视频了解一下

     然后我们开讲,在arma3中据我所知在不使用mod的情况下,希望ai提供远程炮火打击有两种方法,第一种就是使用官方模块的支援模块,第二种就是使用编辑器代码或者脚本。第一种方法不作为今天的重点,我简单的说一下。

   首先我们打开编辑器,选择f5模块内的支援,从中选择支援提供者和支援请求者。将请求者与玩家相连(右键同步至),请求者与提供者相连,提供者与火炮相连。这样进入游戏后就可以通过滚轮切出支援菜单,使用鼠标十字线为火炮提供轰炸坐标。

如图连接

  下面切入正题,说一下火炮轰炸代码 doArtilleryFire命令

官方wiki上给出的doArtilleryFire命令公式是这样的

mortar1 doArtilleryFire [[3000, 120, 1000], "8Rnd_82mm_Mo_shells", 3];

  其中mortar1为火炮的变量名。自设,一致即可。

  doArtilleryFire后的[3000,120,1000]为轰炸点的xyz坐标,这里可以使用getpos a1(即单位a1的位置)和getmarkerpos“m1”(标记m1的位置)代替,后不赘述(本质上这三个命令都是一个关于xyz的坐标字符串).

  "8Rnd_82mm_Mo_shells"为弹药种类,想要查询单位拥有的弹药可以通过在控制台内输入magazines 单位变量名,执行来得到一个字符串,格式通常是["he","smoke","flare"].此时高爆弹的表述方法可以是“he”,也可以是 magazines 单位变量名 select 0.此时 magazines 单位变量名 select 1就是烟雾弹,以此类推。但是要注意,当select 0的弹夹打光以后,原本的select 1会向前占据select 0的位置,此时的select 0即为烟雾弹(也就是说当he打光了你继续给他下命令就会打smoke而不是不打)。所以通常情况下我建议使用“弹药名称”这种方法表述,更精准。最后一个数字3没什么好说的,就是代表打三发。

esc后出现的控制台

  当我们有了doArtilleryFire命令后我们可以让一门火炮选择炮弹类型和炮弹数量轰炸我们预设的位置。如果我们希望多门火炮做相同的动作当然可以把这个命令多打几遍,这里有一个简便方法就是foreach命令

 {_x doartilleryfire [_tgt,_ammo,10]} foreach [gun1,gun2,gun3]

此时_x就代指foreach后面的gun1,gun2和gun3.也就是这三门炮分别执行{ }内的doartilleryfire命令。

  到这里我们可以给出一个用编辑器触发器就可以触发的三门火炮对一点精确轰炸10发he的代码。我给个例子,相信大家可以一通百通。

只需要将以下代码输入到触发器中并自订一个触发条件即可(红字是需要自己在编辑器摆放并命名的)当然这里说的精确只是个相对概念还要考虑到火炮在相应距离的散步。

{_ammo = getartilleryammo [_x] select 0; _tgt = getmarkerpos "xxx"; _x doartilleryfire [_tgt,_ammo,10]} foreach [gun1,gun2,gun3];

如果我们希望炮弹的落点(至少是瞄准的点)可以在目标点方圆一定距离内内随机,以达到火力覆盖的效果,那么我们就需要使用脚本和一些其他命令辅助。

   简单说一下如何创建脚本在编辑器点击场景,保存,然后再次点击场景-打开场景文件夹,在文件夹内新建txt文件。文件名可自拟,文件后缀将txt改为sqf保存,打开文件即可编辑。

  继续讲代码,希望瞄准点随机需要输入如下代码

_mpos = getmarkerpos "bomb" ;
for "_i" from 0 to 10 step 1 do {
        {_len = round (random 80) ;
        _dir = round (random 360) ;
        _tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;
        _ammo = getartilleryammo [_x] select 0;
       _x doartilleryfire [_tgt,_ammo,1]} foreach [g1,g2,g3];
       sleep 4 ;} ;

下面逐句解释

_mpos = getmarkerpos "bomb" ;设一个轰炸基点为命名为bomb的标记点

for "_i" from 1 to 10 step 1 do { };这是一个for循环语句,设定一个_i,_i的值从1到10每次加1运行{ }内的命令。也就是将{ }的命令重复10次

_len = round (random 80) ;设一个_len为0到80以内任意值取整。rondom是随机,有两种表述方式1为rabdom x,即为从0到x任意值,2为random[最小值,中间值,最大值]。round是取整,取整没有特别必要。

_dir = round (random 360) ; 设一个角度为0到360任意值取整

_tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;

瞄准点的坐标为[基点横坐标+_len乘以cos(_dir),基点纵坐标+_len乘以sin(_dir)]。

[ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] 这个运算也可以用 [_pos,_len,_dir] call bis_fnc_relpos;代替,均为_pos_dir角度,距离_len的那个点的坐标。

翻译一下就是_tgt是以基点为中心,以_len最大值80为半径圆内任意一点(三角函数就不解释了)。每一次运行都会在这个极坐标内取一点。


上极坐标图方便理解

  _ammo = getartilleryammo [_x] select 0;弹药选择select 0,之前讲过了

_x doartilleryfire [_tgt,_ammo,1]} foreach [g1,g2,g3];不说了吧。。

  sleep 4 ;这个说一下,这个意思是等待4秒,我们之前说了{ }内的命令会被循环10次,如果没有sleep命令,将会瞬间完成循环,加了4秒就是每次循环之间停顿4秒,这个时间通常需要大于火炮的装填时间,如果是榴弹炮通常需要给到10以上,因地制宜就对了。sleep命令只能在脚本中生效,触发器内无效,这也是为什么我说随机炮火覆盖一定要用到脚本。

   完整的翻译一下这一段。  选取一个基点,循环做十次{g1,g2,g3分别用一发he轰炸极坐标内一点。 每次循环间隔4秒}

  到这里火炮轰炸的事就大概讲完了,接下来讲我演示内选择地图内一点,单击形成标记的代码

openmap true;
click =0;
["82mm","onmapsingleclick",{
              marker = createmarker ["bomb",_pos];
              marker setmarkertype "hd_destroy";
              click =1;
}] call bis_fnc_addstackedeventhandler;
waituntil {click == 1};

openmap true;打开地图

click =0;设click值为0

["82mm","onmapsingleclick",{    }] call bis_fnc_addstackedeventhandler;添加一个事件检查器名字为82mm(其实这个名字无所谓,随意),检查的操作为在地图上单击鼠标左键。当你做出onmapsingleclick这个行为时,运行{ }内动作。

{
              marker = createmarker ["bomb",_pos];
              marker setmarkertype "hd_destroy";
              click =1;
}

{ }内为 marker = 新建一个名称为bomb地点为单击处的标记,marker的类型为摧毁,设置click值为1

waituntil {click == 1};等待click值为1时,继续运行下方代码

下方接上文讲的火炮轰炸代码。

轰炸代码之后考虑到重复使用这个脚本可能会出现弹药不足的情况,可以在后面加一个增加弹药的命令

{_x addMagazines ["rhs_mag_3vo18_10", 1]} foreach [g1,g2,g3];增加弹药10发

sleep 10 ;等待十秒

deletemarker "bomb";删除bomb标记,如果不删除这个标记可能会影响再次使用此脚本。因为叫bomb的标记是独一无二的。重新标记需要删除后重新添加。

脚本最后再说一下字幕

["82mm迫击炮小队","正在对目标进行火力覆盖"] call bis_fnc_showsubtitle;使用这个命令["某人",“某句话”] call bis_fnc_showsubtitle;将这个命令穿插在上文脚本的各个阶段处即可实现在合适的时候出现合适的字幕来提升代入感

脚本说完了,说下触发脚本的方式,可以在触发器内输入如下

execvm"脚本文件名.sqf";

当触发器被触发,脚本即被触发

另外一种提升代入感的方式,视频中演示的方式,通过鼠标滚轮菜单选择触发脚本,这个方法是在另外一个up主 弗里曼博士的锤子 学习的

在一个单位的初始栏中输入

this addaction ["在滚轮菜单显示的名字","脚本文件名.sqf",[],1.5,true,true,"","true",3];

当你靠近这个单位3米时,可以滚轮选择菜单看到"滚轮菜单显示的名字"这个选项,选择这个选项后触发脚本。

你可以把这个命令放在自己身上,也可以放在一个电台。步话机士兵身上。

当然也可以是某个触发器,触发器可以设定一个触发条件比如   !alive a(当a死亡时触发)

但注意此时的this addaction ["滚轮菜单显示的名字","脚本文件名.sqf",[],1.5,true,true,"","true",3];中的this应该改成某个单位比如a1.

这时的效果就是,当a死亡后,你靠近a1 3米时,出现滚轮。

    至于确定敌人坐标这个事。三角定位吧,这个我就不说了

最后放一下视频中的代码

红锤俄军2B14 82mm迫击炮版本

openmap true;
click =0;
["BOMB","onmapsingleclick",{
              marker = createmarker ["bomb",_pos];
              marker setmarkertype "hd_destroy";
              click =1;
}] call bis_fnc_addstackedeventhandler;
waituntil {click == 1};
_mpos = getmarkerpos "bomb" ;
["82mm迫击炮小队","正在对目标进行火力覆盖"] call bis_fnc_showsubtitle;
for "_i" from 1 to 10 step 1 do {
        {_len = round (random 50) ;
        _dir = round (random 360) ;
        _tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;
        _ammo = getartilleryammo [_x] select 0;
       _x doartilleryfire [_tgt,_ammo,1]} foreach [gun1,gun2,gun3,gun4];
       sleep 4 ;
} ;
sleep 10 ;
deletemarker "bomb";

红锤俄军D-30 122mm榴弹炮版本

openmap true;
click =0;
["BOMB","onmapsingleclick",{
              marker = createmarker ["bomb",_pos];
              marker setmarkertype "hd_destroy";
              click =1;
}] call bis_fnc_addstackedeventhandler;
waituntil {click == 1};
["炮阵地指挥员","收到坐标,正在解算射击诸元"] call bis_fnc_showsubtitle;
_mpos = getmarkerpos "bomb" ;
       {_len = round (random 10) ;
        _dir = round (random 360) ;
        _tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;
        _ammo = "rhs_mag_3of56_10";
       _x doartilleryfire [_tgt,_ammo,1]} foreach [g1,g2];
       sleep 10 ;
["炮阵地指挥员","目标确认,全连5发齐射,放"] call bis_fnc_showsubtitle;
for "_i" from 1 to 5 step 1 do {
        {_len = round (random 20) ;
        _dir = round (random 360) ;
        _tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;
        _ammo = "rhs_mag_3of56_10";
       _x doartilleryfire [_tgt,_ammo,1]} foreach [g1,g2,g3,g4];
       sleep 7 ;
      {_len = round (random 50) ;
        _dir = round (random 360) ;
        _tgt = [ (_mpos select 0) + (_len*cos(_dir) ) , (_mpos select 1) + (_len*sin(_dir) ) ] ;
        _ammo = "rhs_mag_3of56_10";
       _x doartilleryfire [_tgt,_ammo,1]} foreach [g5,g6,g7,g8];
       sleep 7 ;
} ;
sleep 10 ;
deletemarker "bomb";




完结

有什么问题可以在评论区提,我尽力解答。如果这篇文章对你有帮助的话,请不要忘了支持一下,点赞投币收藏转发!






本文为我原创

本文禁止转载或摘编

-- --
  • 投诉或建议
评论