Unity太空避障Demo总结
太空避障:主要是实现飞机躲避子弹
面板基类、音乐类、排行榜类、json等等都和上一篇Unity坦克迷宫Demo总结一样,太空避障主要是对四元数的练习和使用
1.选择飞机面板
(1)通过左右按钮对显示的模型进行切换
(2)通过点击鼠标左键可以实现对飞机的拖动 观察飞机的整体
知识点
(1)四元数 * 四元数:会得到一个新的四元数,大多数用于旋转量相乘,相当于旋转(这个旋转的坐标是物体自身的坐标系)
(2)四元数 * 向量:会得到一个新的向量,对一个向量进行一定旋转,相当于旋转向量
public class SelectPanel : BasePanel<SelectPanel>
{public Button btnRight;public Button btnLeft;public Button btnStart;public Button btnClose;//标识当前已经创建的飞机 当切换时要删除该飞机private GameObject nowAirObj;//飞机的父物体位置public Transform airPos;//飞机的属性列表 通过隐藏和显示GameObject实现public GameObject[] hpList;public GameObject[] speedList;public GameObject[] voluemeList;public override void Init(){//在GameDataManager中保存了当前选中的飞机id 默认从0开始 点右按钮++ 左按钮-- 还有对边界的判断btnRight.onClick.AddListener(() =>{++GameDataManager.Instance.nowSelectAir;if(GameDataManager.Instance.nowSelectAir > GameDataManager.Instance.airData.Count - 1)GameDataManager.Instance.nowSelectAir = 0;ChangAir();});btnLeft.onClick.AddListener(() =>{--GameDataManager.Instance.nowSelectAir;if (GameDataManager.Instance.nowSelectAir < 0)GameDataManager.Instance.nowSelectAir = GameDataManager.Instance.airData.Count - 1;ChangAir();});btnStart.onClick.AddListener(() =>{SceneManager.LoadScene("GameScene");});btnClose.onClick.AddListener(() =>{BeginPanel.Instance.ShowPanel();HidePanel();});HidePanel();}//重写了隐藏和显示方法 这样就可以同时实现一些逻辑public override void ShowPanel(){base.ShowPanel();GameDataManager.Instance.nowSelectAir = 0;ChangAir();}public override void HidePanel(){base.HidePanel();DestroyObj();}public void ChangAir(){//删除上个飞机 创建新飞机 并记录DestroyObj();AirData airData = GameDataManager.Instance.airData[GameDataManager.Instance.nowSelectAir];nowAirObj = Instantiate(Resources.Load<GameObject>(airData.res));nowAirObj.transform.SetParent(airPos.transform, false);for(int i = 0; i < hpList.Length;i++){hpList[i].SetActive(i < airData.hp);speedList[i].SetActive(i < airData.speed);voluemeList[i].SetActive(i < airData.volume);}}public void DestroyObj(){if(nowAirObj != null){Destroy(nowAirObj);}}private float time;//点中可以进行拖动public bool isSelect;private void Update(){//让飞机上下缓缓飞(展示作用)通过sin函数 乘内测的数代表飞的频率 乘外侧的数代表飞的位移//基于世界坐标 飞机的展示面会倾斜 基于自己坐标是错的time += Time.deltaTime;this.airPos.Translate(Vector3.up * Mathf.Sin(time) * 0.001f,Space.World);//鼠标左键实现拖动 通过射线检测 将飞机的旋转角度以y旋转 度数为Mouse X * 10度if(Input.GetMouseButtonDown(0)){if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), 1000, 1 << LayerMask.NameToLayer("Air"))){isSelect = true;}}if(Input.GetMouseButtonUp(0)){isSelect = false;}if(isSelect && Input.GetMouseButton(0)){airPos.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 10,Vector3.up);}}
}
2.玩家类(飞机超出屏幕问题未解决)
(1)当飞机左右移动时,需要有一定的倾斜,停止时恢复
(2)玩家类需要受伤 死亡 移动方法
知识点
(1)射线检测时销毁碰撞体(子弹)
public class PlayerObj : MonoBehaviour
{//写成一个单例类private static PlayerObj instance;public static PlayerObj Instance => instance;//maxHp代表最大血量 nowHp代表变量public int nowHp;public int maxHp;public int moveSpeed;public int rotaSpeed;//是否死亡public bool isDead;//目标四元数旋转角度Quaternion targetQ;private float hValue;private float vValue;//世界坐标的点 没有去屏幕外的点private Vector3 frontPos = new Vector3(-41,0,23);private Vector3 frontPos2 = new Vector3(41, 0, -23);//世界坐标转换为屏幕坐标的点private Vector3 nowPos;private void Awake(){instance = this;}void Update(){if (isDead)return;//GetAxisRaw 不是渐变 -1 1两个数//adhValue = Input.GetAxisRaw("Horizontal");//wsvValue = Input.GetAxisRaw("Vertical");//为0时说明静止if (hValue == 0)targetQ = Quaternion.identity;else//不为0时 按左键值会小于0 右键值会大于0 决定一下旋转的方向//可以得到一个目标的四元数targetQ = hValue < 0 ? Quaternion.AngleAxis(20, Vector3.forward) : Quaternion.AngleAxis(-20, Vector3.forward);//趋近于目标四元数this.transform.rotation = Quaternion.Slerp(this.transform.rotation, targetQ,Time.deltaTime * rotaSpeed);//正常移动this.transform.Translate(Vector3.forward * vValue * Time.deltaTime * moveSpeed);//左右移动不能使用自身坐标系 越动越会往下掉 要使用世界this.transform.Translate(Vector3.right * hValue * Time.deltaTime * moveSpeed,Space.World);//当前坐标的屏幕坐标点this.nowPos = Camera.main.WorldToScreenPoint(this.transform.position);//******************临时判断屏幕边缘的逻辑 当分辨率变化时会出错 暂未解决******************if (nowPos.x <= 0){//只管理x 不管理yzthis.transform.position = new Vector3(frontPos.x, this.transform.position.y, this.transform.position.z);}if (nowPos.y <= 0){this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, frontPos2.z);}if(nowPos.x >= Screen.width){this.transform.position = new Vector3(frontPos2.x, this.transform.position.y, this.transform.position.z);}if (nowPos.y >= Screen.height){this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, frontPos.z);}//获取碰到的对象的信息RaycastHit hit;if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000, 1 << LayerMask.NameToLayer("Bullet"))){//通过hit可以得到他身上所有的信息BulletObj bullet = hit.transform.GetComponent<BulletObj>();bullet.Dead();}}public void Wound(){this.nowHp -= 1;Debug.Log("当前血量" + nowHp);GamePanel.Instance.ChangHp(nowHp);if(nowHp <= 0){nowHp = 0;Dead();}}public void Dead(){isDead = true;EndPanel.Instance.ShowPanel();}
}
3.子弹类
(1)子弹的初始化数据 移动方式 生命周期 销毁以及碰撞检测
public class BulletObj : MonoBehaviour
{private BulletData data;private float time;/// <summary>/// 一个初始化方法 创建子弹时调用 传入目标数据/// </summary>/// <param name="id"></param>public void Init(int id){data = GameDataManager.Instance.bulletDatas[id - 1];//生命周期 到一定时间自动销毁子弹Invoke("DelayDestroy", data.destroyTime);}//startPos代表起始位置 下面做四元数匀速运动用的private void Awake(){startPos = this.transform;}//销毁子弹 创建特效public void Dead(){GameObject effObj = Instantiate(Resources.Load<GameObject>(data.effRes));effObj.transform.position = this.transform.position;Destroy(effObj,0.5f);Destroy(this.gameObject);}//碰撞检测public void OnTriggerEnter(Collider other){if(other.CompareTag("Player")){if(!PlayerObj.Instance.isDead){PlayerObj obj = other.GetComponent<PlayerObj>();obj.Wound();Dead();}else{this.Dead();}}}//不确定子弹会不会提前被移除掉 所以使用延迟函数 当子弹已经被移除的时候 就不会执行了public void DelayDestroy(){GameObject effObj = Instantiate(Resources.Load<GameObject>(data.effRes));effObj.transform.position = this.transform.position;Destroy(effObj, 0.5f);Destroy(this.gameObject);}//时间标识 做匀速运动用private float uniform;private Transform startPos;// Update is called once per framevoid Update(){//共同的特征 面朝向移动this.transform.Translate(Vector3.forward * data.forwardSpeed * Time.deltaTime);//1 直线运动//2 曲线运动//3 左抛物线//4 右抛物线//5 跟踪switch (data.type){case 2://sin里面的值 决定 左右变化的频率//sin后面的值 决定 左右位移的多少time += Time.deltaTime;this.transform.Translate(Vector3.right * Mathf.Sin(time * data.rightSpeed) * data.rotaSpeed * Time.deltaTime);break;case 3:this.transform.rotation *= Quaternion.AngleAxis(-data.rotaSpeed * Time.deltaTime,Vector3.up);break;case 4:this.transform.rotation *= Quaternion.AngleAxis(data.rotaSpeed * Time.deltaTime, Vector3.up);break;case 5://先快后慢 出现问题 "子弹无线接近目标旋转位置过远" 那要看一下是不是子弹的位置没有归0//这里使用匀速uniform += Time.deltaTime;Quaternion q = Quaternion.LookRotation(PlayerObj.Instance.transform.position - this.transform.position);this.transform.rotation = Quaternion.Slerp(this.startPos.rotation,q, uniform * data.rotaSpeed);break;}}
}
4.炮口点
(1)炮口的位置为上方三点 中间左右两点 下方三点
(2)炮口的初始角度(为了方便开火点四元数的计算)
(3)上下左右四个点的旋转角度是180度,四个角旋转角度都是90度,这样子弹才能合理地发射在屏幕内
public enum Type_PointType
{topLeft,topRight,topCenter,Left,Right,bottomLeft,bottomRight,bottomCenter
}
public class PointObj : MonoBehaviour
{public Type_PointType type = new Type_PointType();private Vector3 pos;//炮口的初始方向private Vector3 initPos;//炮口去拿到配置表中的数据 方便使用private int num;private float offset;private float delay;//全部的子弹数据List<BulletData> bullets;//单个开火数据public FireData fire;//单个子弹数据public BulletData bullet;// Update is called once per framevoid Update(){//初始化各个炮口的位置UpdatePos();//每次发射子弹的随机数 以及旋转角度的设置Reset();//发射子弹Fire();}public void UpdatePos(){//我们需要找到在z这一层的切面 因为其他子弹也需要在这一层//先根据玩家的世界坐标找到屏幕坐标的z是多少//然后设置世界坐标的z给pos//最后用屏幕转为世界坐标 让子弹出现的位置都在这一层即可pos.z = 40;switch(type){case Type_PointType.topLeft:pos.x = 0;pos.y = Screen.height;initPos = Vector3.right;break;case Type_PointType.topRight:pos.x = Screen.width;pos.y = Screen.height;initPos = Vector3.left;break;case Type_PointType.topCenter:pos.x = Screen.width/2;pos.y = Screen.height;initPos = Vector3.right;break;case Type_PointType.Left:pos.x = 0;pos.y = Screen.height/2;initPos = Vector3.right;break;case Type_PointType.Right:pos.x = Screen.width;pos.y = Screen.height/2;initPos = Vector3.left;break;case Type_PointType.bottomLeft:pos.x = 0;pos.y = 0;initPos = Vector3.right;break;case Type_PointType.bottomRight:pos.x = Screen.width;pos.y = 0;initPos = Vector3.left;break;case Type_PointType.bottomCenter:pos.x = Screen.width/2;pos.y = 0;initPos = Vector3.right;break;}this.transform.position = Camera.main.ScreenToWorldPoint(pos);}//旋转的角度private float angle;/// <summary>/// /// 随机数 将子弹的四种移动方式和开火的两种方式随机排列组合 想实现的功能看个人/// bullet 四种类型1.直线 2.曲线 3.左抛物线 4.右抛物线 5.跟踪 /// fire 两种类型1.连发 2.散弹/// </summary>public void Reset(){//终止条件的判断 如果子弹间隔时间和数量没有发完 不能从新随机if (offset != 0 && num != 0)return;if(fire != null){//delay代表每组子弹的间隔时间delay -= Time.deltaTime;if(delay > 0){return;}}//拿到全部的开火数据 随机选择开火方式List<FireData> fires = GameDataManager.Instance.fireData;fire = fires[Random.Range(0, fires.Count)];//本地拿到初始值this.num = fire.num;this.offset = fire.offset;this.delay = fire.delay;//拿到全部的子弹数据 随机选择子弹移动方式bullets = GameDataManager.Instance.bulletDatas;bullet = bullets[Random.Range(0, bullets.Count)];//1.左上角和右下角发射右抛物线//2.左下角和右上角发射左抛物线//3.type = 3 是左抛物线 type = 4 是右抛物线if(fire.type == 2){//2类型是散弹 需要随机角度switch (type){case Type_PointType.topLeft:case Type_PointType.bottomLeft:case Type_PointType.topRight:case Type_PointType.bottomRight:angle = 90 / num;break;case Type_PointType.topCenter:case Type_PointType.Left:case Type_PointType.Right:case Type_PointType.bottomCenter:angle = 180 / num;break;}}}private Vector3 newRot;/// <summary>/// 开火 个人决定开火口能发射怎样的子弹/// 核心点:根据不同的开火方式 去创建子弹 以及子弹特效 子弹的位置 子弹的旋转角度/// </summary>public void Fire(){if (type == Type_PointType.topLeft || type == Type_PointType.bottomRight){bullet.type = 4;}if (type == Type_PointType.topRight || type == Type_PointType.bottomLeft){bullet.type = 3;}//间隔时间和数量归0 不会进入循环if (offset == 0 && num == 0)return;//每个子弹的判断放到最前面offset -= Time.deltaTime;//当间隔时间大于0 还在等待期 if (offset > 0)return;GameObject go;switch (fire.type){case 1:go = Instantiate(Resources.Load<GameObject>(bullet.bulletRes));go.GetComponent<BulletObj>().Init(bullet.id);go.transform.position = this.transform.position;go.transform.rotation = Quaternion.LookRotation(PlayerObj.Instance.transform.position - this.transform.position);//子弹减少--num;//当子弹发射完成后 间隔时间归0 就不会再次进入循环 没发射完就重置间隔时间offset = num == 0 ? 0 : fire.offset;break;case 2://散弹不能发射曲线子弹if (bullet.type != 2){for (int i = 0; i < num; i++){go = Instantiate(Resources.Load<GameObject>(bullet.bulletRes));go.GetComponent<BulletObj>().Init(bullet.id);go.transform.position = this.transform.position;//四元数乘向量 得到新的向量//每次旋转i * 20 newRot = Quaternion.AngleAxis(i * angle, Vector3.up) * initPos;//新的方向给四元数 最后赋值给角度即可go.transform.rotation = Quaternion.LookRotation(newRot);}offset = num = 0;}else{Reset();}break;}}
}
5.Main调用
(1)最后通过Main放置在游戏场景,当进入场景时,根据选择的id创建飞机,初始化变量,更新界面的ui,其实放在GamePanel中也是一样的,都可以
相关文章:
Unity太空避障Demo总结
太空避障:主要是实现飞机躲避子弹 面板基类、音乐类、排行榜类、json等等都和上一篇Unity坦克迷宫Demo总结一样,太空避障主要是对四元数的练习和使用 1.选择飞机面板 (1)通过左右按钮对显示的模型进行切换 (2ÿ…...
SpringSecurity-重写默认配置
重写UserDetailService组件 1.注入Bean的方式 /*** author: coffee* date: 2024/6/22 21:22* description: 重写springsecurity默认组件:注入Bean的方式*/Configuration public class ProjectConfig {/*** 重写userDetailsService组件*/Beanpublic UserDetailsSer…...
C# 判断值是否在枚举里
你还在代码里面通篇通过数字的定义类型。比如type为1 表示xx,type为2 表示yy吗?然后程序里面通过数字1和2来判断吗?比如下面类似的代码: if(type1){ //.... } else if(type2){ //... } else if(type3){ //... } 老鸟们一般都会用枚举来定义…...
Interview preparation--elasticSearch倒排索引原理
搜索引擎应该具备哪些要求 查询速度快 优秀的索引结构设计高效率的压缩算法快速的编码和解码速度 结果准确 ElasiticSearch 中7.0 版本之后默认使用BM25 评分算法ElasticSearch 中 7.0 版本之前使用 TP-IDF算法 倒排索引原理 当我们有如下列表数据信息,并且系统…...
银河麒麟高级服务器操作系统V10SP2(X86)配置bond0的mac地址为指定子网卡的mac地址
银河麒麟高级服务器操作系统V10SP2(X86)配置bond0的mac地址为指定子网卡的mac地址 一 系统环境二 删除和备份原有配置2.1 down掉bond02.2 备份之前的bond配置到/root/bak2.3 删除bond配置(网卡文件根据实际情况变化) 三 新建bond0…...
python中不同维度的Tensor向量为何可以直接相加——广播机制
文章目录 广播机制示例解释广播机制如何工作代码示例输出解释广播机制的本质 在矩阵加法中,如果两个张量的形状不同,但其中一个张量的形状可以通过广播机制扩展到与另一个张量的形状相同,则可以进行加法操作。广播机制在深度学习框架…...
38.MessageToMessageCodec线程安全可被共享Handler
handler被注解@Sharable修饰的。 这样的handler,创建一个实例就够了。例如: ByteToMessageCodec的子类不能被@Sharable修饰 如果自定义类是MessageToMessageCodec的子类就是线程共享的,可以被@Sharable修饰的 package com.xkj.protocol;import com.xkj.message.Message; i…...
Linux中的全局环境变量和局部环境变量
Linux中的全局环境变量和局部环境变量 一、全局环境变量二、局部环境变量三、 设置全局环境变量 bash shell用一个叫作环境变量 (environment variable)的特性来存储有关shell会话和工作环境的信息(这也是它们被称作环境变量的原 因ÿ…...
【研究】AI大模型需要什么样的硬件?
关注AI大模型 x 硬件的两条思路 从22年11月OpenAI推出ChatGPT至今,我们看到Chatbot应用的能力不断增强,从最初的文字问答,迅速向具有自主记忆、推理、规划和执行的全自动能力的AI Agent发展。我们认为端侧智能是大模型发展的重要分支。建议投…...
人工智能--自然语言处理NLP概述
欢迎来到 Papicatch的博客 目录 🍉引言 🍈基本概念 🍈核心技术 🍈常用模型和方法 🍈应用领域 🍈挑战和未来发展 🍉案例分析 🍈机器翻译中的BERT模型 🍈情感分析在…...
基于Java微信小程序火锅店点餐系统设计和实现(源码+LW+调试文档+讲解等)
💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟感兴趣的可以先收藏起来,还…...
SpringCloud_GateWay服务网关
网关作用 Gateway网关是我们服务的守门神,所有微服务的统一入口。 网关的核心功能特性: 请求路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务&a…...
使用Dropout大幅优化PyTorch模型,实现图像识别
大家好,在机器学习模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象。在训练神经网络时,过拟合具体表现在模型训练数据损失函数较小,预测准确率较高,但是在测…...
Vue3中的常见组件通信(超详细版)
Vue3中的常见组件通信 概述 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refs、parent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。 组件关系传递方式父传子1. props2. v-model3. $refs4. 默认…...
Stm32的DMA的学习
一,介绍 二,DMA框图 三,DMA通道 四,相关HAL库函数 五,配置DMA 六,Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili...
应用安全(补充)
Nessus是目前全世界最多人使用的系统漏洞扫描与分析软件。NMAP是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。X-SCAN安全漏洞扫描工具AppScan是IBM的一款web安全扫描工具,可以利用爬虫技术进行网站安全渗透测试,根据网站入口自…...
鸿蒙开发Ability Kit(程序框架服务):【FA模型切换Stage模型指导】 app和deviceConfig的切换
app和deviceConfig的切换 为了便于开发者维护应用级别的属性配置,Stage模型将config.json中的app和deviceConfig标签提取到了app.json5中进行配置,并对部分标签名称进行了修改,具体差异见下表。 表1 配置文件app标签差异对比 配置项FA模型…...
通过命令行配置调整KVM的虚拟网络
正文共:1234 字 20 图,预估阅读时间:2 分钟 在上篇文章中(最小化安装的CentOS7部署KVM虚拟机),我们介绍了如何在最小化安装的CentOS 7系统中部署KVM组件和相关软件包。因为没有GUI图形界面,我们…...
Apache POI操作excel
第1部分:引言 1.1 Apache POI简介 Apache POI是一个开源的Java库,用于处理Microsoft Office文档。自2001年首次发布以来,它已经成为Java社区中处理Office文档事实上的标准。Apache POI支持HSSF(用于旧版本的Excel格式࿰…...
Python错误集锦:faker模块生成xml文件时提示:`xml` requires the `xmltodict` Python library
原文链接:http://www.juzicode.com/python-error-faker-exceptions-unsupportedfeature-xml-requires-the-xmltodict-python-library 错误提示: faker模块生成xml文件时提示: xml requires the xmltodict Python library Traceback (most r…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2
----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导,采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…...
