【求助】单位武器故障!(已解决)

是这样的,在做TA-SOM的时候,方尖塔这个单位的武器系统非常奇怪,有时可以正常使用,有时无法正常使用,表现方式为火箭弹打不出去,在单位正下方一段距离处演示爆炸动画,但不能对目标造成任何伤害,而比较奇怪的是,这种现象并非每次都会发生,为了测试,我把单位的制造价格和时间都调整成秒造,然后连续造了5个,发现有2个可以正常开火,而3个却不能,总之,每次测试都是有的能开火,有的不能;然后把该武器搭载到一个移动单位上,却没有发现故障,但是该单位在使用一定时间后,有可能故障,甚至退出时造成游戏崩溃;另外,在最早的地狱火战车(移动单位)上曾经测试过类似武器时也发生过“方尖塔”现象,只不过那个时候是100%武器故障。

那么我简单把武器参数说一下,该武器属于火箭发射类武器,但不同于OTA的火箭类武器,该武器类型属于抛物线类,火箭弹是自制模型,没有使用默认渲染效果4,而且有尾烟动画(我曾经试图去掉尾烟,但无改进),另外有一定范围的攻击命中率,火箭有加速度数据,同时,方尖塔单位的脚本在发射时有reload类型的脚本描述(更换子弹),而移动单位在瞄准和开火时没有类似脚本。

故障分析:

  1. 自制火箭弹模型可能引起出错:但目前项目中有大量的武器使用了自制炮弹模型,没有发生异常;
  2. 脚本中火箭连发数量太大:在脚本中使用了左右16发两扇共计32连发的发射脚本,每32发上弹一次,怀疑可能计算量大,但是考虑到出故障的单位从第一发就开始故障,而没出故障的单位则可以连续反复的执行全套脚本,因此难以分析故障点;
  3. 由于烟雾效果或弹道命中率以及其他武器参数中影响到整体的武器发射效果的计算,从而导致数据冗余或无法计算,但涉及面太广,一时难以分析故障点。

以上就是大概的情况了,希望高手帮助分析,并给出解决方案,谢谢。
SoMfixed_MT.jpgSoMfixed_MT.rar (3 MB)

PS. 测试说明,该单位直接放置在TOTALA文件夹下,运行OTA进入游戏,ARM和CORE的40建造菜单的最后一个,图标见上图,为了测试方面,单位暂时修改成秒造,logo贴图可能会有故障,请无视之,另外,单位毁灭后的残骸暂时用了个别的残骸,也请先无视,重点是解决武器发挥不稳定的问题,谢谢!

直接贴脚本和武器参数上来比较好。你那个武器跟猫版2级的战车那个一样的,对照一下参数,看看有没有漏了什么。

估计脚本设置出射点有问题。武器参数大概也有问题,可能是多了影响弹道的参数。

其实这个完全可以用BRUST?用reload很麻烦的。

turn sleeve to x-axis (0-pitch) speed <60>;

好像错了吧,一般看到的都是

turn sleeve to x-axis <0> - pitch speed <60>;

不过我不是很懂这个,或许你这样写也可以?

我没看见reload子脚本。

反编译的时候看出问题了,你设置的静态变量ML被系统错误识别为是否处于瞄准状态了bAiming,建议增加bAiming变量,以免系统错误识别。

那个武器参数我原来自己写过,跟那个差不多,但一直运行不了,所以直接管猫要了这个过来,稍微调整了一下,晚上我去问问猫吧,那家伙现在也不来论坛了,有可能跟什么地方潜水呢。。。

发现你在瞄准脚本里加reload,可能是这个原因导致系统编译时错误将发射口切换(静态变量)当作是否处于瞄准状态(静态变量)。

建议重写脚本,参考以下
TA脚本解析 (总目录)

多炮管切换和攻击间隔控制脚本分析
http://bbs.taclub.net/thread-12210-1-1.html

//下面TA-EXCESS II alpha1e版的CORE的T1双管炮坦克的脚本,估计每个版本的都一样,如果你的版本不一样也可以对照看看
//解析这个脚本的目的是介绍:如何用脚本控制攻击间隔

#define TA

#include “sfxtype.h”
#include “exptype.h”

piece base, hull, lftrack, lfshadow, rftrack, rfshadow, lbtrack, lbshadow, rbtrack, rbshadow, lplate, rplate,
turret, pitchturret, barrel1, fire1, barrel2, fire2, flare1, flare2, flare3, decor;

static-var DamageNow, LastDamage, Cannon, Reloading; //定义静态变量,cannon和Reloading是这里要解析的

SmokeUnit(HealthPercent, SleepTime)
{
signal 8;
set-signal-mask 8;
while( get BUILD_PERCENT_LEFT )
{
sleep 500;
}
while( TRUE )
{
HealthPercent = get HEALTH;
if( HealthPercent < 60 )
{
emit-sfx 256 | 1 from decor;
emit-sfx 256 | 1 from lplate;
SleepTime = 300;
}
if( HealthPercent < 30 )
{
emit-sfx 256 | 2 from pitchturret;
emit-sfx 256 | 2 from rbtrack;
SleepTime = 200;
}
sleep SleepTime;
}
}

HitByWeapon(AngleX, AngleZ)
{
DamageNow = get HEALTH;
if( DamageNow <= LastDamage - 10 )
{
signal 128;
set-signal-mask 128;
LastDamage = DamageNow;
turn base to z-axis AngleZ speed <105.000000>;
turn base to x-axis AngleX speed <105.000000>;
wait-for-turn base around z-axis;
wait-for-turn base around x-axis;
turn base to z-axis <0.000000> speed <30.000000>;
turn base to x-axis <0.000000> speed <30.000000>;
return (0);
}
LastDamage = DamageNow;
}

RockUnit(AngleX, AngleZ)
{
turn base to x-axis AngleX speed <25.000000>;
turn base to z-axis AngleZ speed <25.000000>;
wait-for-turn base around z-axis;
wait-for-turn base around x-axis;
turn base to z-axis <0.000000> speed <10.000000>;
turn base to x-axis <0.000000> speed <10.000000>;
}

Reload() //装弹脚本,控制攻击间隔
{
Reloading = 1; //当静态变量 Reloading=1时
sleep 3500; //延迟3500毫秒,也就是3.5秒
Reloading = 0; //Reloading=0时,什么也不做
return (0); //返回0
}

Create()
{
DamageNow = 100;
LastDamage = 100;
Cannon = fire1; //出生时Cannon = fire1,fire1是炮弹的射出点
Reloading = 0; //初生时Reloading = 0

hide flare1;
hide flare2;
hide flare3;
dont-cache flare1;
dont-cache flare2;
dont-cache flare3;

spin flare1 around z-axis speed <200.00>;
spin flare2 around z-axis speed <-200.00>;
spin flare3 around z-axis speed <2000.00>;

start-script SmokeUnit();
}

StartMoving()
{
dont-cache lftrack;
dont-cache rftrack;
dont-cache lbtrack;
dont-cache rbtrack;
}

StopMoving()
{
cache lftrack;
cache rftrack;
cache lbtrack;
cache rbtrack;
}

RestoreAfterDelay()
{
sleep 4000;
Cannon = fire1;
turn turret to y-axis <0.000000> speed <50.000000>;
turn pitchturret to x-axis <0.000000> speed <15.000000>;
start-script SmokeUnit();//Smoke script seems to disappear sometimes. This should fix the issue.
}

SweetSpot(PieceNum)
{
PieceNum = turret;
}

QueryPrimary(PieceNum) //炮弹的射出点
{
PieceNum = Cannon; //射出点为Cannon,在下面开火时再令Cannon=fire1和fire2,这样就可以让两根炮管轮流开炮了
}

AimFromPrimary(PieceNum)
{
PieceNum = pitchturret;
}

AimPrimary(Heading, Pitch) //瞄准的脚本
{
signal 2;
set-signal-mask 2;
turn turret to y-axis Heading speed <100.00>;
turn pitchturret to x-axis <0.00> - Pitch speed <30.00>;
while( Reloading == 1 ) //如果Reloading = 1
{
sleep 100; //延迟0.1秒
}
turn turret to y-axis Heading speed <100.00>;
turn pitchturret to x-axis <0.00> - Pitch speed <30.00>;
wait-for-turn turret around y-axis;
wait-for-turn pitchturret around x-axis;
start-script RestoreAfterDelay();
return (1); //返回1
}

FirePrimary() //开火的脚本
{
if( Cannon == fire1 ) //当Cannon == fire1时
{
Cannon = Fire2; //就让Cannon = Fire2,下面炮口火光动作,不管
move flare1 to x-axis [0.00] now;
move flare2 to x-axis [0.00] now;
move flare3 to x-axis [0.00] now;
move flare1 to z-axis [0.00] now;
move flare2 to z-axis [0.00] now;
move flare3 to z-axis [0.00] now;

move barrel1 to z-axis [-2.00] speed [40.00];
move flare1 to z-axis [-1.5] speed [30.00];
move flare2 to z-axis [-1.00] speed [20.00];
move flare3 to z-axis [-0.5] speed [10.00];
show flare1;
show flare2;
show flare3;
sleep 150;
hide flare1;
emit-sfx 256 | 2 from fire1;
sleep 25;
hide flare2;
sleep 25;
hide flare3;
emit-sfx 256 | 1 from fire1;
move barrel1 to z-axis [0.00] speed [2.00];
return (0); //返回0
}
Cannon = fire1; //让Cannon = fire1,到这里的目的是为了两个炮管轮流开炮
start-script Reload(); //启动Reload()脚本,延迟3.5秒,使攻击产生3.5秒的间隔

move flare1 to x-axis [-1.80] now;
move flare2 to x-axis [-1.80] now;
move flare3 to x-axis [-1.80] now; //这3句作用是把火光左右移到旁边的炮管口
move flare1 to z-axis [0.00] now;
move flare2 to z-axis [0.00] now;
move flare3 to z-axis [0.00] now; //这3句是前后移动到初始位置,因为这个火光闪时还会移动

move barrel2 to z-axis [-2.00] speed [40.00];
move flare1 to z-axis [-1.5] speed [30.00];
move flare2 to z-axis [-1.00] speed [20.00];
move flare3 to z-axis [-0.5] speed [10.00];
show flare1;
show flare2;
show flare3;
sleep 150;
hide flare1;
emit-sfx 256 | 2 from fire2;
sleep 25;
hide flare2;
sleep 25;
hide flare3;
emit-sfx 256 | 1 from fire2;
move barrel2 to z-axis [0.00] speed [2.00];
}

//这就是一般的双管炮的攻击间隔控制的过程,两根炮管各攻击一次之后,静态变量 Reloading=1,延迟3.5秒,这样就实现了两管轮流开炮后冷却一会再开炮。实际上还可以两根炮管各配一个武器,免去用Reload脚本,不过相比之下那样会消耗多一点资源。不会C语言的,只要会改延迟时间就好了,其它不用管。

//TA-EXCESS II的模型基本都是一个炮口火光,那根炮管开火就让火光“立刻移动”过去在那里闪,这样做的目的是为了节省一个炮口火光的模型,减少多边形数量而已。

Killed(Severity, CorpseType)
{
hide flare1;
hide flare2;
hide flare3;
if( Severity <= 50 )
{
CorpseType = 1;
explode lftrack type BITMAPONLY | BITMAP3;
explode rftrack type BITMAPONLY | BITMAP3;
explode lbtrack type BITMAPONLY | BITMAP1;
explode rbtrack type BITMAPONLY | BITMAP1;
explode pitchturret type SHATTER | BITMAP5;
return (0);
}
CorpseType = 2;
explode lftrack type BITMAPONLY | BITMAP3;
explode rftrack type BITMAPONLY | BITMAP3;
explode lbtrack type BITMAPONLY | BITMAP3;
explode rbtrack type BITMAPONLY | BITMAP3;
explode barrel1 type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP1;
explode barrel2 type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP1;
explode pitchturret type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP1;
explode turret type BITMAPONLY | BITMAP5;
explode hull type SHATTER | BITMAP5;
}

//总结,3炮管,4炮管之类大概也是这样处理,只要在炮管轮流那里加其它炮管就可以。

只能提供这么多了,具体怎么写,不会,还是找XPOY写吧,32个炮口太晕了。:soso__15501390449810790162_4:

我用的方法跟这个差不多,事实上是在这个方法上改进的,另外,我不认为是脚本的问题,很可能跟TA引擎的计算方法有关,因为并不是每次武器都失效,不管怎么说,还是感谢你的热心参与。

顺便召唤一下HFox,给看一下这东西要怎么改进才能稳定

反编译的时候看出问题了,你设置的静态变量ML被系统错误识别为是否处于瞄准状态了bAiming,建议增加bAiming变量,以免系统错误识别。

主要原因是这个,你反编译一下就能发现这个问题,为什么会这样我也不知道。但是这个错了瞄准系统肯定崩溃了。所以导弹射出来就出问题。

另外,TA规定炮弹对发射者本身不造成伤害。可以用垂直导弹车证实。还有一种可能是发射点被移动到地面以下,也不能造成伤害,不过显示效果照样。

没看明白,反编译的时候,所有自定义变量都会被写成Static_Var_(加一个数字),这是系统自动的,因为即便你自定义了“ML”,系统在识别的时候还是会按照“Static_Var_1”来识别,增加bAiming是什么用途,可否写个例子?

ML这个变量是用来识别当前发射到第几发了,瞄准脚本中会做一个判断,只有当进行到最后一发,也就是第32发,并且大于32时,执行“填装”脚本,同时也是闭合脚本(闭合的瞬间会提升装甲,因此把填装动作放在这里进行描述),填装执行完毕后ML值等于1,从第一发开始计算。我目前唯一怀疑的是那个ML值的初始化要不要在闭合脚本里去体现,会好些。。。我的意思是,ML的初始化目前在脚本中一共出现在三个点:

  1. create(),也就是单位制造时的初始化;
  2. restoreafterdelay(),单位失去目标后的恢复脚本;
  3. 瞄准脚本中的副脚本,也就是在判断语句的最后面,那么我在想,判断时会执行call-script deactivatescr(),因此不如把ML的初始化放在deactivatescr()的最后一行

:6_273:我反编译的结果是ML变成baiming,而不是正常的Static_Var_1
baiming是个系统变量,和普通的静态变量不同。
baiming用于判断单位是否处于瞄准状态,只有0和1两个有效值。当大于1时,例如32,baiming无法正确判断,所以攻击方向除了问题,直接打到脚下了吧。

不是吧??我没遇到这问题呀。。。你把UFO放到游戏中运行,是什么效果?是我一楼说的那样吗?

我用你那个cob进行反编译,就是这样。很奇怪。

bAiming是自定义变量吧,有人用它干预瞄准,比如,只有单位处于停止状态时可以发射,运动中不可瞄准发射,就好象星际争霸那样,但为什么反编译会弄出这个变量,我还是不明白,截个图过来看看,到底什么情况。。。

我的测试结果是3个正常发射,2个不正常

bAiming是系统变量,反编译的时候不会变成Static_Var_1
现在似乎问题是,这个脚本有时候能识别为Static_Var_1,有时候却识别为bAiming,当为bAiming时,攻击就出问题。

果然如此。。。看看没有没其他人测试吧,估计也会是这样。。。

再测了一次是1个正常,4个不正常,看来有不稳定性

是呀,使劲顶这个帖子,xpoy过来看看呀。。。TRO在不在??

其实我觉得你为何不按标准写法,重写一个reload子脚本避免这种情况?