Unity类银河战士恶魔城学习总结(P124 CharacterStats UI玩家的UI)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节实现了玩家属性栏,仓库,物品栏UI的制作
UI_StatSlot.cs
这个脚本是用来在Unity的UI上显示玩家属性(比如生命值或攻击力)的。
- 显示状态名称:
statName
用来存储属性名称,比如"Health"。在编辑器中修改这个名字时,它会自动显示在对应的UI文本框里。 - 显示状态值:
statValueText
是用来显示这个属性的数值(比如100生命值)。 - 初始化UI:
Start
方法会在游戏开始时更新UI,确保显示玩家的正确状态。 - 动态更新:
UpdateStatValueUI
方法可以随时调用,更新UI上显示的数值。它会通过PlayerManager
找到玩家的属性,然后把这个值显示在UI上。
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;public class UI_StatSlot : MonoBehaviour
{[SerializeField] private string statName;[SerializeField] private StatType statType;[SerializeField] private TextMeshProUGUI statValueText;[SerializeField] private TextMeshProUGUI statNameText;private void OnValidate(){gameObject.name = "Stat - "+ statName;if(statNameText != null)statNameText.text = statName;}void Start(){UpdateStatValueUI();}public void UpdateStatValueUI(){PlayerStats playerStats = PlayerManager.instance.player.GetComponent<PlayerStats>();if(playerStats !=null){statValueText.text = playerStats.GetStat(statType).GetValue().ToString();}}
}
CharacterStats.cs
把状态类型移动到这个脚本
using System.Collections;
using UnityEngine;public enum StatType//枚举 StatType 的定义
{strength,agility,intelligence,vitality,damage,critChance,critPower,health,armor,evasion,magicRes,fireDamage,iceDamage,lightingDamage
}//10月25日
//10月26日
public class CharacterStats : MonoBehaviour
{private EntityFX fx;[Header("主属性")]public Stat strength;//力量,1点增加1攻击力和%1爆伤public Stat agility;//敏捷,1点增加1%闪避和%1暴击率public Stat intelligence;//智力,1点增加1法术强度和%1魔抗public Stat vitality;//活力,1点增加3生命值[Header("攻击属性")]//offensive statspublic Stat damage;public Stat critChance;//暴击率public Stat critPower;//暴击伤害,默认%150[Header("防守属性")]//defensive statspublic Stat maxHealth;public Stat armor;//护甲public Stat evasion;//闪避public Stat magicResistance;//魔抗[Header("魔法属性")]//magic statspublic Stat fireDamage;public Stat iceDamage;public Stat lightningDamage;public bool isIgnited;//是否燃烧,持续伤害public bool isChilled;//是否冻结,削弱护甲20%public bool isShocked;//是否感电,减少命中率20%[SerializeField] private float ailmentsDuration = 4;//异常状态持续时间private float ignitedTimer;private float chilledTimer;private float shockedTimer;private float igniteDamageCoolDown = .3f;//燃烧伤害间隔时间private float igniteDamageTimer;//燃烧伤害计时器private int igniteDamage;//燃烧伤害[SerializeField] private GameObject shockStrikePrefab;private int shockDamage;public int currentHealth;public System.Action onHealthChanged;public bool isDead { get; private set; }protected virtual void Start(){critPower.SetDefaultValue(150);//暴击伤害默认150%currentHealth = GetMaxHealthValue();//一开始血条满的fx = GetComponent<EntityFX>();}protected virtual void Update(){ignitedTimer -= Time.deltaTime;//燃烧时间减少chilledTimer -= Time.deltaTime;shockedTimer -= Time.deltaTime;igniteDamageTimer -= Time.deltaTime;//燃烧伤害计时器减少if (ignitedTimer < 0)isIgnited = false;if (chilledTimer < 0)isChilled = false;if (shockedTimer < 0)isShocked = false;if (isIgnited)ApplyIgniteDamage();}public virtual void IncreaseStatBy(int _modifier, float _duration, Stat _statToModify){StartCoroutine(StatModCoruntine(_modifier, _duration, _statToModify));}private IEnumerator StatModCoruntine(int _modifier, float _duration, Stat _statToModify)//加buff的协程{_statToModify.AddModifier(_modifier);//添加一个buffyield return new WaitForSeconds(_duration);_statToModify.RemoveModifier(_modifier);//移除一个buff}public virtual void DoDamage(CharacterStats _targetStats)//只是一次物理攻击{if (TargetCanAvoidAttack(_targetStats))return;int totalDamage = damage.GetValue() + strength.GetValue();if (Cancrit()){//Debug.Log("Crit Hit");totalDamage = CalculateCriticalDamage(totalDamage);//Debug.Log(" 总的暴击伤害是"+ totalDamage);//Total crit damage is}totalDamage = CheckTargetArmor(_targetStats, totalDamage);_targetStats.TakeDamage(totalDamage);//把造成的给到继承CharacterStats的类DoMagicDamage(_targetStats);//如果普通攻击不想要魔法伤害移除}#region Magic Damage and ailmentspublic virtual void DoMagicDamage(CharacterStats _targetStats)//只是一次魔法攻击{int _fireDamage = fireDamage.GetValue();int _iceDamage = iceDamage.GetValue();int _lightningDamage = lightningDamage.GetValue();int totalMagicalDamage = _fireDamage + _iceDamage + _lightningDamage + intelligence.GetValue();totalMagicalDamage = CheckTargetResistance(_targetStats, totalMagicalDamage);_targetStats.TakeDamage(totalMagicalDamage);//把造成的给到继承CharacterStats的类//importantif (Mathf.Max(_fireDamage, _iceDamage, _lightningDamage) <= 0)//可以保证下面的while循环不会无限循环return;AttempToApplyAilements(_targetStats, _fireDamage, _iceDamage, _lightningDamage);}private void AttempToApplyAilements(CharacterStats _targetStats, int _fireDamage, int _iceDamage, int _lightningDamage){//判断魔法伤害类型bool canApplyIgnite = _fireDamage > _iceDamage && _fireDamage > _lightningDamage;bool canApplyChill = _iceDamage > _fireDamage && _iceDamage > _lightningDamage;bool canApplyShock = _lightningDamage > _fireDamage && _lightningDamage > _iceDamage;while (!canApplyIgnite && !canApplyChill && !canApplyShock){//三个if同时判断大小,可以完成一个随机属性伤害的bossif (Random.value < .33f && _fireDamage > 0)//Random.value用于生成一个介于 0.0 和 1.0 之间的随机浮点数{canApplyIgnite = true;_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);//Debug.Log("ignited" );return;}if (Random.value < .5f && _lightningDamage > 0){canApplyShock = true;_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);//Debug.Log("shocked" );return;}if (Random.value < .99f && _iceDamage > 0){canApplyChill = true;_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);//Debug.Log("iced" );return;}}if (canApplyIgnite){_targetStats.SetupIgniteDamage(Mathf.RoundToInt(_fireDamage * .2f));}if (canApplyShock){_targetStats.SetupShockDamage(Mathf.RoundToInt(_lightningDamage * .1f));}_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);}public void ApplyAilments(bool _ignite, bool _chill, bool _shock)//应用异常状态{bool canApplyIgnite = !isIgnited && !isChilled && !isShocked;bool canApplyChill = !isIgnited && !isChilled && !isShocked;bool canApplyShock = !isIgnited && !isChilled;//没有其他异常状态才能进入一个异常状态//if (isIgnited || isChilled || isShocked)//如果进入一个异常状态就不能进入其他状态了// return;if (_ignite && canApplyIgnite){isIgnited = _ignite;ignitedTimer = ailmentsDuration;fx.IgniteFxFor(ailmentsDuration);}if (_chill && canApplyChill){isChilled = _chill;chilledTimer = ailmentsDuration;float slowPercentage = .2f;//减速百分比GetComponent<Entity>().SlowEntityBy(slowPercentage, ailmentsDuration);//减速20%fx.ChillFxFor(ailmentsDuration);}if (_shock && canApplyShock){if (!isShocked){ApplyShock(_shock);}else{if (GetComponent<Player>() != null)//防止敌人打玩家自己被电return;HitNearsetTargerWithShockStrike();}}}public void ApplyShock(bool _shock){if (isShocked)//已经进入感电就不如再次进入return;isShocked = _shock;shockedTimer = ailmentsDuration;fx.ShockFxFor(ailmentsDuration);}private void HitNearsetTargerWithShockStrike(){Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 25);//碰撞体检测周围的敌人float closestDistance = Mathf.Infinity;Transform closestEnemy = null;foreach (var hit in colliders){if (hit.GetComponent<Enemy>() != null && Vector2.Distance(transform.position, hit.transform.position) > 1)//如果是敌人并且不是自己,防止自己被电{float distanceToEnemy = Vector2.Distance(transform.position, hit.transform.position);if (distanceToEnemy < closestDistance){closestDistance = distanceToEnemy;closestEnemy = hit.transform;}}if (closestEnemy == null)closestEnemy = transform;}//寻找最近的敌人然后雷击if (closestEnemy != null){GameObject newShockStrike = Instantiate(shockStrikePrefab, transform.position, Quaternion.identity);newShockStrike.GetComponent<ShockStrike_Controller>().Setup(shockDamage, closestEnemy.GetComponent<CharacterStats>());}}//闪电攻击附近的目标private void ApplyIgniteDamage(){if (igniteDamageTimer < 0){DecreaseHealthBy(igniteDamage);//currentHealth -= igniteDamage;if (currentHealth < 0 && !isDead)Die();igniteDamageTimer = igniteDamageCoolDown;}}public void SetupIgniteDamage(int _damage) => igniteDamage = _damage;//设置燃烧伤害public void SetupShockDamage(int _damage) => shockDamage = _damage;//设置感电伤害#endregionpublic virtual void TakeDamage(int _damage)//造成伤害函数,返回伤害值{DecreaseHealthBy(_damage);GetComponent<Entity>().DamageImpact();fx.StartCoroutine("FlashFX");Debug.Log(_damage);if (currentHealth < 0 && !isDead)Die();//人被杀就会死}public virtual void IncreaseHealthBy(int _amount)//加血函数{currentHealth += _amount;if (currentHealth > GetMaxHealthValue())currentHealth = GetMaxHealthValue();if (onHealthChanged != null)onHealthChanged();}protected virtual void DecreaseHealthBy(int _damage)//受到伤害的数值变化{currentHealth -= _damage;if (onHealthChanged != null)onHealthChanged();}protected virtual void Die(){isDead = true;}#region Stat calculationsprivate int CheckTargetResistance(CharacterStats _targetStats, int totalMagicalDamage)//计算魔法伤害(魔抗{totalMagicalDamage -= _targetStats.magicResistance.GetValue() + (_targetStats.intelligence.GetValue() * 3);//减去魔抗值totalMagicalDamage = Mathf.Clamp(totalMagicalDamage, 0, int.MaxValue);//Clamp限制血量数值return totalMagicalDamage;}private int CheckTargetArmor(CharacterStats _targetStats, int totalDamage)//计算物理伤害(护甲{if (_targetStats.isChilled)totalDamage -= Mathf.RoundToInt(_targetStats.armor.GetValue() * .8f);//减去对方的护甲值elsetotalDamage -= _targetStats.armor.GetValue();//减去对方的护甲值totalDamage = Mathf.Clamp(totalDamage, 0, int.MaxValue);//最小值是0,最大值是int.MaxValue,防止别人打我加血return totalDamage;}private bool TargetCanAvoidAttack(CharacterStats _targetStats)//检测闪避{int totalEvasion = _targetStats.evasion.GetValue() + _targetStats.agility.GetValue();//总的闪避率if (isShocked)totalEvasion += 20;if (Random.Range(0, 100) < totalEvasion){Debug.Log("Attack Avoided");return true;}return false;}private bool Cancrit()//暴击检测{int totalCritChance = critChance.GetValue() + agility.GetValue();//总的暴击率if (Random.Range(0, 100) < totalCritChance){return true;}return false;}private int CalculateCriticalDamage(int _damage)//计算爆伤{float totalCritPower = (critPower.GetValue() + strength.GetValue()) * .01f;//Debug.Log("总的暴击率: " + totalCritPower);//total crit powerfloat critDamage = _damage * totalCritPower;//Debug.Log("取整之后的爆伤" + critDamage);//crit damage before round upreturn Mathf.RoundToInt(critDamage);}public int GetMaxHealthValue(){return maxHealth.GetValue() + vitality.GetValue() * 5;}//获取最大生命值#endregionpublic Stat GetStat(StatType _statType)//根据 buffType 返回需要修改的属性{if (_statType == StatType.strength) return strength;else if (_statType == StatType.agility) return agility;else if (_statType == StatType.intelligence) return intelligence;else if (_statType == StatType.vitality) return vitality;else if (_statType == StatType.damage) return damage;else if (_statType == StatType.critChance) return critChance;else if (_statType == StatType.critPower) return critPower;else if (_statType == StatType.health) return maxHealth;else if (_statType == StatType.armor) return armor;else if (_statType == StatType.evasion) return evasion;else if (_statType == StatType.magicRes) return magicResistance;else if (_statType == StatType.fireDamage) return fireDamage;else if (_statType == StatType.iceDamage) return iceDamage;else if (_statType == StatType.lightingDamage) return lightningDamage;else return null;}
}
Buff_Effect.cs
using UnityEngine;//2024年11月11日[CreateAssetMenu(fileName = "Buff Effect", menuName = "Data/Item effect/Buff effect")]
public class Buff_Effect : ItemEffect
{private PlayerStats stats;[SerializeField] private StatType buffType;// Buff 的类型[SerializeField] private int buffAmount; // Buff 的增加量[SerializeField] private float buffDuration;// Buff 持续时间public override void ExcuteEffect(Transform _enemyPositon){stats = PlayerManager.instance.player.GetComponent<PlayerStats>();//相当于获得了CharacterStats的引用stats.IncreaseStatBy(buffAmount, buffDuration, stats.GetStat(buffType));}
}
Inventory.cs
更新部分
[SerializeField] private Transform statSlotParent;private UI_StatSlot[] statSlot;private void Start()//初始实例化{inventoryItems = new List<InventoryItem>();inventoryDictionary = new Dictionary<ItemData, InventoryItem>();stash = new List<InventoryItem>();stashDictionary = new Dictionary<ItemData, InventoryItem>();equipment = new List<InventoryItem>();equipmentDictionary = new Dictionary<ItemData_Equipment, InventoryItem>();//同时获取UI中对应的物品槽//获得起始的脚本inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_ItemSlot>();stashItemSlot = stashSlotParent.GetComponentsInChildren<UI_ItemSlot>();equipmentSlot = equipmentSlotParent.GetComponentsInChildren<UI_EquipmentSlot>();statSlot = statSlotParent.GetComponentsInChildren<UI_StatSlot>();AddStartingItems();}
using System.Collections.Generic;
using UnityEngine;//放在创建仓库的empyty对象上,就是仓库的运行函数
public class Inventory : MonoBehaviour
{public static Inventory instance;//单例模式public List<ItemData> startingItems;//初始装备//两种关键的存贮结构//List:存储玩家的装备、仓库物品、储藏室物品等//Dictionary:存储每个物品的数据以及物品在仓库中的具体信息,例如物品的堆叠数量public List<InventoryItem> equipment;public Dictionary<ItemData_Equipment, InventoryItem> equipmentDictionary;public List<InventoryItem> inventoryItems;public Dictionary<ItemData, InventoryItem> inventoryDictionary;public List<InventoryItem> stash;public Dictionary<ItemData, InventoryItem> stashDictionary;//UI物品槽管理:通过以下代码将游戏中的物品槽和UI界面上的物品槽关联起来[Header("仓库UI")]//Inventory UI[SerializeField] private Transform inventorySlotParent;//位置[SerializeField] private Transform stashSlotParent;[SerializeField] private Transform equipmentSlotParent;[SerializeField] private Transform statSlotParent;//物品和材料的存贮位置分开private UI_ItemSlot[] inventoryItemSlot;private UI_ItemSlot[] stashItemSlot;//储藏室private UI_EquipmentSlot[] equipmentSlot;//装备private UI_StatSlot[] statSlot;[Header("物品冷却")]private float lastTimeUsedFlask;private float lastTimeUsedArmor;//P122解决一开始不能用物品的问题,因为一开始冷却被赋值,使用了currentFlask.itemCoolDownprivate float flaskCoolDown;private float armorCoolDown;private void Awake(){if (instance == null)instance = this;elseDestroy(gameObject);//防止从一个地方到另一个地方}private void Start()//初始实例化{inventoryItems = new List<InventoryItem>();inventoryDictionary = new Dictionary<ItemData, InventoryItem>();stash = new List<InventoryItem>();stashDictionary = new Dictionary<ItemData, InventoryItem>();equipment = new List<InventoryItem>();equipmentDictionary = new Dictionary<ItemData_Equipment, InventoryItem>();//同时获取UI中对应的物品槽//获得起始的脚本inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_ItemSlot>();stashItemSlot = stashSlotParent.GetComponentsInChildren<UI_ItemSlot>();equipmentSlot = equipmentSlotParent.GetComponentsInChildren<UI_EquipmentSlot>();statSlot = statSlotParent.GetComponentsInChildren<UI_StatSlot>();AddStartingItems();}private void AddStartingItems()//添加初始物品{for (int i = 0; i < startingItems.Count; i++){AddItem(startingItems[i]);}}public void EquipItem(ItemData _item)//把一个物品装备到角色身上{ItemData_Equipment newEquipment = _item as ItemData_Equipment;//把 _item 对象转换为 ItemData_Equipment 类型,表示它是一个装备物品InventoryItem newItem = new InventoryItem(newEquipment); //把 ItemData 对象转换为 InventoryItem 对象ItemData_Equipment oldEquipment = null;//要删除的物品foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//遍历装备字典{if (item.Key.equipmentType == newEquipment.equipmentType)//如果装备类型相同oldEquipment = item.Key;//删除该装备}if (oldEquipment != null){UnequipItem(oldEquipment);AddItem(oldEquipment);//把要删除的物品放回仓库}equipment.Add(newItem);equipmentDictionary.Add(newEquipment, newItem);newEquipment.AddModifiers();//添加装备属性RemoveItem(_item);UpdataSlotsUI();}public void UnequipItem(ItemData_Equipment itemToRemove)//移除装备函数{if (equipmentDictionary.TryGetValue(itemToRemove, out InventoryItem value)){equipment.Remove(value);equipmentDictionary.Remove(itemToRemove);itemToRemove.RemoveModifiers();}}private void UpdataSlotsUI()//更新UI物体的数量{// 更新装备槽for (int i = 0; i < equipmentSlot.Length; i++)//将装备物品槽与一个装备字典中的物品进行匹配,并根据匹配结果更新物品槽的内容{foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//遍历装备字典{if (item.Key.equipmentType == equipmentSlot[i].slotType)//这个条件用于确保物品能放入正确的槽位中equipmentSlot[i].UpdataSlot(item.Value);}}// 清空并更新仓库和储藏室的物品槽for (int i = 0; i < inventoryItemSlot.Length; i++)//仓库物品槽{inventoryItemSlot[i].CleanUpSlot();}for (int i = 0; i < stashItemSlot.Length; i++)//储藏室中的物品槽{stashItemSlot[i].CleanUpSlot();}// 重新填充仓库和储藏室for (int i = 0; i < inventoryItems.Count; i++){inventoryItemSlot[i].UpdataSlot(inventoryItems[i]);}for (int i = 0; i < stash.Count; i++){stashItemSlot[i].UpdataSlot(stash[i]);}//更新属性槽for (int i = 0; i < statSlot.Length; i++){statSlot[i].UpdateStatValueUI();}}public void AddItem(ItemData _item)//据物品类型,将物品添加到仓库(inventory)或者储藏室(stash){if (_item.itemType == ItemType.Equipment){AddToInventory(_item);}else if (_item.itemType == ItemType.Material){AddToStash(_item);}UpdataSlotsUI();}private void AddToStash(ItemData _item){if (stashDictionary.TryGetValue(_item, out InventoryItem value)){value.AddStack();}else{InventoryItem newItem = new InventoryItem(_item);stash.Add(newItem);stashDictionary.Add(_item, newItem);}}private void AddToInventory(ItemData _item){if (inventoryDictionary.TryGetValue(_item, out InventoryItem value))//字典中检查仓库中是否有这个物品,具体查找的是ItemData,out InventoryItem value如果找,返回与该键相关联的值{value.AddStack();//如果物品已经存在于库存中,则增加其堆叠数量}else{InventoryItem newItem = new InventoryItem(_item);//如果物品不存在,则创建一个新的 InventoryIteminventoryItems.Add(newItem);inventoryDictionary.Add(_item, newItem);}}//检查物品是否已经在仓库里,如果存在则增加堆叠数量,如果不存在则创建新的物品对象并加入仓库public void RemoveItem(ItemData _item){if (inventoryDictionary.TryGetValue(_item, out InventoryItem value)){if (value.stackSize <= 1){inventoryItems.Remove(value);inventoryDictionary.Remove(_item);}else{value.RemoveStack();}}if (stashDictionary.TryGetValue(_item, out InventoryItem stashValue)){if (stashValue.stackSize <= 1)//如果物品的堆叠数量小于等于1,则从库存中删除该物品{stash.Remove(stashValue);stashDictionary.Remove(_item);}else{stashValue.RemoveStack();//否则就减少堆寨数量}}UpdataSlotsUI();}public bool CanCraft(ItemData_Equipment _itemToCraft, List<InventoryItem> _requiredMaterials)//判断是否可以合成的函数{List<InventoryItem> materialsToRemove = new List<InventoryItem>();for (int i = 0; i < _requiredMaterials.Count; i++){if (stashDictionary.TryGetValue(_requiredMaterials[i].data, out InventoryItem stashValue))//如果储藏室中没有所需材料{if (stashValue.stackSize < _requiredMaterials[i].stackSize)//数量是否足够{Debug.Log("没有足够的材料");return false;}else{materialsToRemove.Add(stashValue);}}else{Debug.Log("没有足够的材料");return false;}}for (int i = 0; i < materialsToRemove.Count; i++)//使用了就从临时仓库中移除{RemoveItem(materialsToRemove[i].data);}AddItem(_itemToCraft);Debug.Log("这里是你的物品" + _itemToCraft.name);return true;}public List<InventoryItem> GetEquipmentList() => equipment;//获取装备列表public List<InventoryItem> GetStashList() => stash;//获取仓库列表public ItemData_Equipment GetEquipment(EquipmentType _type)//获取装备{ItemData_Equipment equipedItem = null;foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//遍历装备字典{if (item.Key.equipmentType == _type)//如果装备类型相同equipedItem = item.Key;//删除该装备}return equipedItem;}public void UseFlask()//使用药水的函数{ItemData_Equipment currentFlask = GetEquipment(EquipmentType.Flask);//获取当前的药水if (currentFlask == null)return;bool canUseFlask = Time.time > lastTimeUsedFlask + flaskCoolDown;//判断是否可以使用药水if (canUseFlask){flaskCoolDown = currentFlask.itemCoolDown;//重置冷却时间,一开始就可以使用物品currentFlask.Effect(null);lastTimeUsedFlask = Time.time;}elseDebug.Log("药水冷却中");}public bool CanUseArmor(){ItemData_Equipment currentArmor = GetEquipment(EquipmentType.Armor);//获取当前装备的护甲信息。if (Time.time > lastTimeUsedArmor + armorCoolDown){//更新冷却时间和使用时间armorCoolDown = currentArmor.itemCoolDown;lastTimeUsedArmor = Time.time;return true;}Debug.Log("护甲正在冷却中");return false;}//private void Updata()//{// Debug.Log(Time.time);//}
}
相关文章:

Unity类银河战士恶魔城学习总结(P124 CharacterStats UI玩家的UI)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了玩家属性栏,仓库,物品栏UI的制作 UI_StatSlot.cs 这个脚本是用来在Unity的UI上显示玩家属性…...
速盾:cdn 支持 php 吗?
在网络开发中,PHP 是一种广泛使用的服务器端脚本语言,用于创建动态网页和 web 应用程序。CDN(Content Delivery Network,内容分发网络)在内容分发方面具有强大的功能,那么它是否支持 PHP 呢? C…...
在linux中使用nload实时查看网卡流量
在Linux系统中,可以使用多种工具来查看网卡流量。以下是一些常用的命令行工具: ifconfig:这是最基本的网络接口查看命令,但在最新的Linux发行版中,ifconfig命令已经被ip命令替代。 ip:用来查看和操作路由…...

【JavaEE进阶】Spring 事务和事务传播机制
目录 1.事务回顾 1.1 什么是事务 1.2 为什么需要事务 1.3 事务的操作 2. Spring 中事务的实现 2.1 Spring 编程式事务(了解) 2.2 Spring声明式事务 Transactional 对比事务提交和回滚的日志 3. Transactional详解 3.1 rollbackFor 3.2 Transactional 注解什么时候会…...

Flink1.19编译并Standalone模式本地运行
1.首先下载源码 2.本地运行 新建local_conf和local_lib文件夹,并且将编译后的文件放入对应的目录 2.1 启动前参数配置 2.1.2 StandaloneSessionClusterEntrypoint启动参数修改 2.1.3 TaskManagerRunner启动参数修改 和StandaloneSessionClusterEntrypoint一样修改…...
gitlab-development-kit部署gitlab《二》
gitlab-development-kit部署gitlab《一》 环境 mac 12.7.4 xcode 14.2 gdk 0.2.16 gitlab-foss 13.7 QA xcode源码安装 # https://crifan.github.io/xcode_dev_summary/website/xcode_dev/install_xcode/ # https://xcodereleases.comopenssl1.1 源码安装 # https://open…...
Java面试之多线程并发篇(3)
前言 本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!SynchronizedMap和ConcurrentHashMap有什么区别?什么是线程安全?Thread类中的yield方法有什么作用?Java线程池中submit() 和 execute()方法有…...
任何使用 Keras 进行迁移学习
在前面的文章中,我们介绍了如何使用 Keras 构建和训练全连接神经网络(MLP)、卷积神经网络(CNN)和循环神经网络(RNN)。本文将带你深入学习如何使用 迁移学习(Transfer Learning&#…...

Mac 使用mac 原生工具将mp4视频文件提取其中的 mp3 音频文件
简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖、省奖…已保研 学习经验:扎实基础 + 多做笔…...
【SQL】一文速通SQL
SQL知识概念介绍 1. Relation Schema vs Relation Instance 简单而言,Relation Schema 是一个表,有变量还有数据类型 R (A1, A2, … , An) e.g. Student (sid: integer, name: string, login: string, addr: string, gender: char) Relation insta…...
【学习】【HTML】块级元素,行内元素,行内块级元素
块级元素 块级元素是 HTML 中一类重要的元素,它们在页面布局中占据整行空间,通常用于创建页面的主要结构组件。 常见的块级元素有哪些? <div>: 通用的容器元素,常用于创建布局块。<p>:段落元素…...

握手协议是如何在SSL VPN中发挥作用的?
SSL握手协议:客户端和服务器通过握手协议建立一个会话。会话包含一组参数,主要有会话ID、对方的证书、加密算法列表(包括密钥交换算法、数据加密算法和MAC算法)、压缩算法以及主密钥。SSL会话可以被多个连接共享,以减少…...

机器学习 - 为 Jupyter Notebook 安装新的 Kernel
https://ipython.readthedocs.io/en/latest/install/kernel_install.html 当使用jupyter-notebook --no-browser 启动一个 notebook 时,默认使用了该 jupyter module 所在的 Python 环境作为 kernel,比如 C:\devel\Python\Python311。 如果,…...

CTF攻防世界小白刷题自学笔记13
1.fileinclude,难度:1,方向:Web 题目来源:宜兴网信办 题目描述:无 给一下题目链接:攻防世界Web方向新手模式第16题。 打开一看给了很多提示,什么language在index.php的第九行,flag在flag.php中,但事情显…...
Rust 模板匹配——根据指定图片查找处于大图中的位置(支持GPU加速)
Rust 模板匹配——根据指定图片查找处于大图中的位置(支持GPU加速) 01 前言 在手搓RPA工具的时候,总会碰到不好定位的情况,那么,就需要根据小图来找到对应屏幕上的位置(以图识图),这个需求也比较简单。想到市面上也有不少RPA工具都有这个功能,那么人家有的,俺也可以…...
JVM详解:类的加载过程
JVM中类的加载主要分为三个部分,分别为加载(loading),链接(linking),初始化(initing)。其中加载负责的主要是讲类文件加载到内存中变为类对象,不过此时只有基…...

Python →爬虫实践
爬取研究中心的书目 现在,想要把如下网站中的书目信息爬取出来。 案例一 耶鲁 Publications | Yale Law School 分析网页,如下图所示,需要爬取的页面,标签信息是“<p>”,所以用 itemssoup.find_all("p&…...

Visitor 访问者模式
1)意图 表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义用于这些元素的新操作。 2)结构 访问者模式的结构图如图 7-48 所示。 其中: Visitor(访问者) 为该对象结构中ConcreteElement 的每一个类声明一个 Vsit 操作。该操作的名字和特征标识…...
Mac解压包安装MongoDB8并设置launchd自启动
记录一下在mac上安装mongodb8过程,本机是M3芯片所以下载m芯片的安装包,intel芯片的类似操作。 首先下载安装程序包。 # M芯片下载地址 https://fastdl.mongodb.org/osx/mongodb-macos-arm64-8.0.3.tgz # intel芯片下载地址 https://fastdl.mongodb.org…...

Springboot采用jasypt加密配置
目录 前言 一、Jasypt简介 二、运用场景 三、整合Jasypt 2.1.环境配置 2.2.添加依赖 2.3.添加Jasypt配置 2.4.编写加/解密工具类 2.5.自定义加密属性前缀和后缀 2.6.防止密码泄露措施 2.61.自定义加密器 2.6.2通过环境变量指定加密盐值 总结 前言 在以往的多数项目中࿰…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...