【Unity实战】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(二)(附源码)

news/2024/10/17 16:26:30/

文章目录

  • 前言
  • 一、火箭筒
    • 1. 编写火箭筒脚本
    • 2. 创建火箭弹和新爆炸特效的预制体
    • 3. 编写火箭弹脚本
    • 4. 设置好火箭弹和火箭筒的脚本和参数
    • 5. 运行效果
  • 二、激光枪
    • 1. 编写激光枪脚本
    • 2. 先运行游戏,看看效果
    • 3. 美化射线
    • 4. 完善代码
    • 5. 再次运行游戏
    • 6. 升级URP项目
    • 7. 后处理
    • 8. 新建Shader Graph
    • 9. 新建材质
    • 10. 运行效果
  • 三、机枪
    • 1. 配置LineRenderer子弹
    • 2. 编写脚本
    • 3. 编写步枪脚本
    • 4. 运行效果
  • 源码
  • 参考
  • 完结

前言

本文紧接上篇文章:制作俯视角射击游戏多种射击效果(一)
没看过上期的建议先去看看,这篇文章我们将继续实现曲线射击与两种不需要实体子弹的射击方式
在这里插入图片描述请添加图片描述

请添加图片描述

源码在文章末尾

一、火箭筒

除了常规的设置直线速度发射子弹,我们也可以通过不断改变移动方向达到曲线射击的效果

1. 编写火箭筒脚本

为火箭筒新建一个脚本RocketLauncher并进入
首先同样也需要继承父类Gun,和散弹枪的思路类似,火箭筒也可以一次发射出多个火箭弹

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;// 火箭发射器类
public class RocketLauncher : Gun
{// 火箭数量public int rocketNum = 3;// 火箭发射角度public float rocketAngle = 15;// 重写父类的开火方法protected override void Fire(){// 播放射击动画animator.SetTrigger("Shoot");// 延迟开火StartCoroutine(DelayFire(.2f));}// 延迟开火协程IEnumerator DelayFire(float delay){yield return new WaitForSeconds(delay);// 计算中间位置int median = rocketNum / 2;// 循环发射火箭for (int i = 0; i < rocketNum; i++){// 从对象池中获取火箭GameObject bullet = ObjectPool.Instance.GetObject(bulletPrefab);// 设置火箭位置bullet.transform.position = muzzlePos.position;// 根据火箭数量的奇偶性设置火箭发射角度if (rocketNum % 2 == 1){bullet.transform.right = Quaternion.AngleAxis(rocketAngle * (i - median), Vector3.forward) * direction;}else{bullet.transform.right = Quaternion.AngleAxis(rocketAngle * (i - median) + rocketAngle / 2, Vector3.forward) * direction;}// 设置火箭目标bullet.GetComponent<Rocket>().SetTarget(mousePos);}}
}

2. 创建火箭弹和新爆炸特效的预制体

因为和普通子弹基本一致,只是添加了一个烟雾的粒子系统作为子物体,爆炸特效也是一样
所以我提前准备好了预制体就不再演示了
在这里插入图片描述

3. 编写火箭弹脚本

但脚本逻辑和子弹还是有很大不同的,所以给火箭弹新建脚本Rocket

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Rocket : MonoBehaviour
{public float lerp; // 插值系数public float speed = 15; // 移动速度public GameObject explosionPrefab; // 爆炸特效预制体new private Rigidbody2D rigidbody; // 刚体组件private Vector3 targetPos; // 目标位置private Vector3 direction; // 移动方向private bool arrived; // 是否到达目标点private void Awake(){rigidbody = GetComponent<Rigidbody2D>(); // 获取刚体组件}public void SetTarget(Vector2 _target) // 设置目标点{arrived = false; // 重置到达标志位targetPos = _target; // 设置目标点}private void FixedUpdate(){direction = (targetPos - transform.position).normalized; // 计算移动方向if (!arrived) // 如果还没到达目标点{transform.right = Vector3.Slerp(transform.right, direction, lerp / Vector2.Distance(transform.position, targetPos)); // 插值旋转rigidbody.velocity = transform.right * speed; // 设置速度}if (Vector2.Distance(transform.position, targetPos) < 1f && !arrived) // 如果到达目标点{arrived = true; // 设置到达标志位}}private void OnTriggerEnter2D(Collider2D other) // 碰撞检测{GameObject exp = ObjectPool.Instance.GetObject(explosionPrefab); // 从对象池中获取爆炸特效exp.transform.position = transform.position; // 设置特效位置rigidbody.velocity = Vector2.zero; // 停止移动StartCoroutine(Push(gameObject, .3f)); // 延迟回收}IEnumerator Push(GameObject _object, float time) // 延迟回收协程{yield return new WaitForSeconds(time); // 等待一段时间ObjectPool.Instance.PushObject(_object); // 回收对象}
}

4. 设置好火箭弹和火箭筒的脚本和参数

在这里插入图片描述
在这里插入图片描述

5. 运行效果

可以看到火箭筒的攻击已经达到我们预期的效果
在这里插入图片描述

二、激光枪

接下来介绍两种特殊的射击方式
一般的枪械都是通过生成子弹并让子弹移动实现发射的功能
发射出的子弹有一个移动的过程,并且检测击中也是由子弹单独完成
不过有一些特殊的枪械还使用实体子弹,这种枪械”发射”的是一种瞬间到达的子弹
在unity中称为“射线”,激光就是一种典型的射线
接下来我们就从激光枪入手,通过射线检测实现这种特殊的射击方式

1. 编写激光枪脚本

为激光枪创建脚本Lasergun,同样继承枪械父类Gun

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lasergun : Gun
{private bool isShooting;// 重写父类的Shoot方法protected override void Shoot(){// 计算枪口朝向direction = (mousePos - new Vector2(transform.position.x, transform.position.y)).normalized;transform.right = direction;// 检测是否按下射击键if (Input.GetButtonDown("Fire1")){isShooting = true;}// 检测是否松开射击键if (Input.GetButtonUp("Fire1")){isShooting = false;}// 设置Shoot动画状态animator.SetBool("Shoot", isShooting);// 如果正在射击,则发射子弹if (isShooting){Fire();}}// 发射子弹protected override void Fire(){// 检测射线碰撞RaycastHit2D hit2D = Physics2D.Raycast(muzzlePos.position, direction, 30);// 绘制射线Debug.DrawLine(muzzlePos.position, hit2D.point);}
}

2. 先运行游戏,看看效果

回到Unityi运行游戏,按住鼠标左键,可以看到一条射线从枪口向鼠标方向射出了
在这里插入图片描述

3. 美化射线

但使用Debug绘制的线条太过简陋,也只能在开发时看到
所以接下来使用其他方法绘制更加美观的射线
我们需要像DrawLine方法一样设置起始和结束位置,LineRenderer就是一个不错的选择
找到激光枪的枪口子物体,添加上LineRenderer组件
LineRenderer将根据可用点的位置绘制多段线条,我们只需要一条直线,所以将size设为2
在这里插入图片描述
将图层顺序调高防止被地面层遮挡,然后更改一下可用点的位置
可以看到场景中已经出现了一段线条,适当调整宽度让线条适配激光枪的宽度
在这里插入图片描述
可以看到场景中已经出现了一段线条,适当调整宽度让线条适配激光枪的宽度
在这里插入图片描述
修改线段的颜色让其符合激光枪的配色,我这里就设置为红色
LineRender的颜色设置窗口和正常的略有不同,可以分别修改两个边界的颜色和透明度
中间的值会自动进行渐变,因为需要纯红色所以两端都设置为红色,也不需要修改透明度
你也可以根据自己的想法设置出更绚丽的颜色
在这里插入图片描述
接着增加末端顶点的值让线段的两端更加圆滑,这样一条用作显示激光的线段就完成了

在这里插入图片描述
我们希望只有在开枪时才显示线段,所以先将LineRenderer取消激活
在这里插入图片描述

4. 完善代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lasergun : Gun
{private GameObject effect; // 特效private LineRenderer laser; // 激光线private bool isShooting; // 是否正在射击protected override void Start(){base.Start();laser = muzzlePos.GetComponent<LineRenderer>(); // 获取激光线组件effect = transform.Find("Effect").gameObject; // 获取特效物体}protected override void Shoot(){direction = (mousePos - new Vector2(transform.position.x, transform.position.y)).normalized; // 获取射击方向transform.right = direction; // 转向射击方向if (Input.GetButtonDown("Fire1")) // 按下射击键{isShooting = true; // 正在射击laser.enabled = true; // 显示激光线effect.SetActive(true); // 显示特效}if (Input.GetButtonUp("Fire1")) // 松开射击键{isShooting = false; // 停止射击laser.enabled = false; // 隐藏激光线effect.SetActive(false); // 隐藏特效}animator.SetBool("Shoot", isShooting); // 设置射击动画if (isShooting) // 正在射击{Fire(); // 发射子弹}}protected override void Fire(){RaycastHit2D hit2D = Physics2D.Raycast(muzzlePos.position, direction, 30); // 发射射线// Debug.DrawLine(muzzlePos.position, hit2D.point);laser.SetPosition(0, muzzlePos.position); // 设置激光线起点laser.SetPosition(1, hit2D.point); // 设置激光线终点effect.transform.position = hit2D.point; // 设置特效位置effect.transform.forward = -direction; // 设置特效方向}
}

5. 再次运行游戏

回到Unity再次运行游戏,按住鼠标左键,现在就可以看到一条更美观的射线了
在这里插入图片描述
不过就算这样这也只是一条线接下来需要让这条线更像激光
我们将使用后处理Post-Processing实现这一效果,你可以将后处理理解为一种滤镜
为了使用后处理,我们需要让项目升级为URP通用渲染管线项目
你可以在创建项目时就选择URP模板创建,不过这里使用第二种方法升级

6. 升级URP项目

我们可以到Windows->Package Manager中搜索universal-导入URP的包
在这里插入图片描述
导入包后还需要一些步聚让项自使用URP
右键Creat-.>Rendering创建一个URP的Asset
在这里插入图片描述

Unity创建出了两个文件,我们选择名字不带render的文件并勾选HDR选项
在这里插入图片描述
然后在Project Setting->Graphics的pipeline setting选项中设置刚创建的URP Asset
在这里插入图片描述
最后勾选相机下的poost processingi选项就设置完成了
在这里插入图片描述

7. 后处理

接下来就可以在层次视图下右键创建一个volume,选择global volume全局生效
在这里插入图片描述
可以看到场景中生成了一个名为Global Volume的物体
将由这个物体下的volumel脚本给相机添加后处理特效
在这里插入图片描述

首先在Profile属性下点击新建创建一个新的volume配置文件
创建完成后下方将出现Add Override的按钮,点击按钮创建一个新特效
选择Bloomi泛光效果,Bloom会产生一个明亮的光晕效果,非常适合用在激光上
目前只需要勾选前两个选项,Threshold属性将设定Bloom产生效果的阈值
Intensity属性则将影响Bloom产生的泛光效果的强度
试着将阈值调低,可以看到整个场景稍微亮了一些
在这里插入图片描述

8. 新建Shader Graph

但我们需要更精确的调整某个物体的泛光值,这时就需要使用HDR了
HDR可以在设置颜色的同时设置强度,这个强度可用在BIoom的阈值上
也就是说,只要将Bloom的阈值提高到1以上
只有我们设置过强度的HDR颜色,Bloom才会进行渲染
要实现这个功能,我们需要自己创建一个Shader来创建材质
使用URP中的Shader Graph可以很方便的创建Shader
右键Creat->Shader Graph创建一个Shader Graph
在这里插入图片描述
重命名为ColorGraph并双击打开
这个Shader需要显示一个HDR的颜色,所以在左侧的黑板创建一个颜色属性
点击加号创建一个Color属性并选择模式为HDR,你可以将属性理解为脚本中的公有变量
在这里插入图片描述

要让渲染的物体显现出来还需要一个纹理,所以需要再创建一个Texture属性
在这里插入图片描述
你可以注意到主区域已经存在一个节点master
我们需要将对应数值输出到这个节点来显示相应的效果
首先右键创健一个simple texture2d节点来将纹理转换为颜色输出
将刚创建的纹理属性拖拽到主区域中并连接到节点作为输入
然后创建一个add节点并让colorj属性和节点输出的颜色相加达到改变颜色的效果
将这个改变后的颜色连接到master节点的color.上,这样就可以通过color属性改变颜色了
不要忘记点击左上角的Save Asset保存后再退出Shader Graph
在这里插入图片描述

9. 新建材质

右键ColorGraphi根据这个shadert创建一个材质起名为BrightMaterial
首先创建一个正方形的sprite传给texture,然后将颜色的强度提高到1以上
在这里插入图片描述
将这个材质设置给显示激光的线段渲染器
在这里插入图片描述

10. 运行效果

运行游戏,可以看到线段有一种明亮的感觉,看起来更像激光了
在这里插入图片描述
也可以在激光末端添加一个粒子特效产生一个击中目标的感觉提升观感
在这里插入图片描述

三、机枪

除了激光还有一种射击方式不需要实体子弹
这种发射方式同样使用射线检测,通过模拟子弹的发射轨迹来实现效果
这种方式和实体子弹一样,每次发射会生成一个物体作为弹道轨迹
所以我们需要先创建弹道的预制体,这里同样使用LineRenderer模拟

1. 配置LineRenderer子弹

在场景中创建一个空物体起名为BulletTracer并添加线段渲染器
同样设置端点数为2、末端顶点为90并提高图层顺序避免被遮挡
调整线段的宽度到合适的感觉,也可以在线段的末端右键添加key来过渡线段的宽度
我这里为了美观略微增加了线段的末端宽度
在这里插入图片描述
然后调整颜色,点击下方的箭头将轨迹的颜色设置为纯灰色
接着点击上方的箭头设置透明度,让透明度随着距离从0逐渐增加
在这里插入图片描述

2. 编写脚本

然后编写脚本BulletTracer并添加给这个物体
这个脚本的功能和弹壳类似,让轨迹生成后逐渐淡出,完全透明后销毁物体

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class BulletTracer : MonoBehaviour
{public float fadeSpeed; // 渐隐速度private LineRenderer line; // 线渲染器private float alpha; // 透明度private void Awake(){line = GetComponent<LineRenderer>(); // 获取线渲染器组件alpha = line.endColor.a; // 获取线渲染器的结束颜色的透明度}private void OnEnable(){line.endColor = new Color(line.endColor.r, line.endColor.g, line.endColor.b, alpha); // 设置线渲染器的结束颜色的透明度StartCoroutine(Fade()); // 开始渐隐协程}IEnumerator Fade(){while (line.endColor.a > 0) // 当线渲染器的结束颜色的透明度大于0时{line.endColor = new Color(line.endColor.r, line.endColor.g, line.endColor.b, line.endColor.a - fadeSpeed); // 透明度减少yield return new WaitForFixedUpdate(); // 等待下一帧}ObjectPool.Instance.PushObject(gameObject); // 回收对象}
}

回到Unity,将BulletTracer物体拖拽到资源窗口中制作成预制体就制作完成了

3. 编写步枪脚本

然后编写步枪脚本Rifle并添加给步枪子物体
这个枪械的功能与基础枪械基本一致,只是要将生成的子弹替换为弹道预制体
这个步骤只涉及发射部分,所以重写Fire函数即可

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Rifle : Gun
{// 重写父类的Fire方法protected override void Fire(){// 播放射击动画animator.SetTrigger("Shoot");// 发射射线检测碰撞RaycastHit2D hit2D = Physics2D.Raycast(muzzlePos.position, direction, 30);// 获取对象池中的子弹并设置轨迹GameObject bullet = ObjectPool.Instance.GetObject(bulletPrefab);LineRenderer tracer = bullet.GetComponent<LineRenderer>();tracer.SetPosition(0, muzzlePos.position);tracer.SetPosition(1, hit2D.point);// 获取对象池中的弹壳并设置位置和旋转GameObject shell = ObjectPool.Instance.GetObject(shellPrefab);shell.transform.position = shellPos.position;shell.transform.rotation = shellPos.rotation;}
}

回到Unity,给Rifle脚本配置参数然后运行游戏
在这里插入图片描述

4. 运行效果

切换到步枪开始射击,现在可以看到发射的弹道轨迹效果了
在这里插入图片描述
到这里所有枪械的射击方式就介绍完了
如果你发现了文章中存在错误或者有更好的解决方法,也欢迎在评论区留言

源码

https://gitcode.net/unity1/TopDownShooter

参考

【视频】:https://www.bilibili.com/video/BV1Mh411v7PU

完结

如果你有其他更好的方法也欢迎评论分享出来,当然如果发现文章中出现了什么问题或者疑问的话,也欢迎评论私信告诉我哦

好了,我是向宇,https://xiangyu.blog.csdn.net/

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是开始自习unity。最近创建了一个新栏目【你问我答】,主要是想收集一下大家的问题,有时候一个问题可能几句话说不清楚,我就会以发布文章的形式来回答。 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~


http://www.ppmy.cn/news/746986.html

相关文章

专注情感故事短视频,三感video获千万级A+轮融资...

3月15日消息&#xff0c;情感故事短视频三感video获得千万级A轮融资&#xff0c;投资方为微博和合一资本&#xff0c;本轮融资将用于拓宽内容品类、发力红人经纪以及情感服务平台“三感情感”的服务升级。 此前&#xff0c;三感video已经获得过两轮融资&#xff1a;2016 年获得…

一下科技助力短视频行业移动视频生态发展

随着短视频行业不断火热&#xff0c;短视频成为了内容营销新阵地&#xff0c;诸如短视频旅游、短视频电商、短视频新闻等“短视频”模式迅速风靡。不少企业和个人利用短视频形式进行推广&#xff0c;依托短视频内容直击用户需求&#xff0c;寻求与用户的情感共鸣&#xff0c;从…

众盟科技:直播浪潮下,医美行业的私域营销之变

上世纪30年代&#xff0c;美国经济大萧条期间&#xff0c;口红的销量却出现大幅提升。经济学家把这一现象称为“口红效应”。一直到今天&#xff0c;“口红效应”仍然是社会经济发展的晴雨表&#xff0c;不同的是&#xff0c;“口红效应”正出现一种替代性消费符号——医疗美容…

音视频流媒体

音视频流媒体 流媒体背景音视频常见术语定义规范 音视频组成编码格式 音频编码格式视频编码格式存储封装格式 视频码率帧率分辨率 码率帧率分辨率 图像存储格式yuv 一幅彩色图像的基本要素是什么YUV与像素的关系YUV图像格式的内存大小 帧率码率与分辨率之间关系 一个视频文件的…

七大特色创业法

提起创业,人们想到最多的是开店、办公司、搞企业。随着时代发展的日新月异,创业方式正在不断发生变化,特别是IT业的崛起,令创业模式更是层出不穷:网络创业、概念创业、团队创业、兼职创业。那么,不同的创业模式有哪些不同的特色?创业者如何寻找适合自己的创业模式? 方式…

06-添加视频效果

06-添加视频效果 一、视频效果的管理二、添加视频效果三、禁止视频效果四、删除视频效果五、设置视频效果参数六、设置效果关键帧七、常用视频效果7.1 "变换"效果7.2 "图像控制"效果7.3 "扭曲"效果7.4 "模糊与锐化"效果7.5 "生成…

康瞳新零售护眼产品新系统 零售商城

康瞳新零售护眼产品新系统 零售商城&#xff0c;甄视康护眼膏全新升级为【康瞳】#康瞳 今天不管您进不进入护眼行业&#xff0c;三五年之后&#xff0c;您肯定都会在用护眼产品参与了&#xff0c;您就是管道的受益者&#xff0c;没参与您就是普通的消费者。 历史前进的车轮不…