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開發2D類銀河惡魔城游戲學習筆記目錄


文章目錄

  • Unity開發2D類銀河惡魔城游戲學習筆記
  • 前言
  • 一、概述
  • 二、預制件(Prefab)
    • (1)預制件介紹
    • (2)創建分身預制件
  • 三、分身技能的實現
    • (1)分身技能的創建
    • (2)分身技能的實現
    • (3)分身的消失與銷毀
    • (4)補充:將預制件Clone實例化到當前位置
  • 四、分身攻擊的實現
    • (1)攻擊動畫
    • (2)分身攻擊的實現
    • (2)分身攻擊的實現
  • 總結 完整代碼
    • 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勾掉就可以了。

在這里插入圖片描述
現在每次沖刺產生分身就是正常攻擊一次了。
在這里插入圖片描述

(2)分身攻擊的實現

最后一個需要解決的問題是分身面向現在是固定朝右的,我們需要再添加一個讓分身朝向最近敵人攻擊的功能。
在分身一定范圍內檢測敵人,比較后選取離分身最近的一個。如果它在分身左側,則翻轉分身讓它面向左側。

    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.pswp.cn/diannao/73637.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73637.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73637.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入解析Java面向對象三大特征之多態、final、抽象類與接口

面向對象編程&#xff08;OOP&#xff09;的三大核心特征為封裝、繼承、多態&#xff0c;其中多態是最具靈活性和擴展性的特性。本文將從多態的本質出發&#xff0c;結合final關鍵字、抽象類與接口的設計&#xff0c;深入探討這些概念的應用場景及其在代碼中的實現細節&#xf…

編碼器和解碼器概念及算法示例【清晰易懂】

編碼器&#xff08;Encoder&#xff09;和解碼器&#xff08;Decoder&#xff09;是處理信息的一對“搭檔”&#xff0c;它們的作用就像是“翻譯員”和“逆翻譯員”。 1. 編碼器&#xff08;Encoder&#xff09;是什么&#xff1f; &#x1f449; 把原始信息變成另一種形式&a…

爬蟲逆向:逆向中用到匯編語言詳細總結

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、匯編語言基礎二、常見匯編指令2.1 數據傳輸指令2.2 算術指令2.3 邏輯指令2.4 控制流指令2.5 其他指令三、寄存器概述四、調用約定五、棧操作與函數調用六、逆向工程中的匯編分析七、常用逆向工具八、實際案例分析九…

CTF WEB題

[文件包含,少許難度] 地址:攻防世界 代碼審計WRONG WAY! <?php include("flag.php"); #包含了一個“flag.php”文件 highlight_file(__FILE__); #來顯示當前文件的源代碼 if(isset($_GET["file1"]) && isset($_GET["file2"])) #isse…

c++圖論(一)之圖論的起源和圖的概念

C 圖論之圖論的起源和圖的概念 圖論&#xff08;Graph Theory&#xff09;是數學和計算機科學中的一個重要分支&#xff0c;其起源可以追溯到 18 世紀 的經典問題。以下是圖論的歷史背景、核心起源問題及其與基本概念和用途&#xff1a; 借用一下CSDN的圖片哈 一、圖論的起源&…

Ollama + CherryStudio:構建本地私有知識庫

前面我們介紹了Ollama的安裝和使用&#xff0c;并通過Open-WebUI進行調用&#xff0c;相信大家對Ollama也有了一定的了解&#xff1b;這篇博文就結合Ollama工具和CherryStudio工具構建一個本地知識庫&#xff08;RAG&#xff09;&#xff1b;在進行接下來的操作之前&#xff0c…

【實戰ES】實戰 Elasticsearch:快速上手與深度實踐-8.2.1AWS OpenSearch無服務器方案

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 8.2.1AWS OpenSearch 無服務器方案深度解析與實踐指南1. Serverless架構的核心價值與行業趨勢1.1 傳統Elasticsearch集群的運維挑戰1.2 Serverless技術演進路線技術特性對比…

清晰易懂的Java8安裝教程

小白也能看懂的 Java 8 安裝教程&#xff08;JDK 和 JRE 分目錄安裝&#xff09; 本教程將手把手教你如何在 Windows 系統上安裝 Java 8&#xff08;JDK 1.8&#xff09;&#xff0c;并將 JDK 和 JRE 安裝到不同的目錄中&#xff0c;同時提供國內 Java 8 下載源和方法。即使你…

圖搜索的兩種寫法,廣度優先和深度優先

最近AI的爆發大家都瘋了&#xff0c;也確實夠瘋&#xff0c;前幾年誰能天天和AI聊天呢&#xff0c;特別它越來越智能&#xff0c;越來越理解你&#xff0c;你越來越離不開它&#xff0c;我很好奇將來它會不會有情緒&#xff0c;太可怕了&#xff0c;一旦有了這個就有了感情&…

嵌入式八股RTOS與Linux---前言篇

前言 Linux與RTOS是校招八股的時候很喜歡考察的知識,在這里并沒有把兩個操作系統完全的獨立開去講,放在一起對比或許可能加深印象。我們講Linux的內核有五部分組成:進程調度、內存管理、文件系統、網絡接口、進程間通信,所以我也將從這五方面出發 中斷管理去對比和RTOS的不同。…

ChatBI 的技術演進與實踐挑戰:衡石科技如何通過 DeepSeek 實現商業落地

隨著人工智能技術的快速發展&#xff0c;ChatBI&#xff08;基于自然語言交互的商業智能&#xff09;逐漸成為企業數據分析領域的熱門話題。作為 BI&#xff08;商業智能&#xff09;領域的新形態&#xff0c;ChatBI 通過自然語言處理&#xff08;NLP&#xff09;技術&#xff…

基于Vue實現Echarts的平滑曲線

在Vue2.x的項目中使用echarts實現如下效果 安裝echarts npm install echarts --save組件引入echarts // 在你的Vue組件中 import * as echarts from echarts;在模板中添加一個div元素&#xff0c;用來放置圖表 <divref"chart"class"chart"style"…

關于重構分析查詢界面的思考(未完)

業務系統里&#xff0c;查詢界面很常見&#xff0c;數據分析場景需求普遍而迫切&#xff0c;而新的技術也在不斷出現&#xff0c;很有必要重構分析查詢界面。 查詢篩選 為了盡可能從數據中發現&#xff0c;需要盡可能地將查詢條件添加進來&#xff0c;可這樣&#xff0c;查詢…

在jQuery中DOM操作

&#xff08;一&#xff09;元素選取 各種選擇器的使用方法與示例 標簽選擇器&#xff1a;通過 HTML 標簽名稱來選取元素。例如&#xff0c;若想選中頁面中所有的段落元素&#xff0c;可使用$(‘p’)。假設我們有如下 HTML 結構&#xff1a; 這是第一個段落 這是嵌套在div中的…

Java 集合框架中 `List` 接口及其子類的詳細介紹,并用 UML 圖表展示層次結構關系,用表格對比各個類的差異。

下面是 Java 集合框架中 List 接口及其子類的詳細介紹&#xff0c;并用 UML 圖表展示層次結構關系。最后&#xff0c;我會用表格對比各個類的差異。 Java 集合框架中 List 接口及其子類 UML 類圖描述 以下是 List 接口及其子類的 UML 類圖描述&#xff0c;不包含方法。 詳細…

Java面試八股—Redis篇

一、Redis的使用場景 &#xff08;一&#xff09;緩存 1.Redis使用場景緩存 場景&#xff1a;緩存熱點數據&#xff08;如用戶信息、商品詳情&#xff09;&#xff0c;減少數據庫訪問壓力&#xff0c;提升響應速度。 2.緩存穿透 正常的訪問是&#xff1a;根據ID查詢文章&…

Spring Boot使用線程池創建多線程

在 Spring Boot 2 中&#xff0c;可以使用 Autowired 注入 線程池&#xff08;ThreadPoolTaskExecutor 或 ExecutorService&#xff09;&#xff0c;從而管理線程的創建和執行。以下是使用 Autowired 方式注入線程池的完整示例。 1. 通過 Autowired 注入 ThreadPoolTaskExecuto…

9、交付手段-強化肌肉記憶(隨身工具箱)

一、交付工具箱 當臨時遇到各類交付棘手問題時&#xff0c;大腦里記住交付工具的使用場景&#xff0c;有利于快速決策&#xff0c;將這些工具轉為肌肉記憶&#xff0c;能夠快速靈活處理交付中的各類問題&#xff0c;蛻變為交付之星 1、復雜項目&#xff1a;WBS分解、日站會、…

【概念】Node.js,Express.js MongoDB Mongoose Express-Validator Async Handler

1. Node.js 定義&#xff1a;Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行時環境&#xff0c;允許你在服務器端運行 JavaScript 代碼。作用&#xff1a;它使得開發者可以使用 JavaScript 編寫服務器端代碼&#xff0c;從而實現前后端使用同一種語言。比喻&#xff1a…

【GPT入門】第22課 langchain LCEL介紹

【GPT入門】第22課 langchain LCEL介紹 1. LCEL介紹與特點2. 原生API與LCEL的對比2. 簡單demo 1. LCEL介紹與特點 LCEL 即 LangChain Expression Language&#xff0c;是 LangChain 推出的一種聲明式語言&#xff0c;用于簡化和優化在 LangChain 框架內構建復雜鏈和應用的過程…