背包系统一
一、创建物品类以及物品类型属性
1.如图所示
2.创建脚本Item类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /// <summary> /// 物品基类 /// </summary> public class Item { public int ID { get ; set ; } //ID public string Name { get ; set ; } //名字 public ItemType Type { get ; set ; } //类型 public ItemQuality Quality { get ; set ; } //质量 public string Description { get ; set ; } //描述 public int Capacity { get ; set ; } //容量 public int BuyPrice { get ; set ; } //购买价格 public int SellPrice { get ; set ; } //售卖价格 public string Sprite { get ; set ; } //物品图片 public Item() { this .ID = -1; } //构造函数 public Item( int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice, string sprite) { this .ID = id; this .Name = name; this .Type = type; this .Quality = quality; this .Description = des; this .Capacity = capacity; this .BuyPrice = buyPrice; this .SellPrice = sellPrice; this .Sprite = sprite; } /// <summary> /// 物品类型 /// </summary> public enum ItemType { Consumable, //消耗品 Equipment, //装备 Weapon, //武器 Material //材料 } /// <summary> /// 品质 /// </summary> public enum ItemQuality { Common, //普通 Uncommon, //不普通 Rare, //稀有 Epic, //史诗般 Legendary, //传奇 Artifact //古老 } /// <summary> /// 得到提示面板应该显示什么样的内容 /// </summary> /// <returns></returns> public virtual string GetToolTipText() { string color = "" ; switch (Quality) { case ItemQuality.Common: color = "white" ; break ; case ItemQuality.Uncommon: color = "lime" ; break ; case ItemQuality.Rare: color = "navy" ; break ; case ItemQuality.Epic: color = "magenta" ; break ; case ItemQuality.Legendary: color = "orange" ; break ; case ItemQuality.Artifact: color = "red" ; break ; } string text = string .Format( "<color={4}>{0}</color>\n<size=10><color=green>购买价格:{1} 出售价格:{2}</color></size>\n<color=yellow><size=10>{3}</size></color>" , Name, BuyPrice, SellPrice, Description, color); return text; } } |
消耗品类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /// <summary> /// 消耗品类 /// </summary> public class Consumable : Item { public int HP { get ; set ; } //血量 public int MP { get ; set ; } //蓝量 public Consumable( int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice , string sprite, int hp, int mp) : base (id,name,type,quality,des,capacity,buyPrice,sellPrice,sprite) { this .HP = hp; this .MP = mp; } public override string GetToolTipText() { string text = base .GetToolTipText(); string newText = string .Format( "{0}\n\n<color=blue>加血:{1}\n加蓝:{2}</color>" , text, HP, MP); return newText; } public override string ToString() { string s = "" ; s += ID.ToString(); s += Type; s += Quality; s += Description; s += Capacity; s += BuyPrice; s += SellPrice; s += Sprite; s += HP; s += MP; return s; } } |
装备类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | public class Equipment : Item { /// <summary> /// 力量 /// </summary> public int Strength { get ; set ; } /// <summary> /// 智力 /// </summary> public int Intellect { get ; set ; } /// <summary> /// 敏捷 /// </summary> public int Agility { get ; set ; } /// <summary> /// 体力 /// </summary> public int Stamina { get ; set ; } /// <summary> /// 装备类型 /// </summary> public EquipmentType EquipType { get ; set ; } public Equipment( int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice, string sprite, int strength, int intellect, int agility, int stamina, EquipmentType equipType) : base (id, name, type, quality, des, capacity, buyPrice, sellPrice, sprite) { this .Strength = strength; this .Intellect = intellect; this .Agility = agility; this .Stamina = stamina; this .EquipType = equipType; } public enum EquipmentType { None, Head, Neck, Chest, Ring, Leg, Bracer, Boots, Shoulder, Belt, OffHand } public override string GetToolTipText() { string text = base .GetToolTipText(); string equipTypeText = "" ; switch (EquipType) { case EquipmentType.Head: equipTypeText = "头部" ; break ; case EquipmentType.Neck: equipTypeText = "脖子" ; break ; case EquipmentType.Chest: equipTypeText = "胸部" ; break ; case EquipmentType.Ring: equipTypeText = "戒指" ; break ; case EquipmentType.Leg: equipTypeText = "腿部" ; break ; case EquipmentType.Bracer: equipTypeText = "护腕" ; break ; case EquipmentType.Boots: equipTypeText = "靴子" ; break ; case EquipmentType.Shoulder: equipTypeText = "护肩" ; break ; case EquipmentType.Belt: equipTypeText = "腰带" ; break ; case EquipmentType.OffHand: equipTypeText = "副手" ; break ; } string newText = string .Format( "{0}\n\n<color=blue>装备类型:{1}\n力量:{2}\n智力:{3}\n敏捷:{4}\n体力:{5}</color>" , text, equipTypeText, Strength, Intellect, Agility, Stamina); return newText; } } |
武器类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /// <summary> /// 武器 /// </summary> public class Weapon : Item { public int Damage { get ; set ; } public WeaponType WpType { get ; set ; } public Weapon( int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice, string sprite, int damage,WeaponType wpType) : base (id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite) { this .Damage = damage; this .WpType = wpType; } public enum WeaponType { None, OffHand, MainHand } public override string GetToolTipText() { string text = base .GetToolTipText(); string wpTypeText = "" ; switch (WpType) { case WeaponType.OffHand: wpTypeText = "副手" ; break ; case WeaponType.MainHand: wpTypeText = "主手" ; break ; } string newText = string .Format( "{0}\n\n<color=blue>武器类型:{1}\n攻击力:{2}</color>" , text, wpTypeText, Damage); return newText; } } |
材料类
1 2 3 4 5 6 7 8 9 10 | /// <summary> /// 材料类 /// </summary> public class Material : Item { public Material( int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice, string sprite) : base (id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite) { } } |
二、UI搭建
1.创建一个BagPanel,在其下面创建Scroll View,可以滑动的包,
2.在Content下创建空对象BagGridPanel,并添加组件GridLayoutGroup、Canvas Group。GridLayoutGroup组件Cell Size设置80X80,Spacing:10X8。添加脚本knapsack
3.在BagGridPanel下创建BagFrame物品槽,添加脚本Slot。并拖成预制体
4.在BagFrame下创建itemsprite(Imge)和ItemAmount(Text),添加脚本ItemUI,并拖成预制体
三、编写Json文件
1.https://www.bejson.com/jsoneditoronline/这个网址可以在线编写Json文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | [ { "id" : 1, "name" : "血瓶" , "type" : "Consumable" , "quality" : "Common" , "description" : "这个是用来加血的" , "capacity" : 10, "buyPrice" : 10, "sellPrice" : 5, "hp" : 10, "mp" : 0, "sprite" : "Sprites/Items/hp" }, { "id" : 2, "name" : "蓝瓶" , "type" : "Consumable" , "quality" : "Common" , "description" : "这个是用来加蓝的" , "capacity" : 10, "buyPrice" : 10, "sellPrice" : 5, "hp" : 0, "mp" : 10, "sprite" : "Sprites/Items/mp" }, { "id" : 3, "name" : "胸甲" , "type" : "Equipment" , "quality" : "Rare" , "description" : "这个胸甲很牛B" , "capacity" : 1, "buyPrice" : 20, "sellPrice" : 10, "sprite" : "Sprites/Items/armor" , "strength" :10, "intellect" :4, "agility" :9, "stamina" :1, "equipType" : "Chest" }, { "id" : 4, "name" : "皮腰带" , "type" : "Equipment" , "quality" : "Epic" , "description" : "这个腰带可以加速" , "capacity" : 1, "buyPrice" : 20, "sellPrice" : 10, "sprite" : "Sprites/Items/belts" , "strength" :1, "intellect" :6, "agility" :10, "stamina" :10, "equipType" : "Belt" }, { "id" : 5, "name" : "靴子" , "type" : "Equipment" , "quality" : "Legendary" , "description" : "这个靴子可以加速" , "capacity" : 1, "buyPrice" : 20, "sellPrice" : 10, "sprite" : "Sprites/Items/boots" , "strength" :10, "intellect" :5, "agility" :0, "stamina" :10, "equipType" : "Boots" }, { "id" : 6, "name" : "护腕" , "type" : "Equipment" , "quality" : "Rare" , "description" : "这个护腕可以增加防御" , "capacity" : 1, "buyPrice" : 20, "sellPrice" : 10, "sprite" : "Sprites/Items/bracers" , "strength" :1, "intellect" :2, "agility" :3, "stamina" :4, "equipType" : "Bracer" }, { "id" : 7, "name" : "神启手套" , "type" : "Equipment" , "quality" : "Common" , "description" : "很厉害的手套" , "capacity" : 1, "buyPrice" : 10, "sellPrice" : 5, "sprite" : "Sprites/Items/gloves" , "strength" :2, "intellect" :3, "agility" :4, "stamina" :4, "equipType" : "OffHand" }, { "id" : 8, "name" : "头盔" , "type" : "Equipment" , "quality" : "Artifact" , "description" : "很厉害的头盔" , "capacity" : 1, "buyPrice" : 10, "sellPrice" : 5, "sprite" : "Sprites/Items/helmets" , "strength" :2, "intellect" :3, "agility" :4, "stamina" :4, "equipType" : "Head" }, { "id" : 9, "name" : "项链" , "type" : "Equipment" , "quality" : "Rare" , "description" : "很厉害的项链" , "capacity" : 1, "buyPrice" : 10, "sellPrice" : 5, "sprite" : "Sprites/Items/necklace" , "strength" :2, "intellect" :3, "agility" :4, "stamina" :4, "equipType" : "Neck" }, { "id" : 10, "name" : "戒指" , "type" : "Equipment" , "quality" : "Common" , "description" : "很厉害的戒指" , "capacity" : 1, "buyPrice" : 20, "sellPrice" : 20, "sprite" : "Sprites/Items/rings" , "strength" :20, "intellect" :3, "agility" :4, "stamina" :4, "equipType" : "Ring" }, { "id" : 11, "name" : "裤子" , "type" : "Equipment" , "quality" : "Uncommon" , "description" : "很厉害的裤子" , "capacity" : 1, "buyPrice" : 40, "sellPrice" : 20, "sprite" : "Sprites/Items/pants" , "strength" :20, "intellect" :30, "agility" :40, "stamina" :40, "equipType" : "Leg" }, { "id" : 12, "name" : "护肩" , "type" : "Equipment" , "quality" : "Legendary" , "description" : "很厉害的护肩" , "capacity" : 1, "buyPrice" : 100, "sellPrice" : 20, "sprite" : "Sprites/Items/shoulders" , "strength" :2, "intellect" :3, "agility" :4, "stamina" :4, "equipType" : "Shoulder" }, { "id" : 13, "name" : "开天斧" , "type" : "Weapon" , "quality" : "Rare" , "description" : "渔翁移山用的斧子" , "capacity" : 1, "buyPrice" : 50, "sellPrice" : 20, "sprite" : "Sprites/Items/axe" , "damage" :100, "weaponType" : "MainHand" }, { "id" : 14, "name" : "阴阳剑" , "type" : "Weapon" , "quality" : "Rare" , "description" : "非常厉害的剑" , "capacity" : 1, "buyPrice" : 15, "sellPrice" : 5, "sprite" : "Sprites/Items/sword" , "damage" :20, "weaponType" : "OffHand" }, { "id" : 15, "name" : "开天斧的锻造秘籍" , "type" : "Material" , "quality" : "Artifact" , "description" : "用来锻造开天斧的秘籍" , "capacity" : 2, "buyPrice" : 100, "sellPrice" : 99, "sprite" : "Sprites/Items/book" }, { "id" : 16, "name" : "头盔的锻造秘籍" , "type" : "Material" , "quality" : "Common" , "description" : "用来锻造头盔的秘籍" , "capacity" : 2, "buyPrice" : 50, "sellPrice" : 10, "sprite" : "Sprites/Items/scroll" }, { "id" : 17, "name" : "铁块" , "type" : "Material" , "quality" : "Common" , "description" : "用来锻造其他东西的必备材料" , "capacity" : 20, "buyPrice" : 5, "sellPrice" : 4, "sprite" : "Sprites/Items/ingots" } ] |
四、解析Json文件
1.Json文件放在Resources文件夹下
2.创建厂库管理对象脚本InventoryManager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class InventoryManager : MonoBehaviour { #region 单例模式 private static InventoryManager _instance; public static InventoryManager Instance { get { if (_instance == null ) { //下面的代码只会执行一次 _instance = GameObject.Find( "InventoryManager" ).GetComponent<InventoryManager>(); } return _instance; } } #endregion /// <summary> /// 物品信息的列表(集合) /// </summary> private List<Item> itemList; |
1 2 3 4 | void Awake() { ParseItemJson(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /// <summary> /// 解析物品信息 /// </summary> void ParseItemJson() { itemList = new List<Item>(); //文本为在Unity里面是 TextAsset类型 TextAsset itemText = Resources.Load<TextAsset>( "Items" ); string itemsJson = itemText.text; //物品信息的Json格式 JSONObject j = new JSONObject(itemsJson); foreach (JSONObject temp in j.list) { string typeStr = temp[ "type" ].str; Item.ItemType type= (Item.ItemType)System.Enum.Parse( typeof (Item.ItemType), typeStr); //下面的事解析这个对象里面的公有属性 int id = ( int )(temp[ "id" ].n); string name = temp[ "name" ].str; Item.ItemQuality quality = (Item.ItemQuality)System.Enum.Parse( typeof (Item.ItemQuality), temp[ "quality" ].str); string description = temp[ "description" ].str; int capacity = ( int )(temp[ "capacity" ].n); int buyPrice = ( int )(temp[ "buyPrice" ].n); int sellPrice = ( int )(temp[ "sellPrice" ].n); string sprite = temp[ "sprite" ].str; Item item = null ; switch (type) { case Item.ItemType.Consumable: int hp = ( int )(temp[ "hp" ].n); int mp = ( int )(temp[ "mp" ].n); item = new Consumable(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, hp, mp); break ; case Item.ItemType.Equipment: // int strength = ( int )temp[ "strength" ].n; int intellect = ( int )temp[ "intellect" ].n; int agility = ( int )temp[ "agility" ].n; int stamina = ( int )temp[ "stamina" ].n; Equipment.EquipmentType equipType = (Equipment.EquipmentType) System.Enum.Parse( typeof (Equipment.EquipmentType),temp[ "equipType" ].str ); item = new Equipment(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, strength, intellect, agility, stamina, equipType); break ; case Item.ItemType.Weapon: // int damage = ( int ) temp[ "damage" ].n; Weapon.WeaponType wpType = (Weapon.WeaponType)System.Enum.Parse( typeof (Weapon.WeaponType), temp[ "weaponType" ].str); item = new Weapon(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, damage, wpType); break ; case Item.ItemType.Material: // item = new Material(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite); break ; } itemList.Add(item); } } |
五、Inventory背包获取物品并进行存储
1.BagPanel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Knapsack : Inventory { #region 单例模式 private static Knapsack _instance; public static Knapsack Instance { get { if (_instance == null ) { _instance = GameObject.Find( "BagGridPanel" ).GetComponent<Knapsack>(); } return _instance; } } #endregion } |
2.InventoryManager
1 2 3 4 5 6 7 8 9 10 11 12 | //通过ID获取物品 public Item GetItemById( int id) { foreach (Item item in itemList) { if (item.ID == id) { return item; } } return null ; } |
3.Inventory
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Inventory : MonoBehaviour { protected Slot[] slotList; //物品槽数组 private float targetAlpha = 1; private float smoothing = 4; private CanvasGroup canvasGroup; public virtual void Start () { slotList = GetComponentsInChildren<Slot>(); canvasGroup = GetComponent<CanvasGroup>(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | public bool StoreItem( int id) { Item item = InventoryManager.Instance.GetItemById(id); //通过ID获取物品 return StoreItem(item); } public bool StoreItem(Item item) { if (item == null ) { Debug.LogWarning( "要存储的物品的id不存在" ); return false ; } if (item.Capacity == 1) { Slot slot = FindEmptySlot(); if (slot == null ) { Debug.LogWarning( "没有空的物品槽" ); return false ; } else { slot.StoreItem(item); //把物品存储到这个空的物品槽里面 } } else { Slot slot = FindSameIdSlot(item); if (slot != null ) { slot.StoreItem(item); } else { Slot emptySlot = FindEmptySlot(); if (emptySlot != null ) { emptySlot.StoreItem(item); } else { Debug.LogWarning( "没有空的物品槽" ); return false ; } } } return true ; } /// <summary> /// 这个方法用来找到一个空的物品槽 /// </summary> /// <returns></returns> private Slot FindEmptySlot() { foreach (Slot slot in slotList) { if (slot.transform.childCount == 0) { return slot; } } return null ; } //找相同的物品槽 private Slot FindSameIdSlot(Item item) { foreach (Slot slot in slotList) { if (slot.transform.childCount >= 1 && slot.GetItemId() == item.ID && slot.IsFilled() == false ) { return slot; } } return null ; } |
4.Slot物品槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /// <summary> /// 物品槽 /// </summary> public class Slot : MonoBehaviour{ public GameObject itemPrefab; //物品预制体 /// <summary> /// 把item放在自身下面 /// 如果自身下面已经有item了,amount++ /// 如果没有 根据itemPrefab去实例化一个item,放在下面 /// </summary> /// <param name="item"></param> public void StoreItem(Item item) { if (transform.childCount == 0) { GameObject itemGameObject = Instantiate(itemPrefab) as GameObject; itemGameObject.transform.SetParent( this .transform); itemGameObject.transform.localScale = Vector3.one; itemGameObject.transform.localPosition = Vector3.zero; itemGameObject.GetComponent<ItemUI>().SetItem(item); } else { transform.GetChild(0).GetComponent<ItemUI>().AddAmount(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /// <summary> /// 得到物品的id /// </summary> /// <returns></returns> public int GetItemId() { return transform.GetChild(0).GetComponent<ItemUI>().Item.ID; } //是否填满 public bool IsFilled() { ItemUI itemUI = transform.GetChild(0).GetComponent<ItemUI>(); return itemUI.Amount >= itemUI.Item.Capacity; //当前的数量大于等于容量 } |
5.ItemUI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | public class ItemUI : MonoBehaviour { #region Data public Item Item { get ; private set ; } //物品 public int Amount { get ; private set ; } //物品数量 #endregion #region UI Component private Image itemImage; //物品图片 private Text amountText; //物品数量文本 //获得物品图片组件 private Image ItemImage { get { if (itemImage == null ) { itemImage = GetComponent<Image>(); } return itemImage; } } //获得物品数量文本组件 private Text AmountText { get { if (amountText == null ) { amountText = GetComponentInChildren<Text>(); } return amountText; } } #endregion private float targetScale = 1f; private Vector3 animationScale = new Vector3(1.4f, 1.4f, 1.4f); private float smoothing = 4; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //更新UI public void SetItem(Item item, int amount = 1) { transform.localScale = animationScale; this .Item = item; this .Amount = amount; // update ui ItemImage.sprite = Resources.Load<Sprite>(item.Sprite); if (Item.Capacity > 1) AmountText.text = Amount.ToString(); else AmountText.text = "" ; } //增加物品数量 public void AddAmount( int amount=1) { transform.localScale = animationScale; this .Amount += amount; //update ui if (Item.Capacity > 1) AmountText.text = Amount.ToString(); else AmountText.text = "" ; } |
6.测试脚本Player
1 2 3 4 5 6 7 | void Update () { //G 随机得到一个物品放到背包里面 if (Input.GetKeyDown(KeyCode.G)) { int id = Random.Range(1, 18); Knapsack.Instance.StoreItem(id); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?