[开发者心得] [知其然]如果实现更丝滑的坦克炮台旋转效果

[复制链接]
878 |0
许你春秋 发表于 2023-12-14 09:43:27 | 显示全部楼层 |阅读模式
如何让炮台转的无比丝滑?使用add?lerp?四元数?不不不,我们还有新方法,答案在视频最后。




思路说明:
高级轮式载具是通过交互物将角色绑定在载具车,而交互物只是限制了角色的移动,并不限制旋转和动画播放,所以是否可以像传统的枪战射击类游戏一样,将炮台想象成一个手持超大号热武器的角色呢。

准备工作:
1:高级轮式载具
   --用来实现下部半部分车身效果
   --绑定四轮个轮并设置车轮显示为关闭,载具如果没有绑定车轮模型,簧下质量会很小,造成开起来不稳的情况。
S2.png


2:炮台预制体和炮弹预制体
   --用来绑定到角色身上,炮台模型在预制体中提前关闭了碰撞,防止挂在角色身上时和角色自身的碰撞产生冲突
   --在炮管口放置一个对象发射器,用来实现开火发射炮弹效果
S3.png



3:角色
     --将角色属性中的[角色面朝方向]设置为[以控制器方向],就可以实现旋转相机镜头时,角色会跟着一起转;
S1.png


4:组装坦克
     --准备两个脚本,一个是将炮台动态生成并绑定到角色根节点插槽内,选择根节点插槽是防止角色自身的待机动画引起的炮台模型出现晃动。


@Component
export default class NewScript extends Script {

    battery: GameObject;
    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        if (SystemUtil.isClient()) {
            GameObject.asyncSpawn("8902771A46CE3FD3151755B5F1AA9182").then((obj) => {
                this.battery = obj as GameObject;

                let player = Player.localPlayer;
                player.character.attachToSlot(this.battery, mw.HumanoidSlotType.Root)
                this.battery.localTransform.position = new Vector(0, 0, 140)
                console.log(`player battery name`, this.battery);
            });
        }
    }
}



     --第二个脚本用来实现开炮逻辑

     --这里只是以最简单的方实现实现了一个开火发射弹炮的逻辑,不能做为实际项目使用时的代码逻辑,仅供效果参考。


@Component
export default class NewScript1 extends Script {

    boom:GameObject //炮弹预制体

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        let gun = this.gameObject as mw.ObjectLauncher
        let effectFire = gun.getChildByName("FrieEffect") as Effect;
     
        Event.addLocalListener("GUNFIRE", async () => {
            effectFire.play(); //播放开火特效
            this.boom = await GameObject.asyncSpawn("7D630BBF422473FB49F2BCAA0C20FEAE") as GameObject; //生成炮弹预制体
            gun.spawnProjectileInstanceLaunch(this.boom.gameObjectId, gun.worldTransform.position, gun.worldTransform.getForwardVector()) //对象发射器执行发射逻辑
        })

        //炮弹命中目标后,播放爆炸特效,并销毁炮弹预制体
        gun.onProjectileHit.add((obj,hitobj,hitResult) => {
            EffectService.playAtPosition("92830",hitResult.traceEnd.clone().add(new Vector(0,0,100)),{
                scale:new Vector(1.5,1.5,1.5)
            });
            obj.destroy();
        })
    }
}




回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表