当前位置: 首页 > news >正文

【Unity案例】搭建射击系统与UI

上期将基础的移动系统搭建完毕后就可以开始搭建更加复杂的系统部分了

前排提示,由于一开始仅思考如何完成操作相关功能,以至于到后面重构稍微有些困难,继续写下去恐成屎山,故在搭完射击和武器UI后不再继续泛化到敌人和敌人状态机

本次主要完成了

自由配置武器参数:武器所需的所有参数都可进行调整

请添加图片描述

武器的追随准星:

根据输入的武器槽位自动平滑的跟随指定武器的枪线,换弹时也会有相应提示

在这里插入图片描述

武器的切换:

不同武器根据数字键进行切换,在UI和准星上也会有所体现

在这里插入图片描述

第一第三人称的切换:

可以在第一第三人称间无缝切换

在这里插入图片描述

请看VCR!

Unity机甲2

文章目录

    • 总览
    • 武器系统
    • 子弹
    • 第一第三人称转换
    • UI

总览

类图结构

请添加图片描述

武器系统

武器使用状态机进行实现,WeaponState继承自State,内部持有Weapon的引用

Weapon是挂载在玩家身上的主要类,一个武器对应一个Weapon,手动输入索引标识其所属的武器槽位

public class Weapon : MonoBehaviour
{public enum FireMode{Single,Brust,Auto}private Entity owner;public int weaponSelectIndex = 0;public bool selected { get; private set; } = false;[Header("武器性能")][SerializeField] private int maxAmmo = 1;                                //最大弹匣弹药量[SerializeField] private int maxPrepareAmmo = 16;                //最大后备弹药量[SerializeField] private float shootingInterval = 0.1f;            //射击间隔[SerializeField] public float reloadTime = 2;                            //换弹时间[Header("开火模式")][SerializeField] public FireMode fireMode = FireMode.Single;      //开火模式 [SerializeField] private int brustNum = 3;                                      //brust一次开火射出的子弹数[SerializeField] private float brustTime = 1;                                  //两次brust开火之间的间隔//[Header("武器状态参数")]private int curAmmo;                                    //当前弹药量private int curPrepareAmmo;                       //当前后备弹药量private float shootingIntervalTimer = 0;    //射击间隔计时器private float brustTimeTimer = 0;               //brust射击间隔计时器private int brustCounter;                             //brust计数器[Header("发射物")][SerializeField] public Transform fireSocket;           [SerializeField] private GameObject bulletPrefab;   public float bulletVelocity = 100;                              public float inertialVelocityMultipler = 10;               public bool constantSpeed = false;                             //本来想做个委托外包出去,想了想不如直接集成在类里得了[Header("特效效果")][SerializeField] private GameObject fireFX;private CinemachineImpulseSource impulseSource;public float cameraShakeMultipler = 1f;[Header("音频")][SerializeField] private AudioClip fireSound;[SerializeField] private AudioClip reloadSound;[SerializeField] private float soundMultipler = 1f;//玩家的输入对应的委托转发public UnityAction onFireStart, onFiring, onFireEnd, onReload;//换弹时的委托,与UI通信使用public UnityAction onReloadStart, onReloadEnd;public UnityAction<float> onReloading;public UnityAction<int, int> onAmmoChanged;//是否选中public UnityAction<bool> onSelectChanged;//自己的状态机private StateMachine stateMachine = new StateMachine();public WeaponIdleState idleState;public WeaponFireState fireState;public WeaponReloadState reloadState;private void Awake(){owner = GetComponent<Entity>();impulseSource = fireSocket.GetComponent<CinemachineImpulseSource>();if (weaponSelectIndex == 1)selected = true;//初始化数据curAmmo = maxAmmo;curPrepareAmmo = maxPrepareAmmo;brustTimeTimer = brustTime;brustCounter = brustNum;//状态初始化idleState = new WeaponIdleState(stateMachine, this);fireState = new WeaponFireState(stateMachine, this);reloadState = new WeaponReloadState(stateMachine, this);//自身赋值到Controller方便其他组件引用PlayerController.Ins.weapons[weaponSelectIndex] = this;}private void Start(){//玩家操作本Weaponowner.onFireStart += () => onFireStart?.Invoke();owner.onFireEnd += () => onFireEnd?.Invoke();owner.onReload += () => onReload?.Invoke();owner.onSelect += (num) =>{selected = num == weaponSelectIndex;onSelectChanged?.Invoke(selected);};owner.onAllSelect += () =>{selected = true;onSelectChanged?.Invoke(selected);};//初始化状态机stateMachine.Init(idleState);}private void Update(){stateMachine.Update();if (shootingIntervalTimer > 0)shootingIntervalTimer -= Time.deltaTime;if (brustCounter <= 0 && brustTimeTimer > 0){brustTimeTimer -= Time.deltaTime;if (brustTimeTimer <= 0)brustCounter = brustNum;}if(owner.firing)onFiring?.Invoke();}public void ModifyAmmo(int amount){curAmmo += amount;curAmmo = Mathf.Clamp(curAmmo, 0, maxAmmo);onAmmoChanged?.Invoke(curAmmo, curPrepareAmmo);}public void Fire(){if (!CanFire())return;//发射投射物Bullet bullet = Instantiate(bulletPrefab, fireSocket.position, fireSocket.rotation).GetComponent<Bullet>();bullet.Init(bulletVelocity, constantSpeed, new Vector3(owner.velocity.x, 0, owner.velocity.z) * inertialVelocityMultipler, owner.flag);//数据更新ModifyAmmo(-1);shootingIntervalTimer = shootingInterval;if (fireMode == FireMode.Brust)                 //如果是Brust模式{brustCounter--;if (brustCounter <= 0)brustTimeTimer = brustTime;}//播放枪口特效Instantiate(fireFX, fireSocket.position, fireSocket.rotation);//震动!impulseSource.m_DefaultVelocity.x = Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.m_DefaultVelocity.y = Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.m_DefaultVelocity.z = Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.GenerateImpulse();//枪口音效AudioManager.PlayClipAtPoint(fireSound, fireSocket.position, soundMultipler);}public void Reload(){int needAmmo = maxAmmo - curAmmo;curAmmo = Mathf.Min(curPrepareAmmo, maxAmmo);curPrepareAmmo = Mathf.Max(curPrepareAmmo - needAmmo, 0);onAmmoChanged?.Invoke(curAmmo, curPrepareAmmo);AudioManager.PlayClipAtPoint(reloadSound, owner.transform.position, soundMultipler);}public bool HaveAmmo() => curAmmo > 0;public bool HavePrepareAmmo() => curPrepareAmmo > 0;public bool CanFire(){if (!selected)return false;//没有子弹if (!HaveAmmo())return false;//没有结束冷却if (shootingIntervalTimer > 0)return false;//如果在Brust模式//如果Counter小于等于0,说明打完了,否则不管//如果打完了并且还没过brust冷却,那就不能打if (fireMode == FireMode.Brust && brustCounter <= 0 && brustTimeTimer > 0)return false;return true;}public bool CanBrust() => brustCounter > 0;public float GetReloadTime() => reloadTime;public int GetCurAmmo() => curAmmo;public int GetCurPrepareAmmo() => curPrepareAmmo;public bool CanReload() => curPrepareAmmo > 0 && curAmmo < maxAmmo;public State GetCurState() => stateMachine.curState;
}

武器的主要逻辑存在于状态机中

在这里插入图片描述

但是由于武器的开火分为连发,单发,爆发,因此还需要做一些特殊的处理

以下是WeaponFireState

在使用爆发模式时,即使玩家松开开火键也不能立即停止开火

public class WeaponFireState : WeaponCommonState
{public bool readyEnd;public WeaponFireState(StateMachine stateMachine, Weapon weapon) : base(stateMachine, weapon){}public override void Enter(){base.Enter();weapon.onFireEnd += OnFireEnd;FireOrReload();readyEnd = false;}public override void Exit(){base.Exit();weapon.onFireEnd -= OnFireEnd;}private void OnFireEnd(){if (weapon.fireMode != Weapon.FireMode.Brust)stateMachine.ChangeState(weapon.idleState);readyEnd = true;}public override void Update(){base.Update();//爆发模式if (weapon.fireMode == Weapon.FireMode.Brust){if (weapon.CanBrust())FireOrReload();else if(readyEnd)stateMachine.ChangeState(weapon.idleState);}else if (weapon.fireMode == Weapon.FireMode.Auto)FireOrReload();}private void FireOrReload(){if (weapon.HaveAmmo()){weapon.Fire();if (!weapon.HaveAmmo())stateMachine.ChangeState(weapon.reloadState);}elsestateMachine.ChangeState(weapon.reloadState);}
}

其他部分较为简短不特别描述

子弹

子弹同样使用一个通用的类进行配置

public class Bullet : MonoBehaviour
{[Header("Physical")]private Rigidbody rb;private Vector3 lastPosition;[Header("Attribute")]//子弹所属派系,可以设定是否开启友军伤害,-1为中立派系public int flag = -1;public float velocity = 100;public bool constantSpeed = false;public float lifeTime = 6f;private float lifeTimer;public float gravityMultiper = 1f;[Header("VFX")]public GameObject explosionPrefab;public GameObject trailPrefab;private void Awake(){rb = GetComponent<Rigidbody>();lastPosition = transform.position;lifeTimer = lifeTime;}public void Init(float velocity, bool constantSpeed, Vector3 inertialVelocity /*惯性力*/, int flag = -1){this.velocity = velocity;this.constantSpeed = constantSpeed;rb.velocity += transform.forward * velocity * Time.fixedDeltaTime / rb.mass;rb.AddForce(transform.forward * velocity + inertialVelocity, ForceMode.Impulse);this.flag = flag;}private void Update(){lifeTimer -= Time.deltaTime;if (lifeTimer < 0)OnCollisionEnter(null);}void FixedUpdate(){//防止错过刚体,对即将经过的间隔做一个射线检测if (Physics.Raycast(lastPosition, rb.velocity.normalized, out RaycastHit hitInfo, rb.velocity.magnitude * Time.fixedDeltaTime)){transform.position = hitInfo.point;rb.velocity = Vector3.zero;return;}//持久动力if (constantSpeed)rb.AddForce(transform.forward * velocity);//调整旋转朝向transform.forward = rb.velocity.normalized;//应用重力乘数rb.velocity += new Vector3(0, 9.8f * (1 - gravityMultiper) * Time.fixedDeltaTime, 0);//记录位置lastPosition = transform.position;}private void OnCollisionEnter(Collision collision){if(collision != null && collision.gameObject.TryGetComponent(out Entity entity)){if (entity.flag == flag)return;}if (trailPrefab){trailPrefab.transform.parent = null;var particleSystems = trailPrefab.GetComponentsInChildren<ParticleSystem>();foreach (var particle in particleSystems){var main = particle.main;main.loop = false;}}Instantiate(explosionPrefab, transform.position, Quaternion.identity);Destroy(gameObject);}private void DelayTrail(){trailPrefab.SetActive(true);}    
}

其内部包含初始惯性处理,持续动力,防止高速穿过物体的处理以及视觉和销毁时如果有拖尾的处理

第一第三人称转换

这一块比较简单,直接使用Cinemachine自带的混合,代码只需要控制两个虚拟相机的激活即可

public class PlayerCameraController : MonoBehaviour
{//Third Person Camera[SerializeField] private CinemachineVirtualCamera thirdPersonCamera;private Cinemachine3rdPersonFollow thirdCameraBody;public float freeLookSide = 0;public float freeLookDistance = 20;float cameraSide;float cameraDistance;//First Peroson Camera[SerializeField] private CinemachineVirtualCamera firstPersonCamera;private Cinemachine3rdPersonFollow firstCameraBody;private Quaternion lastQuaternion;private void Awake(){thirdCameraBody = thirdPersonCamera.GetCinemachineComponent<Cinemachine3rdPersonFollow>();cameraSide = thirdCameraBody.CameraSide;cameraDistance = thirdCameraBody.CameraDistance;firstCameraBody = firstPersonCamera.GetCinemachineComponent<Cinemachine3rdPersonFollow>();}// Update is called once per framevoid Update(){HandleFreeLook();HandleSwitchView();}private void HandleFreeLook(){if (Input.GetKeyDown(KeyCode.C)){//控制器冻结lastQuaternion = PlayerController.GetControllerRotation();PlayerController.SetPause(true);//第三人称参数thirdCameraBody.CameraSide = freeLookSide;thirdCameraBody.CameraDistance = freeLookDistance;//隐藏准星(有视觉Bug)foreach(var hair in UIManager.Ins.crossHairs){hair.gameObject.SetActive(false);}}if (Input.GetKeyUp(KeyCode.C)){//控制器恢复PlayerController.SetControllerRotation(lastQuaternion);PlayerController.SetPause(false);//第三人称参数thirdCameraBody.CameraSide = cameraSide;thirdCameraBody.CameraDistance = cameraDistance;//显示UIforeach (var hair in UIManager.Ins.crossHairs){hair.gameObject.SetActive(PlayerController.Ins.weapons[hair.weaponIndex].selected);}}}private void HandleSwitchView(){if (Input.GetKeyDown(KeyCode.V)){firstPersonCamera.gameObject.SetActive(!firstPersonCamera.gameObject.activeSelf);thirdPersonCamera.gameObject.SetActive(!thirdPersonCamera.gameObject.activeSelf);}}
}

UI

比较重要的地方是丝滑的UI跟随以及实时的武器栏

后者只需要在制作时留意委托就可以很方便的调用,前者则需要一些不同空间的变换知识

准星的跟随部分

一开始我在Canvas中选择的渲染模式是覆盖,后来发现在覆盖的模式下不能添加自发光,导致UI较暗,于是调整为了摄像机空间,但调整后导致原本跟踪正确的准星又不再正确,下面是解决办法

public class CrossHairUI : MonoBehaviour
{//自身private RectTransform rect, parent;[SerializeField] private GameObject aimHair, reloadHair;[SerializeField] private TextMeshPro reloadTxt;//武器public int weaponIndex = 0;private Weapon weapon;private Transform fireSocket;public float lerpMultipler = 0.1f;void Start(){rect = GetComponent<RectTransform>();parent = rect.parent.GetComponent<RectTransform>();weapon = PlayerController.Ins.weapons[weaponIndex];fireSocket = weapon.fireSocket;weapon.onReloadStart += OnReloadStart;weapon.onReloading += OnReloading;weapon.onReloadEnd += OnReloadEnd;weapon.onSelectChanged += (selected) =>{gameObject.SetActive(selected);};gameObject.SetActive(weapon.selected);}void Update(){if (Physics.SphereCast(fireSocket.position, .5f, fireSocket.forward, out RaycastHit hitInfo, 1000)){if(RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, RectTransformUtility.WorldToScreenPoint(Camera.main, hitInfo.point), Camera.main, out Vector2 localPoint)){rect.localPosition = Vector2.Lerp(rect.localPosition, localPoint, lerpMultipler);}}else{Vector3 point = fireSocket.position + fireSocket.forward * 3000;if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, RectTransformUtility.WorldToScreenPoint(Camera.main, point), Camera.main, out Vector2 localPoint)){rect.localPosition = Vector2.Lerp(rect.localPosition, localPoint, lerpMultipler);}}}private void OnReloadStart(){aimHair.SetActive(false);reloadHair.SetActive(true);}private void OnReloading(float remainTime){reloadTxt.SetText(remainTime.ToString("0.00"));}private void OnReloadEnd(){aimHair.SetActive(true);reloadHair.SetActive(false);}
}

在Update中首先SphereCast来获取击中的点,再将其WorldToScreenPoint变换到屏幕空间,如果是覆盖的渲染模式,此时已经结束了,但由于是摄像机模式,因此需要再多一个变换即ScreenPointToLocalPointInRectangle将其变换到面板上的相对位置。之后使用插值即可实现丝滑的跟踪准

相关文章:

【Unity案例】搭建射击系统与UI

上期将基础的移动系统搭建完毕后就可以开始搭建更加复杂的系统部分了 前排提示&#xff0c;由于一开始仅思考如何完成操作相关功能&#xff0c;以至于到后面重构稍微有些困难&#xff0c;继续写下去恐成屎山&#xff0c;故在搭完射击和武器UI后不再继续泛化到敌人和敌人状态机…...

Python使用zdppy_mysql操作MySQL和MariaDB数据库快速入门教程

zdppy_mysql 使用python操作MySQL 项目开源地址&#xff1a;https://github.com/zhangdapeng520/zdppy_mysql 安装 pip install zdppy_mysql使用教程 连接MySQL import zdppy_mysql from config import host, username, password, database, port# 连接数据库 db zdppy_…...

union 的正确食用方法

0.前情提要 &#xff08;很久&#xff09;之前上编译原理时&#xff0c;一次实验课需要补充完善一个用 c 写的词法分析器&#xff1b;而这个分析器在定义语法树结点时使用了 union 存储语言中不同表达式的类型标签或值本身。因为当时刚好学完了 cpp&#xff0c;拿着锤子看啥都…...

汇编语言在虚拟机中输出“Hello World!”

1.软件 Nasmide64.exe(李忠老师编写) Fixvhdw64.exe(李忠老师编写) VirtualBox虚拟机(免费 开源) 2.过程 01.Fixvhdw64.exe输入以下代码: mov ax,0xb800 mov ds,ax mov byte [0x00],H mov byte [0x02],e mov byte [0x04],l mov byte [0x06],l mov byte [0x08],o mov byte…...

JVM类的加载和类的加载器

JVM类的加载和类的加载器 一.类的加载过程 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内&#xff0c;然后在堆区创建一个java.lang.Class对象&#xff0c;用来封装类在方法区内的数据结构。类的加载的最终产品是位于…...

MLM:多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略

MLM&#xff1a;多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略 目录 相关文章 AI之MLM&#xff1a;《MM-LLMs: Recent Advances in MultiModal Large Language Models多模态大语言模型的最新进展》翻译与解读 MLM之CLIP&#xff1a;CLIP…...

Java健康养老智慧相伴养老护理小程序系统源码代办陪诊陪护更安心

健康养老&#xff0c;智慧相伴 —— 养老护理小程序&#xff0c;代办陪诊陪护更安心 &#x1f308;【开篇&#xff1a;智慧养老&#xff0c;新时代的温馨守护】&#x1f308; 在这个快节奏的时代&#xff0c;我们总希望能给予家人更多的关爱与陪伴&#xff0c;尤其是家中的长…...

Python | Leetcode Python题解之第390题消除游戏

题目&#xff1a; 题解&#xff1a; class Solution:def lastRemaining(self, n: int) -> int:a1 1k, cnt, step 0, n, 1while cnt > 1:if k % 2 0: # 正向a1 stepelse: # 反向if cnt % 2:a1 stepk 1cnt >> 1step << 1return a1...

Github 2024-09-01 开源项目月报 Top16

根据Github Trendings的统计,本月(2024-09-01统计)共有16个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目9TypeScript项目5Dart项目2C项目1Jupyter Notebook项目1Rust项目1开发者职业成长指南 创建周期:2670 天开发语言:TypeScript协议类…...

C++ 继承(二)

目录 1. 实现一个不能被继承的类 2. 友元与继承 3.继承与静态成员 4.多继承及其菱形继承问题 (1). 继承模型 (2). 虚继承 (2.1)虚继承解决数据冗余和二义性的原理 (3). 多继承中指针偏移问题 (4). IO库中的菱形虚拟继承 5. 继承和组合 1. 实现一个不能被继承的类 方法1…...

第 2 章:AJAX 的使用

AJAX 的使用 核心对象&#xff1a;XMLHttpRequest&#xff0c;AJAX 的所有操作都是通过该对象进行的。 1. 使用步骤 创建 XMLHttpRequest 对象 var xhr new XMLHttpRequest(); 设置请求信息 xhr.open(method, url);//可以设置请求头&#xff0c;一般不设置 xhr.setReques…...

ROS——视觉抓取

纲要 视觉抓取中的关键技术 内参标定 物体识别定位 抓取姿态分析 运动规划 外参标定 任意两个位姿之间的关系 眼在外 眼在内 手眼标定流程 robot 部分 标定效果 视觉抓取例程 grasping_demo.cpp 获取两个坐标系之间变换关系:waitForTransform 、 LookupTransform 求相…...

EPLAN2022基础教程

EPLAN2022软件介绍 EPLAN是一款专业的电气设计和绘图软件&#xff0c;它可以帮助我创建和管理电气项目&#xff0c;生成各种报表和文档&#xff0c;与其他软件和系统进行交互&#xff0c;优化工程流程和质量。与传统的CAD绘图对比&#xff0c;EPLAN更适合绘制电气原理图。 下…...

【JavaWeb】Servlet 详解(处理逻辑及常见方法)

文章目录 1. Tomcat1.1 常见的错误1.1.1 出现 4041.1.2 出现 4051.1.3 出现 500 1.2 HttpServlet1.2.1 Tomcat 的处理逻辑1.2.2 相关方法 1.3 HttpServletRequest1.3.1 常见方法1.3.2 jackson 处理逻辑 1.4 HttpServletResponse1.4.1 常见方法 1. Tomcat tomcat 是一个 HTTP 服…...

6 自研rgbd相机基于rk3566之深度计算库程序详解

自研rgbd相机基于rk3566之深度计算库详解 1 tof深度计算库框架读入深度图像参数配置tof模组标定参数读入及解析深度计算函数接口2 tof深度计算库程序详解深度计算程序头文件深度计算程序 源文件1 tof深度计算库框架 读入深度图像参数配置 支持raw8/raw10/raw16 格式 /*******…...

分布式系统框架hadoop3入门

分布式系统框架hadoop3入门 (qq.com) Hadoop3作为分布式系统架构的重要基石&#xff0c;为大规模数据存储与处理提供了强大支持 基本信息 hadoop&#xff1a;一个存储和处理大数据的分布式系统框架 组成&#xff1a; HDFS&#xff08;数据存储&#xff09;、MapReduce&…...

使用 i3.LayoutCell() 方法绘制版图并输出为 GDS 文件

使用 i3.LayoutCell 方法绘制版图并输出为 GDS 文件 引言正文引言 在 IPKISS i3.SRef() 函数 一文中我们介绍了如何使用 i3.SRef() 函数将 instance 对象添加到 i3.LayoutCell() 创建的 Cell 对象上。但是当我们使用 write_gdsii() 输出版图时代码就会报错。这里我们将介绍如何…...

mariadb容器

下载镜像 $ sudo docker pull mariadb启动容器 $ sudo docker run --name my-mariadb -d -e MARIADB_DATABASEtestdb -e MARIADB_ROOT_PASSWORDLetmein -p 3306:3306 mariadb上面命令会启动一个名为my-mariadb的容器&#xff0c;并初始化一个testdb数据库&#xff0c;同时设置…...

应用层协议Http

Http协议 1.1 什么是http协议 在进行网络通信时&#xff0c;应用层协议一般都是程序员自己写的&#xff0c;但是有一些大佬其实已经定义出了一些现成的应用层协议&#xff0c;例如&#xff1a;HTTP&#xff08;超文本传输协议&#xff09;、FTP&#xff08;文件传输协议&#…...

display flex 的div 被子元素撑开不显示滚动条的一个解决demo

display flex 的div 被子元素撑开&#xff0c;不显示y轴滚动条的 一个解决demo。 注&#xff1a; 不一定适用所有人的的相同问题 less # less .contact {display: flex;flex-grow: 1;overflow: hidden auto;flex-direction: column;.contact-items {flex: 1 1 0;display: flex…...

Obsidian LiveSync技术全景:自托管同步插件的深度解析与架构揭秘

Obsidian LiveSync技术全景&#xff1a;自托管同步插件的深度解析与架构揭秘 【免费下载链接】obsidian-livesync 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-livesync Obsidian LiveSync作为一款社区驱动的自托管同步插件&#xff0c;为Obsidian用户提供了…...

【华为云CCE实战】内网环境下的Nacos集群容器化部署全流程

1. 内网环境下的Nacos集群部署挑战 在企业级微服务架构中&#xff0c;Nacos作为服务注册中心和配置中心扮演着关键角色。但在内网隔离环境下部署Nacos集群&#xff0c;就像在没有GPS信号的隧道里组车队——既需要确保每辆车&#xff08;节点&#xff09;都能互相定位&#xff0…...

别再吹牛了,% Vibe Coding 存在无法自洽的逻辑漏洞!捶

简介 langchain中提供的chain链组件&#xff0c;能够帮助我门快速的实现各个组件的流水线式的调用&#xff0c;和模型的问答 Chain链的组成 根据查阅的资料&#xff0c;langchain的chain链结构如下&#xff1a; $$Input \rightarrow Prompt \rightarrow Model \rightarrow Outp…...

【稀缺首发】金融级大模型上线前必过测试关:自动生成符合ISO/IEC 25010标准的137条可执行用例(含合规性断言模板)

第一章&#xff1a;大模型工程化测试用例自动生成 2026奇点智能技术大会(https://ml-summit.org) 大模型工程化落地的核心挑战之一&#xff0c;在于测试覆盖难以随模型迭代速度同步演进。传统手工编写测试用例的方式在面对动态 Prompt、多轮对话、上下文敏感输出等场景时&…...

树莓派3 GPIO避坑指南:从引脚烧毁到代码报错的10个常见问题(附解决方案)

树莓派3 GPIO避坑指南&#xff1a;从引脚烧毁到代码报错的10个常见问题&#xff08;附解决方案&#xff09; 当你第一次将LED连接到树莓派的GPIO引脚&#xff0c;却发现它死活不亮时&#xff0c;那种挫败感简直让人抓狂。更糟的是&#xff0c;你可能还会闻到一股焦糊味——没错…...

战地2042 0xc000007b错误解决方法:不重装系统的修复教程

《战地风云2042》启动时弹出一个“应用程序无法正常启动(0xc000007b)”的错误窗口&#xff0c;这几乎是PC游戏玩家最头疼的报错之一。这个错误代码本身比较笼统&#xff0c;它不代表你的游戏文件坏了&#xff0c;也不代表你的系统彻底崩溃了&#xff0c;而是系统在尝试运行程序…...

[具身智能-353]:大模型如何提供服务?MCP Client如何调用大模型的服务?

在MCP架构中&#xff0c;大模型&#xff08;LLM&#xff09;并不是一个被动等待调用的“函数库”&#xff0c;而是一个拥有推理能力的“智能体”。因此&#xff0c;MCP Client 调用大模型的方式&#xff0c;不是简单的“调用服务”&#xff0c;而是“发起一次决策请求”。这就像…...

Claude API与Graphormer协同:构建智能化学研究助手

Claude API与Graphormer协同&#xff1a;构建智能化学研究助手 1. 引言&#xff1a;化学研究的语言障碍 化学研究领域长期存在一个有趣的现象&#xff1a;专业研究人员与普通用户之间存在巨大的认知鸿沟。一个简单的分子结构描述&#xff0c;对化学家来说可能像母语一样自然&…...

DownKyi视频下载工具:3步快速上手与5大实用技巧

DownKyi视频下载工具&#xff1a;3步快速上手与5大实用技巧 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff09;…...

AcousticSense AI算力优化:批处理+FP16混合精度使吞吐量提升3.2倍

AcousticSense AI算力优化&#xff1a;批处理FP16混合精度使吞吐量提升3.2倍 1. 引言&#xff1a;当音乐分析遇上性能瓶颈 想象一下&#xff0c;你正在搭建一个音乐流派的智能分析平台。用户上传一首歌&#xff0c;系统需要快速、准确地告诉你这首歌是摇滚、爵士还是电子乐。…...