FPS游戏开发(3)

闲杂:

想玩游戏的时候就来写博客,其实我个人的感觉写博客就跟写书是一样的吗,写书是将内心的故事呈现给读者,而写博客就是将技术呈现给读者,一方面我们可以将自己的技术分享出来供大家学习,第二个是希望大家可以给我的技术做一些指点,互相学习互相交流,希望能在评论区多多留言,我也可以解决疑难杂症。

故事开始:

在FPS的游戏开发当中设计到枪械的方面,手雷的方面,近战武器,以及一些特殊的道具,所以这些模块值得去深挖和细品,古人云:彩虹风雨后,成功细节中(我也不知道是哪个古人说的)

我的思路,搭建场景,然后给box添加上Rigibody组件(不要给地面也添加该组件,会出现很奇怪的情况,如果想试一试的小伙伴,可以玩一下)
在这里插入图片描述
接下来就是Granade,吐槽一下,我的第一版手雷和上面的箱子一样大,由于太过搞笑所以我就弄了手雷2.0,看起来就舒服多了
在这里插入图片描述
接下来就是脚本方面了,我的思路是这样的,首先是Granade.cs的脚本

  • 手雷延时爆炸delay
  • 手雷的爆炸半径
  • 手雷的爆炸力度

这三方面考虑好后就可以开始写脚本了,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Granade : MonoBehaviour
{

    public float delay = 3f;
    public float radius = 5f;
    public float force = 700f;

    public GameObject ExplosionEffect;
    public GameObject ExplosionAudio;


    float countDown;

    bool hasExploaded = false;


    void Start()
    {

        countDown = delay;
    }

   
    void Update()
    {
        countDown -= Time.deltaTime;

        if (countDown <=  0f && !hasExploaded)
        {
            Explode();
            hasExploaded = true;
        }
    }

    void Explode()
    {
        Instantiate(ExplosionEffect, transform.position, transform.rotation);
        Instantiate(ExplosionAudio, transform.position, transform.rotation);


        //add force to move
        //该半径内的所有碰撞器,返回一个数组
        Collider[] collidersToMove = Physics.OverlapSphere(transform.position,radius);

        //遍历球体内的所有Collider
        foreach (Collider nearbyObject in collidersToMove)
        {
            //获取球体半径范围内的rigibody
            Rigidbody rb = nearbyObject.GetComponent<Rigidbody>();

            if (rb != null)
            {
                //向模拟爆炸效果的刚体施加力
                rb.AddExplosionForce(force,transform.position, radius);
            }
        }

        Destroy(gameObject);

    }

    //Granade Demage
}

代码分析:
我在此脚本中用了一个特殊的方法,我们知道,当物体被销毁的时候,身上的脚本以及组件都被销毁了,所以不能够将声音和爆炸的特效挂载到手雷上面,而是应该单独做成两个预制体,接下来在手雷爆炸的时候将这两个预制体加载出来,这样就解决了这个办法。
Instantiate(ExplosionEffect, transform.position, transform.rotation);
Instantiate(ExplosionAudio, transform.position, transform.rotation);

然后给Granade添加爆炸力和爆炸范围
Collider[] collidersToMove = Physics.OverlapSphere(transform.position,radius);
在这里插入图片描述
在官方文档中,讲到了参数和使用方法。我解释一下返回Collider数组的作用,这里是将球形范围内的所有包含Collder组件的物体都存起来,接下来遍历球体内物体上的Rigibody组件,然后可以给含有该组件的物体添加爆炸力度,爆炸力是手雷来提供的,这样就实现了手雷爆炸击飞箱子。
rb.AddExplosionForce(force,transform.position, radius);
在这里插入图片描述Granade的部分就完成了,接下来就是手雷爆炸特效和手雷音效销毁,回收的阶段,我遇到的问题是特效如果不销毁就会一直常驻内存,而且特效也会重复播放,所以,我就另外写了一个脚本来专门管理它,DestroyGameObject(名字起的不是很恰当,后期优化)

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyGameObject : MonoBehaviour
{

    public float effectTime = 6f;
    public GameObject BigExplosionEffect;
    public GameObject GranadeAudio;

    float currentDown;

    bool hasPerfab = true;

    void Start()
    {
        currentDown = effectTime;
    }

    
    void Update()
    {
        currentDown -= Time.deltaTime;

        if (currentDown <= 0 && hasPerfab)
        {

            if (BigExplosionEffect != null && GranadeAudio != null)
            {
                currentDown = effectTime;
                DestoryExplosinEffect();
                DestoryExlosinAudio();
                hasPerfab = true;
            }
            else
            {
                hasPerfab = false;
                
            }

        }

    }


    void DestoryExplosinEffect()
    {

        GameObject obj = GameObject.Find("BigExplosionEffect(Clone)");

        if (obj != null)
        {
            Destroy(obj);
        }

    }

    void DestoryExlosinAudio()
    {

        GameObject obj = GameObject.Find("GranadeAudio(Clone)");

        if (obj != null)
        {
            Destroy(obj);
        }  

    }
}

代码解释:

我先定义了一个计时器,由于我的特效和声音大概是3秒,加上之前的手雷延时爆炸3秒,所以是6秒之后销毁,这样写是比较简单的,分开控制,方法也是分开写的,方便后期的管理。
添加了一个控制条件hasPerfab ,控制它只销毁一次,之前想一次扔好几个手雷,但是出现了一些小问题(其实问题蛮大的),我下来解决一下,在下回书中我们在讲解。然后将其挂载到场景CheckDestory上,如图
在这里插入图片描述
最后是控制手雷的扔出,ThrowerGranade,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GranadeThrower : MonoBehaviour
{
    public float throwerForce = 15f;
    public GameObject GranadePrefab;
    private AudioSource audioSource;

    bool isFirst = true;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
    }

    void Update()
    {
        
        if (Input.GetMouseButtonDown(0))
        {
        	//播放手雷扔出的音效
            audioSource.Play();
            if (isFirst)
            {
                ThrowGranade();
                isFirst = false;
            }
        }

    }

    void ThrowGranade()
    {
        GameObject granade = Instantiate(GranadePrefab,transform.position, transform.rotation);

        Rigidbody rb = granade.GetComponent<Rigidbody>();

        rb.AddForce(transform.forward * throwerForce,ForceMode.VelocityChange);

    }
}

代码解释:
挂载到相机上,按下鼠标左键时,添加一个向前的力,这样手雷就扔出去了,我后期想加上抛物线,后面在改进,这样就可以实现真正的手雷模拟器(无情)

完整的演示图:
在这里插入图片描述

本回合完,预知后事如何,且看下回分解(有赞的观众老爷能不能点一下赞,手写了三篇)

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用的 主要技术有: 1、大面积山脉渲染,使用Heightmap构造地形,7级 LOD 细节精度,地形无限重复循环 。 2、清晰、自然的地表贴图。 3、读取.MD2 、.MS3D 格式的3D模型文件。 4、粒子系统,产生爆炸、炊烟等特效。 5、太阳光晕。 6、使用Blend模拟Brightness/contrast调节图象亮度。 操作控制 可以在GameSetting菜单中设定: 1.视频属性 ( Video Setting ) 1).屏幕分辨率( Resolution ) 游戏率默认为800*600,在任务执行前可改变分辨率,但不会立即生效,只有在初始化任务时才改变分辨率。 2).屏幕亮度( Brigthness ) 在不同的硬件配置上,屏幕亮度往往表现出较大差异,通过该项可将亮度调节到最佳。 3).视野范围 ( Visible Distance ) 调节地形绘制的距离。对于配置较低的硬件,适当降低视野距离可提高帧速率,但由于远处地形网格较粗,对帧速率提高贡献并不大。 4).雾浓度 ( Fog Density ) 2.音频属性 ( Audio Setting ) 1).背景音乐(music) 可以打开或关闭背景音乐,可以调节音量。 音乐播放 audio/music/menu.mp3 ,如果你有自己喜爱的mp3音乐文件可以将它替换 menu.mp3 文件。 2).音效( sound ) 可以打开或关闭音效,可以调节音量。游戏中的枪声与人物的发声具有3D效果。 3.键盘操作 ( Keyboard Setting ) 以下操作可以更改 Up、Down、Left、Right设定移动操作。 Fire 射击 Jump 跳跃 Zoom 放大远处景物 Help 弹出帮助 修改方法:用鼠标点击选项,然后输入新的按键。 另外,游戏保留了几个开发模式下的操作: Page Up 提升视点高度 Page Down 降低视点高度 (可以看到地形绘制区域) L 线框模式 F 冻结所有敌人 V 隐身 N 敌人攻击力为零 I 隐藏房子 O 隐藏敌人 P 隐藏树木 在游戏运行中,按 Help 项的按键获得帮助。 4.鼠标操作 鼠标的移动可改变视角,默认设定左键为射击,右键为放大。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值