Unity教程(十六)敌人攻击状态的实现
Unity开发2D类银河恶魔城游戏学习笔记
Unity教程(零)Unity和VS的使用相关内容
Unity教程(一)开始学习状态机
Unity教程(二)角色移动的实现
Unity教程(三)角色跳跃的实现
Unity教程(四)碰撞检测
Unity教程(五)角色冲刺的实现
Unity教程(六)角色滑墙的实现
Unity教程(七)角色蹬墙跳的实现
Unity教程(八)角色攻击的基本实现
Unity教程(九)角色攻击的改进
Unity教程(十)Tile Palette搭建平台关卡
Unity教程(十一)相机
Unity教程(十二)视差背景
Unity教程(十三)敌人状态机
Unity教程(十四)敌人空闲和移动的实现
Unity教程(十五)敌人战斗状态的实现
Unity教程(十六)敌人攻击状态的实现
Unity教程(十七)敌人战斗状态的完善
如果你更习惯用知乎
Unity开发2D类银河恶魔城游戏学习笔记目录
文章目录
- Unity开发2D类银河恶魔城游戏学习笔记
- 前言
- 一、概述
- 二、创建骷髅攻击动画
- 三、骷髅攻击的实现
- (1)整理代码
- (2)创建SkeletonAttackState
- (3)触发器的实现
- (4)攻击的实现
- 四、骷髅攻击的冷却
- 总结 完整代码
- EnemyState.cs
- Enemy.cs
- Enemy_SkeletonAnimationTriggers.cs
- Enemy_Skeleton.cs
- SkeletonBattleState.cs
- SkeletonAttackState.cs
- SkeletonMoveState.cs
前言
本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记,如有错误,欢迎指正。
本节实现敌人的攻击状态。
Udemy课程地址
对应视频:
Enemy’s Attack State
一、概述
在骷髅进入战斗状态并走到距离玩家很近的距离时,就要进入攻击状态攻击玩家。本节中我们就实现骷髅的攻击状态。
这一部分状态转换条件较多,如下图:
二、创建骷髅攻击动画
我们创建动画skeletonAttack
层次面板中选中Enemy_skeleton下的Animator,在Animation面板中创建动画
将精灵表SkeletonAttack内容全部拖入,采样率改为15
动画创建的更详细讲解见Unity教程(零)Unity和VS的使用相关内容
连接状态机,并添加过渡条件Attack,并修改过渡设置
添加bool型条件变量Attack,并连接过渡
Entry->skeletonAttack的过渡,加条件变量
skeletonAttack->Exit的过渡,加条件变量,并更改设置
三、骷髅攻击的实现
(1)整理代码
上一节我们用到了很多次骷髅的速度,所以我们在敌人状态中创建刚体,使代码更简洁。
protected Rigidbody2D rb;public virtual void Enter(){rb = enemyBase.rb;triggerCalled = false;enemyBase.anim.SetBool(animBoolName, true);}
SkeletonBattleState状态Update函数中改为
public override void Update(){base.Update();if (enemy.IsPlayerDetected()){if (enemy.IsPlayerDetected().distance < enemy.attackDistance){stateMachine.ChangeState(enemy.attackState);}}if(player.position.x > enemy.transform.position.x)moveDir = 1;else if(player.position.x < enemy.transform.position.x)moveDir = -1;enemy.SetVelocity(enemy.moveSpeed * moveDir, rb.velocity.y);}
SkeletonMoveState状态Update函数中改为
public override void Update(){base.Update();enemy.SetVelocity(enemy.moveSpeed*enemy.facingDir,rb.velocity.y);if(!enemy.isGroundDetected() || enemy.isWallDetected()){enemy.Flip();stateMachine.ChangeState(enemy.idleState);}}
(2)创建SkeletonAttackState
首先创建SkeletonAttackState,它继承自EnemyState,通过菜单生成构造函数和重写。
添加Enemy_Skeleton变量,并修改构造函数中传入值
protected Enemy_Skeleton enemy;public SkeletonAttackState(EnemyStateMachine _stateMachine, Enemy _enemyBase, Enemy_Skeleton _enemy, string _animBoolName) : base(_stateMachine, _enemyBase, _animBoolName){enemy = _enemy;}
(3)触发器的实现
和Player一样,敌人攻击的结束也要借助触发器来实现。
详细讲解请见Unity教程(八)角色基本攻击的实现
我们在状态基类EnemyState中添加改变参数的函数,若触发器被调用,则triggerCalled置为真。添加代码:
//修改触发器参数public virtual void AnimationFinishTrigger(){triggerCalled = true;}
在Enemy中进行调用
//设置触发器public virtual void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();
我们创建骷髅的触发器脚本Enemy_SkeletonAnimationTriggers。获取Animator的父组件Enemy_Skeleton,并调用其中的AnimationTrigger()
//Enemy_SkeletonAnimationTriggers:触发器组件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy_SkeletonAnimationTriggers : MonoBehaviour
{private Enemy_Skeleton enemy => GetComponentInParent<Enemy_Skeleton>();private void AnimationTrigger(){enemy.AnimationTrigger();}
}
把触发器脚本挂在Enemy_Skeleton的Animator下面  我们在skeletonAttack的最后一帧设置事件帧,调用触发器函数设置triggerCalled参数。
先把白色竖线拉到最后一帧,点击动画面板左边钉子符号的标志添加事件。
点击选中事件帧,在右边面板选中函数AnimationTrigger
Fuction->Enemy_SkeletonAnimationTriggers->Methods->AnimationTrigger()
(4)攻击的实现
我们要在Enemy_Skeleton中创建骷髅攻击状态。
public SkeletonAttackState attackState { get; private set; }protected override void Awake()
{base.Awake();idleState = new SkeletonIdleState(stateMachine,this,this,"Idle");moveState = new SkeletonMoveState(stateMachine, this,this, "Move");battleState = new SkeletonBattleState(stateMachine, this, this, "Move");attackState = new SkeletonAttackState(stateMachine, this, this, "Attack");
}
在SkeletonBattleState中添加状态转换,当距离过近时转换到攻击状态。
public override void Update(){base.Update();if (enemy.IsPlayerDetected()){if (enemy.IsPlayerDetected().distance < enemy.attackDistance){stateMachine.ChangeState(enemy.attackState);}}if(player.position.x > enemy.transform.position.x)moveDir = 1;else if(player.position.x < enemy.transform.position.x)moveDir = -1;enemy.SetVelocity(enemy.moveSpeed * moveDir, enemy.rb.velocity.y);}
我们在SkeletonAttackState中实现攻击的具体内容。
首先我们希望骷髅靠近玩家时,先停止移动再攻击,所以我们先把骷髅速度赋零。
在攻击动画播放完触发器被触发时,攻击结束,转换到战斗状态。
点击Animator也能看到左侧Attack变量在转换(切换很快,不仔细看不清楚)。
四、骷髅攻击的冷却
现在骷髅的攻击是连续不断的,在游戏中通常小怪是按照一定的频率进行的,让玩家有一定的躲避时间。
我们给骷髅小怪加上攻击冷却时间,实现上可以参照Player的连击。
我们在Enemy中添加冷却时间attackCoolDown,记录上次攻击的时间lastTimeAttacked用于实现。
[Header("Attack Info")]public float attackDistance;public float attackCoolDown;[HideInInspector] public float lastTimeAttacked;
在SkeletonAttackState中,每次退出攻击状态时,更新lastTimeAttacked。
public override void Exit(){base.Exit();enemy.lastTimeAttacked=Time.time;}
在SkeletonBattleState中添加CanAttack函数,利用现在的时间与上次攻击时间加冷却时间比较,判断冷却时间是否已经过去,骷髅是否处于可攻击状态。
先判断是否能检测到玩家,再判断玩家与骷髅的距离,再做攻击冷却的判断,条件都成立时转到战斗状态。
public override void Update(){base.Update();if (enemy.IsPlayerDetected()){if (enemy.IsPlayerDetected().distance < enemy.attackDistance){if(CanAttack())stateMachine.ChangeState(enemy.attackState);}}if(player.position.x > enemy.transform.position.x)moveDir = 1;else if(player.position.x < enemy.transform.position.x)moveDir = -1;enemy.SetVelocity(enemy.moveSpeed * moveDir, rb.velocity.y);}private bool CanAttack(){if (Time.time >= enemy.lastTimeAttacked + enemy.attackCoolDown)return true;return false;}
设置合适的冷却时间
效果如下
我们可以看到骷髅每隔一段时间进行攻击了。但是有个很明显的问题,在攻击的间隙骷髅不会停止移动,玩家会被推着走。这个问题下节我们再来解决。
总结 完整代码
EnemyState.cs
增加刚体和触发函数调用
//EnemyState:敌人状态基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyState
{protected EnemyStateMachine stateMachine;protected Enemy enemyBase;protected Rigidbody2D rb;private string animBoolName;protected float stateTimer;protected bool triggerCalled;//构造函数public EnemyState(EnemyStateMachine _stateMachine, Enemy _enemyBase, string _animBoolName){this.stateMachine = _stateMachine;this.enemyBase = _enemyBase;this.animBoolName = _animBoolName;}public virtual void Enter(){rb = enemyBase.rb;triggerCalled = false;enemyBase.anim.SetBool(animBoolName, true);}public virtual void Update(){stateTimer-= Time.deltaTime;}public virtual void Exit(){enemyBase.anim.SetBool(animBoolName, false);}//修改触发器参数public virtual void AnimationFinishTrigger(){triggerCalled = true;}
}
Enemy.cs
添加攻击相关变量,添加触发函数调用。
//Enemy:敌人基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : Entity
{[SerializeField] protected LayerMask WhatIsPlayer;[Header("Move Info")]public float moveSpeed = 1.5f;public float idleTime = 2.0f;[Header("Attack Info")]public float attackDistance;public float attackCoolDown;[HideInInspector] public float lastTimeAttacked;public EnemyStateMachine stateMachine;protected override void Awake(){base.Awake();stateMachine = new EnemyStateMachine();}protected override void Update(){base.Update();stateMachine.currentState.Update();}//设置触发器public virtual void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();public virtual RaycastHit2D IsPlayerDetected()=>Physics2D.Raycast(transform.position, Vector2.right * facingDir, 50 ,WhatIsPlayer);protected override void OnDrawGizmos(){base.OnDrawGizmos();Gizmos.color = Color.yellow;Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + attackDistance * facingDir, transform.position.y));}
}
Enemy_SkeletonAnimationTriggers.cs
触发器组件
//Enemy_SkeletonAnimationTriggers:触发器组件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy_SkeletonAnimationTriggers : MonoBehaviour
{private Enemy_Skeleton enemy => GetComponentInParent<Enemy_Skeleton>();private void AnimationTrigger(){enemy.AnimationTrigger();}
}
Enemy_Skeleton.cs
增加攻击状态创建
//Enemy_Skeleton:骷髅敌人
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy_Skeleton : Enemy
{#region 状态public SkeletonIdleState idleState { get; private set; }public SkeletonMoveState moveState { get; private set; }public SkeletonBattleState battleState { get; private set; }public SkeletonAttackState attackState { get; private set; }#endregionprotected override void Awake(){base.Awake();idleState = new SkeletonIdleState(stateMachine,this,this,"Idle");moveState = new SkeletonMoveState(stateMachine, this,this, "Move");battleState = new SkeletonBattleState(stateMachine, this, this, "Move");attackState = new SkeletonAttackState(stateMachine, this, this, "Attack");}protected override void Start(){base.Start();stateMachine.Initialize(idleState);}protected override void Update(){base.Update();}}
SkeletonBattleState.cs
添加攻击冷却判断条件,修改转到攻击状态的条件,修改刚体速度部分代码
//SkeletonBattleState:骷髅战斗状态
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkeletonBattleState : EnemyState
{private Transform player;private Enemy_Skeleton enemy;private int moveDir;public SkeletonBattleState(EnemyStateMachine _stateMachine, Enemy _enemyBase, Enemy_Skeleton _enemy, string _animBoolName) : base(_stateMachine, _enemyBase, _animBoolName){enemy=_enemy;}public override void Enter(){base.Enter();player = GameObject.Find("Player").transform;}public override void Exit(){base.Exit();}public override void Update(){base.Update();if (enemy.IsPlayerDetected()){if (enemy.IsPlayerDetected().distance < enemy.attackDistance){if(CanAttack())stateMachine.ChangeState(enemy.attackState);}}if(player.position.x > enemy.transform.position.x)moveDir = 1;else if(player.position.x < enemy.transform.position.x)moveDir = -1;enemy.SetVelocity(enemy.moveSpeed * moveDir, rb.velocity.y);}private bool CanAttack(){if (Time.time >= enemy.lastTimeAttacked + enemy.attackCoolDown)return true;return false;}
}
SkeletonAttackState.cs
创建攻击状态,攻击时速度置零,触发器触发转回到战斗状态
//SkeletonAttackState:骷髅攻击状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkeletonAttackState : EnemyState
{protected Enemy_Skeleton enemy;public SkeletonAttackState(EnemyStateMachine _stateMachine, Enemy _enemyBase, Enemy_Skeleton _enemy, string _animBoolName) : base(_stateMachine, _enemyBase, _animBoolName){enemy = _enemy;}public override void Enter(){base.Enter();}public override void Exit(){base.Exit();enemy.lastTimeAttacked=Time.time;}public override void Update(){base.Update();enemy.ZeroVelocity();if (triggerCalled)stateMachine.ChangeState(enemy.battleState);}
}
SkeletonMoveState.cs
修改刚体速度部分代码
//SkeletonMoveState:骷髅移动状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkeletonMoveState : SkeletonGroundedState
{public SkeletonMoveState(EnemyStateMachine _stateMachine, Enemy _enemyBase, Enemy_Skeleton enemy, string _animBoolName) : base(_stateMachine, _enemyBase, enemy, _animBoolName){}public override void Enter(){base.Enter();}public override void Exit(){base.Exit();}public override void Update(){base.Update();enemy.SetVelocity(enemy.moveSpeed*enemy.facingDir,rb.velocity.y);if(!enemy.isGroundDetected() || enemy.isWallDetected()){enemy.Flip();stateMachine.ChangeState(enemy.idleState);}}
}
相关文章:

Unity教程(十六)敌人攻击状态的实现
Unity开发2D类银河恶魔城游戏学习笔记 Unity教程(零)Unity和VS的使用相关内容 Unity教程(一)开始学习状态机 Unity教程(二)角色移动的实现 Unity教程(三)角色跳跃的实现 Unity教程&…...

图像超分辨率(ISR)
图像超分辨率(Image Super-Resolution, ISR)是一种图像处理技术,旨在通过软件算法从低分辨率的图像中重建出高分辨率的图像。这种技术对于改善图像质量、增加细节清晰度等方面非常重要,特别是在图像放大、卫星成像、医学成像和视频…...

园区网基础组网保姆级(mstp,vrrp,irf,eth-trunk,route-policy,ospf,bgp,rbm,nat,mlag等等)
本文实验使用模拟器:H3C HCL 5.10.2版本 一、园区核心/接入架构1.1.三层架构1.2.二层架构二、园区核心 To 接入实践2.1.MSTP+VRRP派系2.1.1.MSTP+VRRP配置2.1.2.MSTP+VRRP验证2.2.IRF+Eth-Trunk派系2.2.1.IRF+Eth-Trunk配置2.3.两种派系的对比2.4.VXLAN结构三、园区核心/出口架…...

大数据技术原理与应用
第一章、大数据概述 1、大数据时代的特征,并结合生活实例谈谈带来的影响。 (一)特征 1、Volume 规模性:数据量大。 2、Velocity高速性:处理速度快。数据的生成和响应快 摩尔定律:每两年,数…...

《黑神话悟空》开发框架与战斗系统解析
本文主要围绕《黑神话悟空》的开发框架与战斗系统解析展开 主要内容 《黑神话悟空》采用的技术栈 《黑神话悟空》战斗系统的实现方式 四种攻击模式 连招系统的创建 如何实现高扩展性的战斗系统 包括角色属性系统、技能配置文件和逻辑节点的抽象等关键技术点 版权声明 本…...

网络资源模板--Android Studio 通讯录App
目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 通讯录 二、项目测试环境 三、项目详情 首页 MainActivity 类是一个 Android 地址簿应用的核心部分,负责管理联系人列表的显示、搜索和添…...
Spring 出现 No qualifying bean of type ‘com.xxx‘ available 解决方法
目录 1. 问题所示2. 原理分析3. 解决方法4. 彩蛋4.1 bug彩蛋4.2 完整Demo4.3 补充Springboot1. 问题所示 出现如下问题: 19:58:23.476 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean o…...
C# 批量更改文件后缀名称
解决问题思路 解决固定文件夹下更改文件后缀名,采用轮询的方式, 流程如下: 获取当前文件名(带后缀的文件名)截取文件名称,去掉后缀另存为带更改后的后缀文件 注意:采用第三方插件࿰…...
KIC算法介绍及pyrosetta示例代码
Kinetic Loop Closure (KIC) 是 Rosetta 中一种重要的环区(loop region)建模算法,主要用于解决蛋白质中的柔性区域(特别是环区)的重构问题。环区是蛋白质中非常灵活的部分,通常结构不确定。KIC 算法采用基于运动学的解决方案,通过设置特定的几何约束,能够在给定的两端锚…...

【论文串烧】多媒体推荐中的模态平衡学习 | 音视频语音识别中丢失导致的模态偏差对丢失视频帧鲁棒性的影响
文章目录 一、多媒体推荐中的模态平衡学习1.1 研究背景1.2 解决问题1.3 实施方案1.4 文章摘要1.5 文章重点1.6 文章图示图 1:不同模型变体在 AmazonClothing 数据集上的初步研究图 2:CKD模型架构的说明图 3:在 Amazon-Clothing 数据集上训练过…...

【C语言二级考试】循环结构设计
C语言二级考试——循环结构程序设计 五.循环结构程序设计 1.for循环结构 2.while和do-while循环结构 3.continue语句和break语句 4.循环的嵌套 知识点参考【C语言】循环-CSDN博客 文章目录 1.for循环2.while和do-while循环结构3.continue语句和break语句4.循环的嵌套 1.for循环…...

诗文发布模板(python代码打造键盘录入诗文自动排版,MarkDown源码文本)
python最好用的f-string,少量代码打造键盘录入诗文自动排版。 (笔记模板由python脚本于2024年09月19日 19:11:50创建,本篇笔记适合喜欢写诗的pythoner的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free&am…...
GO主流开源框架
GO主流开源框架 Go 语言有着丰富的开源框架生态,涵盖了多种应用场景,如 Web 开发、数据库操作、微服务、日志处理等。以下是一些常见的 Go 框架及其典型作用场景: 1. Web 框架 Gin: 作用:一个高性能的轻量级 Web 框架ÿ…...
LeetCode:2398. 预算内的最多机器人数目 双指针+单调队列,时间复杂度O(n)
2398. 预算内的最多机器人数目 today 2398. 预算内的最多机器人数目 题目描述 你有 n 个机器人,给你两个下标从0开始的整数数组 chargeTimes 和 runningCosts ,两者长度都为 n 。第 i 个机器人充电时间为 chargeTimes[i] 单位时间,花费 ru…...

oracle 插入date日期类型的数据、插入从表中查出的数据,使用表中的默认数据
date sysdate to_date 插入从表中查出的数据 方式一 方式二 或者指定列名称 下边这个案例的前提是指定列插入,如果不指定,则也是默认的...

物流系统打单软件 佳易王物流运单怎么打印教程
一、前言 物流系统打单软件 佳易王物流运单怎么打印教程 1、佳易王物流管理系统可同时打印物流单和标签 2、如果一台电脑上有多台打印机,软件可以设置物流或标签对应的打印机,系统自动识别打印机。 二、软件程序图文说明 1、上图为 物流单在空白单上打…...
二叉树计算
题目描述 给出一个二叉树,请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。左子树表示该节点左侧叶子节点为根节点的一颗新树;右子树表示该节点右侧叶子节点为根节点的一颗新树。 输入描述 2行整数&#…...
Java并发执行举例
在Java中实现并发执行可以通过多种方式,最常见的方式包括使用线程、ExecutorService、ForkJoinPool等。以下是几种常用并发执行的示例: 1. 使用Thread类 这是Java中最基础的并发实现,通过创建一个继承自Thread的类或实现Runnable接口来定义…...
Java 基础知识九(网络编程)
UDP DatagramSocket:通讯的数据管道 -send 和receive方法 -(可选,多网卡)绑定一个IP和Port DatagramPacket -集装箱:封装数据 -地址标签:目的地IPPort package org.example.net;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.n…...
深入解析Go语言的类型方法、接口与反射
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 Go语言作为一门现代编程语言,以其简洁高效的特性受到广大开发者的喜爱。在本文中,我们将深入探讨Go语言中的类型方法、接口和反射机制。通过丰富的代码示例和详尽的解释,帮助您全面理解这些关键概念,并在实际…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...