项目实训(十二)——FPS游戏枪械射击弹孔及子弹散射

一、前言

本篇博客记录的内容为上篇的延续,将介绍完成的射击反馈震屏、子弹散射等工作内容。实现了子弹击中物体产生弹孔的功能。

二、枪械射击弹孔及音效

在之前导入的特效包中找到Bullet_GoldFire_Small_Impact,然后拖拽到场景中去。
在这里插入图片描述
在Weapon文件夹下创建一个Bullet脚本,在其中完成设计弹孔的相关逻辑的编写。由于rigidbody会产生资源的消耗,所用用transform来移动就可以。

using System;
using Unity.Mathematics;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Scripts.Weapon
{
    
    
    public class Bullet : MonoBehaviour
    {
    
    
        public float BulletSpeed;//子弹速度
        public GameObject ImpactPrefab;
        public ImpactAudioData ImpactAudioData;
        private Transform bulletTransform;
        private Vector3 prevPosition;


        private void Start()
        {
    
    
            bulletTransform = transform;
            prevPosition = bulletTransform.position;//初始化
        }

        private void Update()
        {
    
    
            prevPosition = bulletTransform.position;

            bulletTransform.Translate(0, 0, BulletSpeed * Time.deltaTime);

            if (!Physics.Raycast(prevPosition,
                (bulletTransform.position - prevPosition).normalized,
                out RaycastHit tmp_Hit,
                (bulletTransform.position - prevPosition).magnitude)) return;//没有碰撞到物体的话就返回
            var tmp_BulletEffect =
                Instantiate(ImpactPrefab,
                    tmp_Hit.point,
                    Quaternion.LookRotation(tmp_Hit.normal, Vector3.up));
            
            Destroy(tmp_BulletEffect, 3);//特效在3秒后destroy


        }
    }
}

在AssualtRifle脚本中,实例化子弹,并可以进行子弹速度的调整。测试发现子弹速度低于

        private void CreateBullet()
        {
    
    
            GameObject tmp_Bullet = Instantiate(BulletPrefab, MuzzlePoint.position, MuzzlePoint.rotation);

            tmp_Bullet.transform.eulerAngles += CalculateSpreadOffset();

            var tmp_BulletScript = tmp_Bullet.AddComponent<Bullet>();
            tmp_BulletScript.ImpactPrefab = BulletImpactPrefab;
            tmp_BulletScript.ImpactAudioData = ImpactAudioData;
            tmp_BulletScript.BulletSpeed = 500;
        }

制作过程中,使用了debug打印,画线等多种方式来检测子弹的碰撞是否成功。
然后实现一下子弹射中物体的声音。
创建ImpactAudioData脚本,和枪械的射击声音一样,也是继承ScriptableObject。Tag AudioClip下面有若干个声音。

using System.Collections.Generic;
using UnityEngine;

namespace Scripts.Weapon
{
    
    
    [CreateAssetMenu(menuName = "FPS/Impact Audio Data")]
    public class ImpactAudioData : ScriptableObject
    {
    
    
        public List<ImpactTagsWithAudio> ImpactTagsWithAudios;
    }

    [System.Serializable]
    public class ImpactTagsWithAudio
    {
    
    
        public string Tag;
        public List<AudioClip> ImpactAudioClips;
    }
}

回到unity中,类似于枪械开火声音的设置,也是创建一下Audio,然后将音频拖拽到相应的位置,并且设置好相应的tag。
在Bullet脚本中编写弹孔声音的相关逻辑。在碰撞到对应的tag后,返回tag里面的元素,注意对tag进行判断。

//For Audio
            var tmp_TagsWithAudio =
                ImpactAudioData.ImpactTagsWithAudios.Find((_audioData) => _audioData.Tag.Equals(tmp_Hit.collider.tag));
            if (tmp_TagsWithAudio == null) return;
            int tmp_Length = tmp_TagsWithAudio.ImpactAudioClips.Count;
            AudioClip tmp_AudioClip = tmp_TagsWithAudio.ImpactAudioClips[Random.Range(0, tmp_Length)];
            AudioSource.PlayClipAtPoint(tmp_AudioClip, tmp_Hit.point);//直接用的这个类,不需要使用它的组件。

然后回到AssualtRifle脚本,去添加一下audio的赋值。

tmp_BulletScript.ImpactAudioData = ImpactAudioData;

三、子弹散射

打开枪的父类Firearms
子弹的散射根据相机的fov,因为需要进行瞄准的相关实现。

protected Vector3 CalculateSpreadOffset()
        {
    
    
            float tmp_SpreadPercent = SpreadAngle / EyeCamera.fieldOfView;

            return tmp_SpreadPercent * UnityEngine.Random.insideUnitCircle;
        }

float tmp_SpreadPercent = SpreadAngle / EyeCamera.fieldOfView;算出散射的百分比。
在上面声明散射角度变量。

public float SpreadAngle;

然后在CreateBullet中获取到子弹的transform和欧拉角。

private void CreateBullet()
        {
    
    
            GameObject tmp_Bullet = Instantiate(BulletPrefab, MuzzlePoint.position, MuzzlePoint.rotation);

            tmp_Bullet.transform.eulerAngles += CalculateSpreadOffset();

            var tmp_BulletScript = tmp_Bullet.AddComponent<Bullet>();
            tmp_BulletScript.ImpactPrefab = BulletImpactPrefab;
            tmp_BulletScript.ImpactAudioData = ImpactAudioData;
            tmp_BulletScript.BulletSpeed = 500;
        }

那么散射就完成了,射中物体的弹孔将会根据散射的角度进行一定程度的随机偏移。

猜你喜欢

转载自blog.csdn.net/Fancy145/article/details/125055918
今日推荐