射击游戏问题记录

射击射线方向设置为枪的z轴正方向,使用Debug.DrawRay(),画出的射线在两种情况之间不停变化。

94ced98c92c24d359332fbc25d85665a.gif

此时人物的Chest用了Aim Constraint组件,把这个组件关掉,这个现象的就消失了,射线很平稳。

推测原因:AimConstraint组件在不停改变Chest的旋转,Debug.DrawRay()如果在Update里执行,好像在一帧里Update()和AimConstraint执行的顺序是不一定的,有些帧Update()执行时AimConstraint组件还没有改变Chest的旋转,Chest的朝向还和没有AimConstraint一样,它的子物体机瞄相机forward方向发出的射线也是原来的方向。

把人物仰起来,进一步证实了这个猜想:两条射线一条是仰起的,一条还是平的。23905cdd91224412a9179e2474fb76dd.gif

解决方法:在LateUpdate()里调用计算射击射线的起点和方向的代码,可保证计算射线起点和方向时AimConstraint已经对Chest的旋转做过改变。好像在一帧里LateUpdate()总是在AimConstraint之后执行。

Aim Constraint约束的物体旋转不对

想让人物头的z轴朝向小球,结果变成了这样

23270e8ae107bcf3e49640926d4b72da.png

原因:Aim Constraint里的Constraint Settings设置了Rotation Offset的Y为90.

f5d479aec9d627ba462f5b68f2536e8b.png

使用IK调整手的位置,但是手的位置不在IK的位置,有偏差

左手IK是枪的子节点。坐标轴标识的是左手IK的位置,明显在左手下方。

1af0f441fe2486f61b4b036386a4bf68.png

又在人物的Chest下建了个子节点作为左手IK目标,发现手能被完美拉到IK目标的位置。

f7a8b27c3b4fc151500abd59799ae393.png

又做了几个实验,不改变IK目标的位置,只改变父节点,左手的位置确实会变化:

做Neck的子节点:手在IK目标处

4e113a3a6d52580c8d96b3553606072f.png

做Head的子节点:手在IK目标下方

fa129ca0baca88dd1516cff9d1f61638.png

做Right wrist的子节点:手在IK目标上方

0b7961f3043454b0773d723aae05b62c.png大概规律:假设被约束物体和IK目标的最低级共同父节点是P,IK目标最多可以做P的一级子节点而没有偏移。这里枪和左手的最低级共同父节点是Chest,IK目标作为Chest及其一级子节点Right shoulder、Neck的子节点时,没有偏移,从Right shoulder的一级节点Right arm开始往下,Neck的一级节点Head开始往下,IK目标做这些节点的子节点时,会出现偏移。

但是这不合理,设置IK的方法接收的只是一个Vector3和一个Quaternion,这几个方法根本不知道给它们位置和旋转数据的节点是谁的父节点。

后来发现还是因为AimConstraint组件。我给Head加了AimConstraint组件,由前面的经验知道,在某些帧执行Update()的时候AimConstraint是不生效的。这里可能IK用的是AimConstraint生效前的IK位置,窗口里显示的是AimConstraint生效后的位置。把Head的AimConstraint关掉,确实IK位置和右手一致了。

可以得出结论:OnAnimatorIK()执行的时候AimConstraint还没有生效,但是手动把IK拖成Head的子节点时AimConstraint是生效了的,且Scene里显示的是AimConstraint生效后的位置。或者说,如果IK目标是一个带有AimConstraint的物体的子物体,那么用来约束时用的是没有启用AimConstaint时IK的位置。

下面的实验可以进一步证明这一点:把IK作为Head的子物体,通过改变AimConstraint的参数使头部转动(可以改Sources物体的位置,也可以改Aim Vector、Up Vector),IK的位置并没有变,右手的位置也没有变。

71265820e9d746e696105b8f1e356cf3.png

那么有没有方法让OnAnimatorIK()使用AimConstaint生效后的IK位置?或许可以在LateUpdate()里把IK的位置和旋转存在变量里,再传给OnAnimatorIK(),我试了,IK是能跟头一起运动了,但是有滞后。而且手的位置和IK偏差很大。

110554eb473913e2c83d8f01035e100a.png

据此可以得到经验:调IK之前务必先关掉AimConstraint,这样无论是Scene窗口里看到的IK位置,还是OnAnimatorIK()里用到的,才和实际的数据一样。

我在Chest上也挂了AimConstraint,那么如果把IK改成Spine的子节点,则引擎先在AimConstraint没生效时把手约束到IK的位置,再加上AimConstraint的效果。结果就是腰的仰角越大,手和IK偏差越大,实验结果确实是这样:

95e84fb6664cf845eddd8a89f2b813c5.png

而把左手IK挂在枪上产生的偏差很容易想到是因为引擎在双手IK没生效时确定好双手IK的位置,然后使双手IK生效,这时左手IK因为右手被约束偏移而产生了偏移,而左手还是被约束到IK生效之前的位置,导致二者位置不一致。这一点可以关闭右手IK,看左手和左手IK是否一致来确定。

关闭右手IK后左手IK和左手:位置一致

65c22219360bddbe8ee0cd301f3f01b1.pngde7ccf0fabf644b86202e864db9fa720.png

开启右手IK,左手IK的位置产生一个偏移,左手位置不变:

a08e56b310c3d6fee31ce76295dadf65.png

更一般的结论:使用多个改变动画的组件协作时(如IK、AimConstraint、AnimationRigging、AvatarMask),出现未预期的效果很可能是因为几个组件没有按预想的顺序叠加,可能是各自生效后叠加,或者叠加顺序不对。此时可以把所有组件撤掉一个个加上,看从哪一步出问题。所以应该少用改变动画的组件,尽量修改动画本身。

执行Destroy()没有生效

a75c3c1b0a586780c5f3cb7dc2bf9aca.png

原因:ParticleSystem是组件,Destroy()组件是从物体上移除该组件。

解决方法:改成Destroy(bloodshed.gameObject);

丘丘人每换一次弹匣,弹匣会变小一些

换弹匣就是把弹匣挂到左手上,装弹匣的时候再挂回枪上。这个枪素材的scale不是1,我知道和这个有关系。其他人物换弹匣没这个问题。

我发现

1.父物体scale变化时,子物体在监视器里的scale不变,但是子物体的实际大小变了

2.物体的父物体改变后,引擎会自动修改它的scale,使它的实际大小不变,这应该能保证换弹后弹匣大小不变

a2f8d53585fe468b425b0a49ee7b4474.png

3.这个问题和我把Mag弹匣作为Body枪身的子物体有关,作为根节点AK47的子物体是没问题的,而且根节点的Scale是1,Body的Scale不是1.

cff8bce8e6b221c29ef96c5a2711dde2.png

今天用胡桃换了很多次弹匣,发现弹匣也是会变小的,只是每次变小的不明显,要换很多次才能看出来。而且每换一次弹匣的Scale都不一样。

1351193a5131519169fe756a936bc997.png22c5810cdf8a08364fb813386b5edd60.png

结论就是:一个物体的父物体会变化的时候,尽量把它挂在Scale是1的物体下。如果不是1就在blender里ctrl a应用缩放。

敌人没有按动画事件设置的频率射击

使用动画事件控制敌人开始射击和停止射击的时机,人物没有按设计的频率射击。很长时间不射击,也有时候不停射击。

这里打印pullTrigger,是True。但是敌人检查器的pullTrigger字段是False。

然后我想到我刚给死亡动画加了停止射击的关键帧,且Any State会过渡到死亡状态。把死亡动画的停止射击移除,果然问题消失了。但是它又没有转换到死亡状态,为什么会播放死亡动画的关键帧?

人物死亡使用布娃娃效果,敌人打死NPC没有关闭animator,我打死NPC正常开启布娃娃

开启布娃娃里用协程关闭了animator,研究发现在yield return之前打印都正常,后面打印没有效果。只有NPC打死NPC有这个问题,NPC打死我、我打死NPC都正常。用[ContextMenu()]执行死亡方法也有问题。

这段代码是我抄的。为什么要用协程关动画呢?我试了试直接关动画,布娃娃正常开启了。

后来这个问题不出现了。不了了之了。

敌人被打死后我靠近又突然开枪

开始运行后人物自己向前移动

原因:不小心在人物Hips上加了非触发器碰撞体,和人物碰撞体碰撞。

开始运行后第一次换弹回到初始的位置和旋转

把Animator Override Controller替换换弹动画的代码删掉,问题就消失了。

然后注意到此时人物用的是Animator Controller不是Animator Override Controller。说明运行时新建Animator Override Controller再替换动画会导致人物回到初始Transform。应该直接给人物用Animator Override Controller。

M21开瞄准镜后瞄准相机只能左右旋转,改变人物仰角瞄准相机的仰角不变,关镜、到Scene窗口再回去仰角会更新

好像在瞄准镜状态下人物的仰角没有每帧更新。

另一个狙击枪VSS没这个问题。初始拿VSS,换成M21会有问题。改成初始拿M21,换成VSS,两个枪都没问题了。

针对看一眼Scene窗口就更新的情况,我把Game和Scene窗口同时显示,然后就™没问题了。好像animator.SetBoneLocalRotation()有人看着它就更新,不看着就不更新。

把瞄准相机后移到某个程度,问题就消失了。

然后我去找animator更新的设置,把Culling Mode改成Always Animate,问题解决。

->

VSS没出问题可能因为它比较短,animator还认为我在看它,所以保持更新。我把VSS的瞄准相机往前放,放到这个位置,也出现同样的问题:

出问题的距离比M21远得多,然后我发现VSS模型的缩放是100,可能和这个有关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值