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教程(十八)战斗系统 攻击逻辑
Unity教程(十九)战斗系统 受击反馈
Unity教程(二十)战斗系统 角色反击

Unity教程(二十一)技能系统 基础部分
Unity教程(二十二)技能系统 分身技能
Unity教程(二十三)技能系统 投掷技能


如果你更习惯用知乎
Unity开发2D类银河恶魔城游戏学习笔记目录


文章目录

  • Unity开发2D类银河恶魔城游戏学习笔记
  • 前言
  • 一、概述
  • 二、预制件(Prefab)
    • (1)预制件介绍
    • (2)创建分身预制件
  • 三、分身技能的实现
    • (1)分身技能的创建
    • (2)分身技能的实现
    • (3)分身的消失与销毁
    • (4)补充:将预制件Clone实例化到当前位置
  • 四、分身攻击的实现
    • (1)攻击动画
    • (2)分身攻击的实现
    • (3)分身攻击方向
  • 总结 完整代码
    • PlayerDashState.cs
    • Clone_Skill.cs
    • Clone_Skill_Controller.cs
    • SkillManager.cs
    • Player.cs


前言

本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记,如有错误,欢迎指正。

本节实现角色分身技能。

Udemy课程地址

对应视频:
Clone Creating Ability
Clone’s Attack


一、概述

本节实现分身技能。
实现解锁技能后,在角色冲刺时产生一个分身,分身会攻击距离最近的一个敌人。
在这里插入图片描述

二、预制件(Prefab)

(1)预制件介绍

Unity的预制件相当于创建一个模板,使得游戏对象作为可重用资源。可以用这个模板在场景中创建新的预制件实例。
详细内容可见Unity官方手册预制件

首先是预制件的创建。
预制件的创建很简单,将一个游戏对象从 Hierarchy 窗口拖入 Project 窗口就可以了。
在这里插入图片描述


预制件的实例化。
最简单的是将预制件资源从 Project 视图拖动到 Hierarchy 或 Scene 视图,创建实例。
在这里插入图片描述

也可通过脚本进行实例化。使用Object的Instantiate函数。


Object Instantiate (Object original);Object Instantiate (Object original, Transform parent);Object Instantiate (Object original, Transform parent, bool instantiateInWorldSpace);Object Instantiate (Object original, Vector3 position, Quaternion rotation);Object Instantiate (Object original, Vector3 position, Quaternion rotation, Transform parent);

参数含义如下表:

参数含义
original要复制的现有对象(如预制件)
position新对象的位置
rotation新对象的方向
parent将指定给新对象的父对象
instantiateInWorldSpace分配父对象时,传递 true 可直接在世界空间中定位新对象。
传递 false 可相对于其新父项来设置对象的位置。

预制件的编辑。 可以在预制件模式下编辑预制件。这种情况可以单独或在上下文中编辑预制件资源。

在这里插入图片描述

在这里插入图片描述
也可以在实例中编辑后覆盖预制体。使用Overrides应用和还原覆盖。

在这里插入图片描述

(2)创建分身预制件

将玩家精灵表第一帧拖入层次面板中并重命名为Clone。

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

创建动画控制器Clone_AC

在这里插入图片描述
将Clone_AC挂载到Clone下面

在这里插入图片描述
这时我们发现Clone的图像被遮挡了。

在这里插入图片描述
调整SpriteRenderer中的层次顺序,使Clone位于敌人之前,玩家之后。

在这里插入图片描述
给Clone添加动画,这里我们不需要重新建立动画,只需要把原来Player的动画复用。
打开Clone的Aniamtor面板,将PlayerIdle拖入作为默认状态,再拖入PlayerAttack1、PlayerAttack2、PlayerAttack3。

在这里插入图片描述
创建Prefabs文件夹存放预制件。

在这里插入图片描述
将层次面板中的Clone拖入文件夹,预制件创建完成。

在这里插入图片描述
把层次面板中的Clone删除,后续我们用到它时会在脚本中创建。

三、分身技能的实现

分身技能Clone_Skill继承自Skill基类。我们要实现按下冲刺键后,在玩家冲刺的位置创建一个分身,因此我们需要在PlayerDashState开始时传入Player的位置创建分身。

实现时还要创建一个分身技能的控制器Clone_Skill_Controller,将它挂载到Clone预制件下,控制分身的位置。这里让人容易疑惑,为什么要大费周章再创建一个控制器脚本。个人理解,更多是因为马上要实现的分身攻击,攻击时需要触发动画事件,因此必须有个脚本挂在Clone预制体下面。这里就把控制分身位置的功能也写进去了。

此外,还可在实例化时就指定分身位置,这种形式也会在下面写一下。

(1)分身技能的创建

在Scripts文件夹中创建Skills文件夹存放技能相关脚本。
在这里插入图片描述
创建分身技能脚本Clone_Skill,它继承自Skill基类,将它挂到技能管理器下。

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

在技能管理器脚本中创建分身技能并赋值。

    public Clone_Skill clone { get; private set; }private void Start(){dash = GetComponent<Dash_Skill>();clone = GetComponent<Clone_Skill>();}

(2)分身技能的实现

创建分身技能控制器Clone_Skill_Controller,创建函数SetupClone设置分身信息。
在这里插入图片描述
双击预制件Clone,在面板中点击Add Component添加组件。
注意:脚本是添加在预制件上的。

在这里插入图片描述

在Clone_Skill_Controller中添加设置分身信息的函数。

//Clone_Skill_Controller:分身技能控制器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Clone_Skill_Controller : MonoBehaviour
{//设置分身信息public void SetupClone(Transform _newTransform){transform.position = _newTransform.position;}
}

在Clone_Skill脚本中添加实例化预制体的函数,并调用SetupClone设置分身信息。
//Clone_Skill:分身技能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Clone_Skill : Skill
{[SerializeField] private GameObject clonePerfab;public void CreateClone(Transform _clonePosition){GameObject newClone = Instantiate(clonePerfab);newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition);}
}

为预制体赋值
在这里插入图片描述


在Player中创建SkillManager方便管理。
    public SkillManager skill;// 设置初始状态protected override void Start(){base.Start();skill = SkillManager.instance;StateMachine.Initialize(idleState);}

接着在PlayerDashState的中调用CreateClone,使得冲刺后在玩家位置创建一个分身。

    //进入状态public override void Enter(){base.Enter();player.skill.clone.CreateClone(player.transform);//设置冲刺持续时间stateTimer = player.dashDuration;}

效果如下:
在这里插入图片描述

基本功能已经实现,但有个很明显的问题,创建的分身没有回收。

(3)分身的消失与销毁

此技能需要让分身持续一段时间后逐渐消失,可以使clone预制件的图像随时间透明度逐渐降低实现,最后透明度降到0时销毁分身。这需要用到计时器,而且要设置分身持续的时长和消失的速度。

我们把经常需要变动修改的变量放在CloneSkill中方便管理,这里将分身持续时长cloneDuration放在里面。

public class Clone_Skill : Skill
{[Header("Clone Info")][SerializeField] private GameObject clonePerfab;[SerializeField] private float cloneDuration;public void CreateClone(Transform _clonePosition){GameObject newClone = Instantiate(clonePerfab);newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition, cloneDuration);}
}

在Clone_Skill_Controller中设置计时器,实现图像透明度递减,并在透明度为0时销毁对象。
public class Clone_Skill_Controller : MonoBehaviour
{private SpriteRenderer sr;[SerializeField] private float colorLosingSpeed;private float cloneTimer;private void Awake(){sr = GetComponent<SpriteRenderer>();}private void Update(){cloneTimer -= Time.deltaTime;if(cloneTimer < 0){sr.color = new Color(1, 1, 1, sr.color.a - Time.deltaTime * colorLosingSpeed);if (sr.color.a <= 0)Destroy(gameObject);}}//设置分身信息public void SetupClone(Transform _newTransform, float _cloneDuration){transform.position = _newTransform.position;cloneTimer = _cloneDuration;}
}

设置合适的技能持续时间和消失速度
在这里插入图片描述
在这里插入图片描述
效果如下:
在这里插入图片描述

(4)补充:将预制件Clone实例化到当前位置

只需在实例化时直接传入位置参数即可,其他函数要随着做一些更改。
在Clone_Skill中

    public void CreateClone(Transform _clonePosition){GameObject newClone = Instantiate(clonePerfab,_clonePosition);newClone.GetComponent<Clone_Skill_Controller>().SetupClone(cloneDuration);}

在Clone_Skill_Controller中

    //设置分身信息public void SetupClone(float _cloneDuration){cloneTimer = _cloneDuration;}

四、分身攻击的实现

(1)攻击动画

进入预制件Clone的编辑,在Animator中创建空状态用于空闲和攻击状态过渡。创建Int型变量AttackNumber用于确定攻击段数。
在这里插入图片描述
连接playerIdle与Empty状态,当AttackNumber>0时,进入Empty。
PlayerIdle->Empty, 加条件变量并更改设置

在这里插入图片描述
分别连接Empty和三个攻击状态,在AttackNumber等于1时进入playerAttack1,同理等于2、3时分别进入其他两个状态
在这里插入图片描述

(2)分身攻击的实现

在技能树中分身攻击技能解锁后才可使用,这里我们先实现功能部分,所以先在Clone_Skill中添加一个变量canAttack用于测试。

public class Clone_Skill : Skill
{[Header("Clone Info")][SerializeField] private GameObject clonePerfab;[SerializeField] private float cloneDuration;[Space][SerializeField] private bool canAttack;public void CreateClone(Transform _clonePosition){GameObject newClone = Instantiate(clonePerfab);newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition, cloneDuration,canAttack);}
}

当解锁分身攻击技能时,在Clone_Skill_Controller中实现分身攻击的设置。

设置Animator中的条件变量AttackNumber为1-3中随机一个数,播放相应攻击动画。
注意:在Unity中Random.Range(a, b) 生成的是 [ a, b ) 区间内的整数。

private Animator anim;private void Awake(){sr = GetComponent<SpriteRenderer>();anim = GetComponent<Animator>();}//设置分身信息public void SetupClone(Transform _newTransform, float _cloneDuration, bool _canAttack){if (_canAttack)anim.SetInteger("AttackNumber", Random.Range(1, 4));transform.position = _newTransform.position;cloneTimer = _cloneDuration;}

效果如下:
在这里插入图片描述

现在分身攻击是连续不断地没有结束攻击的部分,我们可以复用攻击动画以前的事件实现。
在这里插入图片描述
参照PlayerAnimationTriggers里函数的写法,在Clone_Skill_Controller中添加AnimationTrigger和AttackTrigger两个函数,分别用于结束攻击和触发攻击效果。
AnimatonTrigger会将计时器设置为小于0的数,相当于分身技能持续时间直接结束,开始逐渐消失。
AttackTrigger与玩家攻击的实现逻辑一样,检查攻击范围内的敌人,造成伤害效果。
添加如下代码:

    [SerializeField] private Transform attackCheck;[SerializeField] private float attackCheckRadius = 0.8f;private void AnimationTrigger(){cloneTimer = -0.1f;}private void AttackTrigger(){Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCheck.position, attackCheckRadius);foreach (var hit in colliders){if (hit.GetComponent<Enemy>() != null)hit.GetComponent<Enemy>().Damage();}}

在Clone下创建一个空物体并重命名为attackCheck,将它移动到分身前方合适的位置。然后用它为变量attackCheck赋值。
进行修改时可以在预制体的编辑里,也可以将预制体拖到场景中修改完再覆盖原来的预制体。
在这里插入图片描述
在这里插入图片描述
做完这些你会发现分身可以攻击敌人了,但攻击还是接连不断。
在这里插入图片描述
因为这次在Animator中没有将PlayerAttack连到Exit状态,没有退出,所以动画会循环播放。
将三个攻击动画的lLoop Time勾掉就可以了。

在这里插入图片描述
现在每次冲刺产生分身就是正常攻击一次了。
在这里插入图片描述

(3)分身攻击方向

最后一个需要解决的问题是分身面向现在是固定朝右的,我们需要再添加一个让分身朝向最近敌人攻击的功能。
在分身一定范围内检测敌人,比较后选取离分身最近的一个。如果它在分身左侧,则翻转分身让它面向左侧。

    private Transform closestEnemy;//设置分身信息public void SetupClone(Transform _newTransform, float _cloneDuration, bool _canAttack){if (_canAttack)anim.SetInteger("AttackNumber", Random.Range(1, 4));transform.position = _newTransform.position;cloneTimer = _cloneDuration;FaceClosestTarget();}private void FaceClosestTarget(){Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 25);float closestDistace = Mathf.Infinity;foreach(var hit in colliders){if (hit.GetComponent<Enemy>() != null){float distanceToEnemy = Vector2.Distance(transform.position, hit.transform.position);if (distanceToEnemy < closestDistace){closestDistace = distanceToEnemy;closestEnemy = hit.transform;}}}if(closestEnemy != null){if (closestEnemy.position.x < transform.position.x)transform.Rotate(0, 180, 0);}}

效果如下:

在这里插入图片描述

总结 完整代码

PlayerDashState.cs

添加分身的创建。

//PlayerDashState:冲刺状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerDashState : PlayerState
{//构造函数public PlayerDashState(PlayerStateMachine _stateMachine, Player _player, string _animBoolName) : base(_stateMachine, _player, _animBoolName){}//进入状态public override void Enter(){base.Enter();player.skill.clone.CreateClone(player.transform);//设置冲刺持续时间stateTimer = player.dashDuration;}//退出状态public override void Exit(){base.Exit();}//更新public override void Update(){base.Update();//切换滑墙状态if(!player.isGroundDetected() && player.isWallDetected()) stateMachine.ChangeState(player.wallSlideState);//设置冲刺速度player.SetVelocity(player.dashDir * player.dashSpeed, 0);//切换到空闲状态if (stateTimer < 0)stateMachine.ChangeState(player.idleState);}
}

Clone_Skill.cs

创建分身,添加经常需要在面板上更改的相关变量。

//Clone_Skill:分身技能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Clone_Skill : Skill
{[Header("Clone Info")][SerializeField] private GameObject clonePerfab;[SerializeField] private float cloneDuration;[Space][SerializeField] private bool canAttack;public void CreateClone(Transform _clonePosition){GameObject newClone = Instantiate(clonePerfab);newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition, cloneDuration,canAttack);}
}

Clone_Skill_Controller.cs

设置分身信息,实现分身逐渐消失,实现分身攻击,将分身改为面向最近的敌人。

//Clone_Skill_Controller:分身技能控制器
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;public class Clone_Skill_Controller : MonoBehaviour
{private SpriteRenderer sr;private Animator anim;[SerializeField] private float colorLosingSpeed;private float cloneTimer;[SerializeField] private Transform attackCheck;[SerializeField] private float attackCheckRadius = 0.8f;private Transform closestEnemy;private void Awake(){sr = GetComponent<SpriteRenderer>();anim = GetComponent<Animator>();}private void Update(){cloneTimer -= Time.deltaTime;if(cloneTimer < 0){sr.color = new Color(1, 1, 1, sr.color.a - Time.deltaTime * colorLosingSpeed);if (sr.color.a <= 0)Destroy(gameObject);}}//设置分身信息public void SetupClone(Transform _newTransform, float _cloneDuration, bool _canAttack){if (_canAttack)anim.SetInteger("AttackNumber", Random.Range(1, 4));transform.position = _newTransform.position;cloneTimer = _cloneDuration;FaceClosestTarget();}private void AnimationTrigger(){cloneTimer = -0.1f;}private void AttackTrigger(){Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCheck.position, attackCheckRadius);foreach (var hit in colliders){if (hit.GetComponent<Enemy>() != null)hit.GetComponent<Enemy>().Damage();}}private void FaceClosestTarget(){Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 25);float closestDistance = Mathf.Infinity;foreach(var hit in colliders){if (hit.GetComponent<Enemy>() != null){float distanceToEnemy = Vector2.Distance(transform.position, hit.transform.position);if (distanceToEnemy < closestDistance){closestDistance = distanceToEnemy;closestEnemy = hit.transform;}}}if(closestEnemy != null){if (closestEnemy.position.x < transform.position.x)transform.Rotate(0, 180, 0);}}
}

SkillManager.cs

创建分身技能。

//SkillManager:玩家管理器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkillManager : MonoBehaviour
{public static SkillManager instance;public Dash_Skill dash { get; private set; }public Clone_Skill clone { get; private set; }private void Awake(){if (instance != null && instance != this){Destroy(this.gameObject);}else{instance = this;}}private void Start(){dash = GetComponent<Dash_Skill>();clone = GetComponent<Clone_Skill>();}
}

Player.cs

创建并初始化技能管理器。

//Player:玩家
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : Entity
{[Header("Attack details")]public Vector2[] attackMovement;public float counterAttackDuration = 0.2f;public bool isBusy { get; private set; }[Header("Move Info")]public float moveSpeed = 8f;public float jumpForce = 12f;[Header("Dash Info")]public float dashSpeed=25f;public float dashDuration=0.2f;public float dashDir { get; private set; }public SkillManager skill;#region 状态public PlayerStateMachine StateMachine { get; private set; }public PlayerIdleState idleState { get; private set; }public PlayerMoveState moveState { get; private set; }public PlayerJumpState jumpState { get; private set; }public PlayerAirState airState { get; private set; }public PlayerDashState dashState { get; private set; }public PlayerWallSlideState wallSlideState { get; private set; }public PlayerWallJumpState wallJumpState { get; private set; }public PlayerPrimaryAttackState primaryAttack { get; private set; }public PlayerCounterAttackState counterAttack { get; private set; }#endregion//创建对象protected override void Awake(){base.Awake();StateMachine = new PlayerStateMachine();idleState = new PlayerIdleState(StateMachine, this, "Idle");moveState = new PlayerMoveState(StateMachine, this, "Move");jumpState = new PlayerJumpState(StateMachine, this, "Jump");airState = new PlayerAirState(StateMachine, this, "Jump");dashState = new PlayerDashState(StateMachine, this, "Dash");wallSlideState = new PlayerWallSlideState(StateMachine, this, "WallSlide");wallJumpState = new PlayerWallJumpState(StateMachine, this, "Jump");primaryAttack = new PlayerPrimaryAttackState(StateMachine, this, "Attack");counterAttack = new PlayerCounterAttackState(StateMachine, this, "CounterAttack");}// 设置初始状态protected override void Start(){base.Start();skill = SkillManager.instance;StateMachine.Initialize(idleState);}// 更新protected override void Update(){base.Update();StateMachine.currentState.Update();CheckForDashInput();}public IEnumerator BusyFor(float _seconds){isBusy = true;yield return new WaitForSeconds(_seconds);isBusy = false;}//设置触发器public void AnimationTrigger() => StateMachine.currentState.AnimationFinishTrigger();//检查冲刺输入public void CheckForDashInput(){if (Input.GetKeyDown(KeyCode.LeftShift) && SkillManager.instance.dash.CanUseSkill()){dashDir = Input.GetAxisRaw("Horizontal");if (dashDir == 0)dashDir = facingDir;StateMachine.ChangeState(dashState);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37152.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

麒麟银河V10服务器RabbitMQ安装

安装步骤 rabbitMQ依赖于erlang的环境&#xff0c;所以需要先安装erlang&#xff0c;erlang跟rabbitMQ是有版本之间的关联关系的&#xff0c;根据对应的版本去安装下载&#xff0c;保证少出问题。 可以通过官网来查看RabbitMQ和erlang之间的版本对应关系 rabbitMQ和erlang之间…

让“树和二叉树”埋在记忆土壤中--性质和概念

Nice to meet your! 目录 树的介绍&#xff1a; 树的创建&#xff1a; 二叉树的概念和结构&#xff1a; 二叉树的存储结构&#xff1a; 树的介绍&#xff1a; 概念和结构&#xff1a; 不知你们是否在现实中看见过分为两个叉的枯树&#xff0c;大概长这样&#xff1a; 那…

UDP协议原理

UDP协议原理 本篇介绍 在前面使用UDP编程时已经基本了解了UDP的工作模式&#xff0c;也知道了UDP有三个特点&#xff1a; 无连接不可靠面向数据报 但是当时并没有具体谈论为什么UDP有以上三个特点&#xff0c;基于这个原因&#xff0c;本篇就会针对这三个原因进行介绍 UDP…

关于金融开发领域的一些专业知识总结

目录 1. 交易生命周期 1.1 证券交易所 1.1.1 交易前 1) 订单生成&#xff08;Order Generation&#xff09; 2) 订单管理&#xff08;Order Management&#xff09; 1.1.2 交易执行 3) 交易匹配&#xff08;Trade Matching&#xff09; 1.1.3 交易后 4) 交易确认&…

Flutter运行错误:UG! exception in phase ‘semantic analysis‘

最近在Mac Mini M4上通过Android Studio导入Flutter项目并运行&#xff0c;结果一直跑不起来&#xff0c;错误日志如下&#xff1a; 执行命令查看版本信息&#xff1a; flutter doctor --verbose通过输出信息Java version OpenJDK Runtime Environment (build 21.0.41242208…

DeepSeek + Kimi 自动生成 PPT

可以先用deepseek生成ppt大纲&#xff0c;再把这个大纲复制到Kimi的ppt助手里&#xff1a; https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 选择ppt模板&#xff1a; 点击生成ppt就制作好了。

【C#语言】C#中的同步与异步编程:原理、示例与最佳实践

文章目录 ⭐前言⭐一、同步编程&#xff1a;简单但低效的线性执行&#x1f31f;代码示例&#x1f31f;执行流程示意图&#x1f31f;同步编程特点 ⭐二、异步编程&#xff1a;非阻塞的高效执行&#x1f31f;代码示例&#x1f31f;执行流程示意图&#x1f31f;异步编程核心机制&a…

【MySQL数据库】存储过程与自定义函数(含: SQL变量、分支语句、循环语句 和 游标、异常处理 等内容)

存储过程&#xff1a;一组预编译的SQL语句和流程控制语句&#xff0c;被命名并存储在数据库中。存储过程可以用来封装复杂的数据库操作逻辑&#xff0c;并在需要时进行调用。 类似的操作还有&#xff1a;自定义函数、.sql文件导入。 我们先从熟悉的函数开始说起&#xff1a; …

【sgFloatDialog】自定义组件:浮动弹窗,支持修改尺寸、拖拽位置、最大化、还原、最小化、复位

sgFloatDialog <template><div :class"$options.name" v-if"visible" :theme"theme" :size"size" :style"style"><!-- 托盘头部 --><div class"header" ref"header" dblclick.s…

Java后端开发技术详解

Java作为一门成熟的编程语言&#xff0c;已广泛应用于后端开发领域。其强大的生态系统和广泛的支持库使得Java成为许多企业和开发者的首选后端开发语言。随着云计算、微服务架构和大数据技术的兴起&#xff0c;Java后端开发的技术栈也不断演进。本文将详细介绍Java后端开发的核…

搭建ISCSI传输的配置与管理

前提是&#xff1a; windows server2019设置成桥接模式&#xff0c;因为要让虚拟机和主机设置成一个网段&#xff0c;才能通过网络进行新建虚拟磁盘。 1.添加ISCSI角色 安装位置 选择文件和存储服务----------文件和iscsl 服务------------iscsl目标服务器 2.右上角点击任务&a…

晶艺代理,100V3.5A高耐压LA1823完全替换MP9487--启烨科技有限公司

晶艺品牌LA1823是异步降压转换器&#xff0c;COT控制&#xff0c;PFM工作模式, 150KHz/ 250KHz/ 450KHz &#xff0c;开关频率可调节&#xff0c;输入电压4.5~100V&#xff0c;2A平均电流&#xff0c;峰值电流3.5A&#xff0c;采用ESOP8封装。 晶艺LA1823的特性&#xff1a; 4.…

2024年消费者权益数据分析

&#x1f4c5; 2024年315消费者权益数据分析 数据见&#xff1a;https://mp.weixin.qq.com/s/eV5GoionxhGpw7PunhOVnQ 一、引言 在数字化时代&#xff0c;消费者维权数据对于市场监管、商家诚信和行业发展具有重要价值。本文基于 2024年315平台线上投诉数据&#xff0c;采用数…

jmeter吞吐量控制器-Throughput Controller

jmeter吞吐量控制器-Throughput Controller 新增吞吐量控制器名词解释测试场景场景1&#xff1a;场景2&#xff1a;场景3场景4场景5场景6场景7场景8 测试结论 根据百分比执行不同的接口测试场景测试结果 新增吞吐量控制器 名词解释 Based on: Total Executions(总执行数)/Perc…

微服务》》Kubernetes (K8S) 集群配置网络》》Calico

嘻嘻嘻 以Calico 为例子 Calico官网 官网上有安装Calico插件的步骤 步骤 要在主节点 主节点 主节点 执行 kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/tigera-operator.yaml kubectl create -f https://raw.githubuse…

蓝桥杯关于栈这个数据结构的一个算法题目

文章目录 1.题目概述解释2.思路分析3.代码解析 1.题目概述解释 找出来这个字符串里面重复出现的字符&#xff0c;类似于这个消消乐的游戏&#xff1b; 示例一里面的这个bb是连续的并且是一样的这个字符&#xff0c;因此删除bb&#xff0c;删除之后发现这个aa有一次相邻了&…

打破煤矿通信屏障,无线系统赋能生产安全与智能进阶

项目背景 在煤矿行业智能化转型的浪潮中&#xff0c;七台河矿业局积极回应国家煤矿智能化建设的号召&#xff0c;采取了具有前瞻性的战略举措——在七台河地区的煤矿部署了“井上井下”无线覆盖与广播一体化系统。此举旨在消除井上与井下之间的通信障碍&#xff0c;加强矿业局与…

基于CNN的FashionMNIST数据集识别4——GoogleNet模型

源码 import torch from torch import nn from torchsummary import summaryclass Inception(nn.Module):def __init__(self, in_channels, c1, c2, c3, c4):super().__init__()self.ReLu nn.ReLU()#路径1self.p1_1 nn.Conv2d(in_channelsin_channels, out_channelsc1, kern…

面试题精选《剑指Offer》:JVM类加载机制与Spring设计哲学深度剖析-大厂必考

一、JVM类加载核心机制 &#x1f525; 问题5&#xff1a;类从编译到执行的全链路过程 完整生命周期流程图 关键技术拆解 编译阶段 查看字节码指令&#xff1a;javap -v Robot.class 常量池结构解析&#xff08;CONSTANT_Class_info等&#xff09; 类加载阶段 // 手动加载…

(2025|ICLR|华南理工,任务对齐,缓解灾难性遗忘,底层模型冻结和训练早停)语言模型持续学习中的虚假遗忘

Spurious Forgetting in Continual Learning of Language Models 目录 1. 引言 2. 动机&#xff1a;关于虚假遗忘的初步实验 3. 深入探讨虚假遗忘 3.1 受控实验设置 3.2 从性能角度分析 3.3 从损失景观角度分析 3.4 从模型权重角度分析 3.5 从特征角度分析 3.6 结论 …