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

news2024/12/23 18:51:45

文章目录

  • 前言
  • 一、火箭筒
    • 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.coloradmin.cn/o/726180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指offer13.机器人的运动范围

一开始没看清题目&#xff0c;没看到要一步一步移动&#xff0c;我以为是看所有格子中有几个格子符合条件&#xff0c;就直接遍历所有格子&#xff0c;把每个格子的i&#xff0c;j每个位数上的数相加看看是否小于k&#xff0c;是就给counts加一最后返回couts&#xff0c;我还说…

OSPF小实验

OSPF小实验 要求&#xff1a; 1、地址配置 R1&#xff1a; R2&#xff1a; R3&#xff1a; R4&#xff1a; R5&#xff1a; R6&#xff1a; 2、启用R1-R3的ospf&#xff0c;划分为区域0 R1&#xff1a; R2&#xff1a; R3&#xff1a; 3、R1-R2之间采用ppp的pap单向认证 R1为…

select + option 获取 value 来 innerHTML 插入内容或元素

目录 select optioninnerHTML 在元素中插入内容 select option 可以实现一个下拉选择&#xff0c;选择到那个&#xff0c;就可以获取其value&#xff0c;并且弹窗。 <!DOCTYPE HTML> <html><head><meta charset"utf-8"><style>.st…

【数据结构与算法】查找课后习题

题目 下面一共有4道有关查找的课后习题&#xff0c;全部都是思路题、画图题并不是完整的算法设计题故在此就一起列举出来了~ 1. 已知一个有序表的表长为8N&#xff0c;并且表中没有关键字相同的记录 假设按如下所述方法查找一个关键字等于给定值K的记录&#xff1a;先在第8,1…

Jmeter性能优化方案

最近用jmeter测试并发出现了访问端口异常问题的排查及解决方案做一个归纳&#xff1a; 背景&#xff1a;接口压测异常情况发生率达到了99% 线上情况&#xff1a; 错误情况展示&#xff1a; 原因&#xff1a; Jmeter里的http sample勾选了keep alive&#xff0c;导致会话一直…

2022年真题 - 16 - cockpit

cockpit 题目配置 题目 安装 cockpit 来检测 ispsrv 服务器的状态 配置 安装 cockpit [rootStorageSrv ~]# yum -y install cockpit启动服务 [rootStorageSrv ~]# systemctl enable --now cockpit.socketInsideCli 浏览器访问 http://192.168.100.200:9090

【数据结构与算法】假设图采用邻接表存储,判断一个未知顶点个数和边数的无向连通图G是否是棵树

题目 Qestion: 设计一个算法,判断一个未知顶点个数和边数的无向连通图G是否是棵树,假设图采用邻接表存储。若是树,返回true;否则返回 false。 (用图1和图2验证作业题2算法的正确性) 图一图二的邻接表结构 运行结果以及其解释 由结果可知图一为无向连通图&#xff0c;图二不为…

基于Arcgis 一带一路地图制作 沿途主要城市 路线

数据准备&#xff1a; 全球范围的DEM地形数据 海上丝绸之路节点城市shp陆上丝绸之路节点城市shp全球行政区域shp 全球的shp和主要城市 数据&#xff1a;下载 海上丝绸之路节点城市和陆上丝绸之路节点城市shp&#xff1a;下载 一带一路沿途经济走廊shp&#xff1a;下载 数据…

【Linux】Linux基础命令-cp、ls、mv、chmod、rm、mkdir、cd、find、pwd

1.添加用户 &#xff08;1&#xff09;切换到管理员 sudo su &#xff08;2&#xff09;添加用户 addusr zhangdi &#xff08;3&#xff09;设置密码 &#xff08;4&#xff09;切换到自己的账号 su zhangdi 2.mkdir、cd命令&#xff0c;要求能建立目录、进入与退出目录 &a…

Linux下打包发布QT程序,并运行在其他没有安装QT环境的linux系统上

一、Linux下打包发布步骤如下 编译应用程序环境&#xff1a;ubuntu18.04版本开发环境&#xff1a;Qt5.14.2编译环境&#xff1a;gcc_64要移植的电脑&#xff1a;ubuntu18.04版本&#xff0c;没有开发环境 第一步&#xff1a;打包依赖库 1、创建一个打包目录&#xff0c;把生…

JavaScript Day11 DOM事件机制

事件机制 HTML DOM 允许 JavaScript 对 HTML 事件作出反应。JavaScript 能够在事件发生时执行&#xff0c;比如当用户点击某个 HTML 元素时。 为了在用户点击元素时执行代码&#xff0c;请向 HTML 事件属性添加 JavaScript 代码&#xff1a; <div iddiv1>我是一个div&…

如何在Microsoft Excel中进行不连续区域批量填充

快速填充是 Excel 最令人惊叹的功能之一,它因让一个需要数小时手动执行的乏味任务瞬间自动执行而得名,然而它也有局限性: 结果不是动态的。当你更改其所基于的值时,快速填充值不会更新。你需要再次执行快速填充才能更新值。 快速填充可能并不总是返回结果。该模式对于 Exce…

从零开始理解Linux中断架构(17)--设备中断处理函数

现在达到了最后一步,给中断源安装上设备层级的中断处理函数,这个是每个具体设备驱动需要做的核心工作,每个device probe 时,驱动程序会初始本设备的寄存器和使用request_threaded_irq@manage.c 注册设备自己相关的中断处理函数。 设备中断处理函数的运行位置如下图的红色箭…

如何用wireshark查看snmpv3报文

编辑->首选项 Protocols 选择SNMP协议&#xff0c;点击编辑 填写账号 加密方式 密码 加密方式 密码 加密的数据可以看见了

RabbitMQ系列(12)--Fanout交换机的简介与实现

1、Fanout交换机的介绍 接收所有的消息广播到它知道的队列中&#xff0c;类似于发布订阅模式&#xff0c;只要Fanout禁用RoutingKey,绑定同一交换机的队列都可同时收到消息&#xff1b;若Fanout启动了routingkey&#xff0c;则绑定同一交换机且routingkeyKey相同的队列才能收到…

Flutter生命周期小结

Flutter 中的生命周期&#xff0c;包含以下几个阶段&#xff1a; createState &#xff0c;在 StatefulWidget 中创建 State 的方法&#xff0c;当 StatefulWidget 调用时会触发 createState 。initState &#xff0c;在 State 初始化时调用&#xff0c;因此可以在此期间执行 …

TortoiseGit 如何回退到以前的版本?

要在 TortoiseGit 中回退到以前的版本&#xff0c;可以按照以下步骤进行操作&#xff1a; 在资源管理器中&#xff0c;右键单击你的 Git 仓库文件夹&#xff0c;然后选择 "TortoiseGit"&#xff0c;再选择 "Show log"。这将打开 TortoiseGit 的日志界面。…

前端开发需要了解的工具集合

前端开发需要了解的一些工具&#xff0c;这些工具能够帮助你在项目开发中事半功倍。 1. nrm: npm registry 管理器 registry: npm 远程仓库的地址。 由于众所周知的原因&#xff0c;npm 官方仓库在国内特别的慢&#xff0c;所以我们需要用一些替代性方案&#xff0c;一种方案…

vue指令简介

什么是指令&#xff1f; 这些是特殊的说明&#xff0c;它们会在附加到 HTML 元素时更改其行为。 换句话说&#xff0c;这些是附加到 HTML 元素的特殊属性&#xff0c;这些属性可以更改行为并基于 DOM 的表达式值提供对 DOM 的控制。 所有 Vue 指令均以v-为前缀。 该前缀用于以…

一文读懂FPC(15)- FPC的挠曲性

FPC系列文章目录 1.什么是FPC 2.什么是R-FPC 3&#xff0c;FPC的基材 4.FPC基材压延铜和电解铜的区别 5&#xff0c;FPC的辅材 6&#xff0c;FPC常见的四种类型 7&#xff0c;FPC的生产流程简介 8&#xff0c;R-FPC的生产流程简介 9&#xff0c;FPC的发展及应用 10&a…