FPS Microgame源码解析:武器系统

FPS Microgame源码解析:武器系统

Unity官方面向新手的FPSMicroGame,本文分析了一下其中的武器系统。

射击

  • 散射

散射的计算WeaponController.cs脚本里。在GetShotDirectionWithinSpread函数里,主要是通过Vector3.Slerp,将 枪口的前向向量 和 一个随机的从球心到球面的单位向量,做插值。插值比例就是BulletSpreadAngle / 180f。可以想象一下, 两个三维向量角度之差最多是180°,所以BulletSpreadAngle 是最大散射角。

 void HandleShoot()
 {
         
     //...
     // spawn all bullets with random direction
     for (int i = 0; i < bulletsPerShotFinal; i++)
     {
   
         Vector3 shotDirection = GetShotDirectionWithinSpread(WeaponMuzzle);
         ProjectileBase newProjectile = Instantiate(ProjectilePrefab, WeaponMuzzle.position,
                                                    Quaternion.LookRotation(shotDirection));
         newProjectile.Shoot(this);
     }
     //...
 }
 
 
 public Vector3 GetShotDirectionWithinSpread(Transform shootTransform)
 {
   
     float spreadAngleRatio = BulletSpreadAngle / 180f;
     Vector3 spreadWorldDirection = Vector3.Slerp(shootTransform.forward, UnityEngine.Random.insideUnitSphere,
                                                  spreadAngleRatio);
 
     return spreadWorldDirection;
 }
  • 后坐

    • 射击游戏中,为了模拟真实的枪械,后坐力又分为水平后坐力和竖直后坐力。由于这两种后坐力的影响,枪械在连发时,弹道会形成一个T字型,俗称T型弹道。具体原理是:竖直后坐会一直把枪口上抬,抬升到一个最大角度后保持。水平后坐会给弹道增加随机的左右偏移。所以在枪械连发时,可以看到由于竖直后坐的作用,弹道快速上抬,之后高度不变,左右摇摆,得到T型弹道。
    • 完善的游戏中,后坐力的手感表现需要,模型的运动表现 + 弹道的表现 + 镜头动画的表现。当前的FPSMicroGame中,只有模型的运动表现。我们先来看看。在PlayerWeaponsManager.cs里。
      • 在update函数里叠加了每帧的后坐力,m_AccumulatedRecoil其实代表后坐力累加后,期望枪械所在的位置。
      • 在lateUpdate函数里 调用UpdateWeaponRecoil();计算了后坐力的动画,并最终修改了武器的位置WeaponParentSocket.localPosition。这里要注意,后坐力是朝Z轴负方向。
        • UpdateWeaponRecoil函数里,先判断期望的后坐力位置,和当前后坐力位置差异。如果差异过大,则往期望后坐力位置移动。否者说明后坐力已经达到,就开始恢复。
    void Update()
    {
         
        //...
        // Handle accumulating recoil
        if (hasFired)
        {
         
            m_AccumulatedRecoil += Vector3.back * activeWeapon.RecoilForce;
            m_AccumulatedRecoil = Vector3.ClampMagnitude(m_AccumulatedRecoil, MaxRecoilDistance);
        }
        //...
    }
    
    
    void LateUpdate()
    {
         
        UpdateWeaponAiming();
        UpdateWeaponBob();
        UpdateWeaponRecoil();
        UpdateWeaponSwitching();
    
        // Set final weapon socket position based on all the combined animation influences
        WeaponParentSocket.localPosition =
            m_WeaponMainLocalPosition + m_WeaponBobLocalPosition + m_WeaponRecoilLocalPosition;
    }
    
    
    // Updates the weapon recoil animation
    void UpdateWeaponRecoil()
    {
         
        // if the accumulated recoil is further away from the current position, make the current position move towards the recoil target
        if (m_WeaponRecoilLocalPosition.z >= m_AccumulatedRecoil.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值