Unity - バックパックシステム(鍛造および装備システムを含む)

バックパック システム パッケージ git アドレス: https://github.com/PigerYoung/InventorySystem.git

バックパックシステムはアイテムと切り離せないため、バックパックシステムを設計する際にはアイテム(Item)のクラス図を設定し、配布用のUMLクラス図を添付する必要があります。

 まず、親クラスのItemはすべての装備品がItemクラスを継承しているため、クラス図に従って書くことができます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum ItemType//物品种类
{
    Consumable,//消耗品
    Equipment,//装备
    Weapon,//武器
    Material//材料
}
public enum Quality//物品品质
{
    Common,
    Uncommon,
    Rare,
    Epic,
    Legendary,
    Artifact
}

public class Item //物品基类
{
    public int ID { get; set; }
    public string Name { get; set; }
    public ItemType ItemType { get; set; }
    public Quality Quality { get; set; }
    public string Description { get; set; }
    public int Capicity { get; set; }
    public int BuyPrice { get; set; } 
    public int SellPrice { get;set; }
    public string Sprite { get; set; }//存放物品的图片路径,通过Resources加载
    public Item(int iD, string name, ItemType itemType, Quality quality, string description, int capicity, int buyPrice, int sellPrice)
    {
        ID = iD;
        Name = name;
        ItemType = itemType;
        Quality = quality;
        Description = description;
        Capicity = capicity;
        BuyPrice = buyPrice;
        SellPrice = sellPrice;
        Sprite = sprite;
    }
public Item() { }//无参构造函数,防止子类在没中没有显式定义构造函数,则会默认调用父类无参数构造
//函数。
}

次に、アイテム、消耗品、装備品、武器、材料のカテゴリのサブカテゴリを順番に作成します。 

using UnityEngine;

/// <summary>
/// 消耗品类
/// </summary>
public class Consumable : Item
{
    public int HP { get; set; }//消耗品增加的血量
    public int Mp { get; set; }//消耗品增加的蓝量
    public Consumable(int hP, int mp, int iD, string name, ItemType itemType, Quality quality, string description, int capicity, int buyPrice, int sellPrice,string sprite) :base(iD,name,itemType,quality,description,capicity,buyPrice,sellPrice, sprite)
    {
        HP = hP;
        Mp = mp;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum EquipType//装备类型枚举
{
    Head,//头部
    Neck,//脖子
    Ring,//戒指
    Leg,//腿
    Bracer,//护腕
    Boots,//靴子
    Shoulder,//肩膀
    Belt,//腰带
    OffHand//副手
}
/// <summary>
/// 装备类
/// </summary>
public class Equipment : Item
{
    public int Strength { get; set; }//力量
    public int Intellect { get; set; }//智力
    public int Agility { get; set; }//敏捷
    public int Stamina { get; set; }//体力
    public EquipType equipType { get; set; }//装备类型 
    public Equipment(int strength, int intellect, int agility, int stamina, EquipType equipType, int iD, string name, ItemType itemType, Quality quality, string description, int capicity, int buyPrice, int sellPrice,string sprite): base(iD, name, itemType, quality, description, capicity, buyPrice, sellPrice, sprite)
    {
        Strength = strength;
        Intellect = intellect;
        Agility = agility;
        Stamina = stamina;
        this.equipType = equipType;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Playables;
using UnityEngine;

/// <summary>
/// 武器类
/// </summary>
public enum WeaponType//武器类型
{
    offHand,//副手
    mianHand//主手
}

public class Weapon : Item
{
    public int Damage { get; set; }
    public WeaponType weaponType { get; set;}

    public Weapon(int damage ,WeaponType weaponType,int iD, string name, ItemType itemType, Quality quality, string description, int capicity, int buyPrice, int sellPrice,string sprite) : base(iD, name, itemType, quality, description, capicity, buyPrice, sellPrice, sprite)
    {
       Damage = damage;
       this.weaponType = weaponType;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 材料类
/// </summary>
public class Material : Item
{
public Material(int iD, string name, ItemType itemType, Quality quality, string description, int capicity, int buyPrice, int sellPrice, string sprite) : base(iD, name, itemType, quality, description, capicity, buyPrice, sellPrice, sprite)
    {

    }
    public Material()
    { }
}

項目クラスを記述した後、json 形式を使用してさまざまな項目を作成し、コード内で json を解析すると、解析された json が項目のさまざまな情報を割り当てることができます (簡単な方法は、クラスのスクリプトがマウントされることです) (プレハブにはゲームオブジェクトに関するさまざまな情報が保存されており、ここでの JSON の役割は装備に関するさまざまな情報を保存することであるため)、この方法はアイテムの数が多い場合にのみ適しています。 (Litjson はファイルを解析するときに大文字と小文字を区別します!! したがって、json ファイルのフィールド名は、クラス内の名前の内容および大文字と小文字と一致している必要があります)

(!! Listjson は、列挙型を解析するときに、"ItemType": "Consumable" を使用してこの種類の列挙型を解析できません。また、自動的に文字列に解析します。そのため、解決策は 2 つあります。 1. ISerializationCallbackReceiver インターフェイスを使用してシリアル化します。完了後に、文字列を列挙型に変換します。これには、クラスに列挙型と文字列型の両方が含まれている必要があります (これら 2 つは対応している必要があります)。詳細については、参照リンクを参照してください。 2. json 形式を表すには、int 型を使用します。たとえば、Consumable に対応する列挙型 int は 0 なので、このように参照リンクを記述します)

これは json ファイルの内容の一部であり、テストに使用されます

[
  {     "Id": 1,     "Name": "血液ボトル",     "ItemType": 0,     "Quality": 1,     "Description": "これは血液を増やすために使用されます",     "Capacity": 10,     " BuyPrice ": 10、     "SellPrice": 5、     "Sprite": "スプライト/アイテム/hp"、     "Hp": 100、     "Mp": 0   } ]












json ファイルを取得した後、json ファイルを解析して管理するための InventoryManager クラスを作成できます。json を解析するとき、さまざまな機器 (サブクラス) を受け取るために itemList コレクション (Item の親クラスがリストに格納されている) のみが使用されるため、 )、そのため、動的に json を解析する方法、つまり JsonData を使用してそれを受信し (すべての情報を受信できる)、json 内の特定の識別子によってそれを区別し、対応するサブクラス オブジェクトを新しく作成して配置する必要があります。それを itemList に追加します。

アイデアを明確にするために、まず、開発がこの段階になったときに InventoryManager クラスが持つべきものを添付します (まだ開発されていないため、内容は後で追加されます)。

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using LitJson;
using System;

public class InventoryManager : MonoBehaviour
{
    #region 单例模式
    private static InventoryManager _instance;
    public static InventoryManager Instance
    {
        get 
        {
            if( _instance == null )
            {
                _instance = GameObject.Find("InventoryManager").GetComponent<InventoryManager>();//这里是在静态方法中,因此不能直接用this或者gameobject来获取组件
            }
            return _instance;
        }
    }
    #endregion

    #region 解析json
    //这里设计的大概思想就像,首先json文件是一个写好的装备信息,改json文件是一个[{},{}],数组里面的类是继承自Item的,因此设定一个itemList集合
    //将json文件解析到itemList(解析json到数组需要用到Litjson,unity内置的jsonutility不能解析成数组),如果使用itemList = JsonMapper.ToObject<List<Item>>(itemsjson);
    //会出现一个问题,就是虽然能够成功解析到内容,但是因为是json数组里面存放的是Item的子类对象,子类有特定的一些属性就不能成功解析到itemList 集合的对象中(因为itemList存放的是Item对象,是父类对象),因此也就访问不到
    //因此就需要动态解析json,也就是把所有的json信息都要解析出来,不能只将json解析为Item对象,因此就可以使用JsonData类,来接受json的解析,并且通过判断每一个对象的itemtype来newItem的子对象,并add到itemLis中(子类向上转型);如果要使用itemList对象时,就需要向下转型成对应的子类对象
    private List<Item> itemList = new List<Item>();

    private void Start()
    {
        ParseItemJson();
    }
    //解析物品信息
    void ParseItemJson()
    { 
        TextAsset itemText = Resources.Load<TextAsset>("Items");
        string itemsjson = itemText.text;//物品信息的json格式
        //itemList=JsonUtility.FromJson<List<Item>>(itemsjson);//jsonuti不能解析成数组
        JsonData jsondata = JsonMapper.ToObject(itemsjson);
        //itemList = JsonMapper.ToObject<List<Item>>(itemsjson);//将json解析到itemList中,用一个父类List集合保存所有子类对象(我觉得这里有设计缺陷)
        Item itemtemp = null;                                    
        for (int i=0; i<jsondata.Count;i++)//用物品类型来区分
        {
            int id = (int)jsondata[i]["Id"];
            string name = jsondata[i]["Name"].ToString();
            ItemType itemType = (ItemType)((int)jsondata[i]["ItemType"]);
            Quality quality = (Quality)((int)jsondata[i]["Quality"]);
            string description = jsondata[i]["Description"].ToString();
            int capicity = (int)jsondata[i]["Capicity"];
            int buyprice = (int)jsondata[i]["BuyPrice"];
            int sellprice = (int)jsondata[i]["SellPrice"];
            string sprite = jsondata[i]["Sprite"].ToString();
            switch (itemType)
            {
                case ItemType.Consumable:
                    int hp = (int)jsondata[i]["Hp"];
                    int mp = (int)jsondata[i]["Mp"];
                    itemtemp = new Consumable(hp, mp, id, name, itemType, quality, description, capicity, buyprice, sellprice, sprite);
                    break;
                case ItemType.Equipment:
                    break;
                case ItemType.Weapon:
                    break;
                case ItemType.Material:
                    break;
                default:
                    break;
            }
            itemList.Add(itemtemp);
        }
        Consumable test = (Consumable)itemList[0];
        Debug.Log(test.HP + "+" + test.Mp);
    }
    #endregion
}

 json を正常に読み取れたら、UI を設計して構築できます。

Unity で UI を構築します (ここでは詳しい構築方法は説明しません。バックパック システムについては学習しましたが、まだ UI の構築方法がわかりません!!! 戻ってさらに構築してください)

UIを設計する際の注意点:スロットとアイテムはそれぞれプレハブ化されています。つまり、後の追加と非表示を容易にするために、グリッドとアイテムのアイテムが別々に作成されます(追加のアイデアは、アイテムをサブとして設定することです) -グリッドのオブジェクトを取得し、ローカル座標を 0 に割り当てます。非表示と同じです)

現在のビルド効果

UIを構築したら、UIに合わせてスクリプトを設計しますバックパックパネルを例にすると、1.Inventory、2.Knapsack、3.Slot、4.ItemUIの4つのスクリプトが必要になります(具体的な機能はスクリプト内)

1. Inventory クラスはパネル クラスの親クラスです。パネル クラスはバックパック パネル、ボックス パネルなどでもあります。ここではバックパック パネルを例に挙げます。パネル クラスに共通のメソッド属性がいくつかあります。アイテムスロットの一覧表示やアイテムストレージ関数の呼び出し、空スロットの検索、同じアイテムが入っているスロットの検索など。

2.ナップサッククラス、バックパックパネルの独自メソッド属性(バックパックパネルに実装)

3. スロット クラス。グリッド関数へのアイテムの格納 (Inventory クラスによって呼び出される)、スロットの下のアイテム タイプの取得、現在のスロットが特定の機器 (マウントされている) で満たされているかどうかの判断など、グリッドを制御するスクリプトです。スロットプレハブ)

4. スロット内のアイテムのUIスクリプトを制御するItemUIクラス(アイテムと数量、アイテムの設定など)(アイテムプレハブにマウントされています)

以下に、この段階までに開発された 4 つのスクリプトのソース コードを添付します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 所有可以装物品面板的父类,用来装物品
/// </summary>
public class Inventory : MonoBehaviour
{
    //所有装物品的面板都有Slot,因此可以用list集合来存放当前面板的所有slot
    private List<Slot> slotList = new List<Slot>();
   public virtual void Start()//因为还有背包,箱子等面板可能会用到Start函数,所以把它设为虚函数
    {
        slotList.AddRange(GetComponentsInChildren<Slot>());
    }

/// <summary>
/// 存储物品函数
/// </summary>
/// <param name="id">存储id对应的Item</param>
/// <returns>是否存放成功</returns>
    public bool StoreItem(int id)
    {
        Item item =InventoryManager.Instance.GetItemById(id);
        if (item == null)
        {
            Debug.LogWarning("要储存的物品id不存在");
            return false;
        }
        //如果要存储的物品id存在
        if(item.Capicity==1)//如果容量为1
        {
            //放在一个新格子里面
            Slot slot=FindEmptySlot();
            if (slot==null)
            {
                Debug.LogWarning("没有空的物品槽");
                return false;
            }
            else
            {
                slot.StoreItem(item);//把物品存储到空物品槽里面
            }
        }
        else//如果容量不为1
        {
              //找一个和item的id一样的格子进行存放
            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;
    }

    private Slot FindEmptySlot()//找空的物品槽Slot
    {
        foreach (Slot slot in slotList)
        {
            if(slot.transform.childCount==0)
            {
                return slot;
            }
        }
        return null;
    }
   private Slot FindSameIdSlot(Item item)//找物品槽存放的item与参数itemID相同的slot
    {
        foreach (Slot slot in slotList)
        {
            if(slot.transform.childCount>=1&&slot.GetItemId()==item.Id&&slot.IsFilled()==false)
            {
                return slot;
            }
        }
        return null;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Knapsack : Inventory
{
    #region 单例模式
    private static Knapsack _instance;
    public static Knapsack Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = GameObject.Find("KnapsackPanel").GetComponent<Knapsack>();//这里是在静态方法中,因此不能直接用this或者gameobject来获取组件
            }
            return _instance;
        }
    }
    #endregion
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/// <summary>
/// 这是存储物品的格子脚本
/// </summary>
public class Slot : MonoBehaviour
{
    public GameObject itemPrefab;//这里需要用预制件进行赋值
   public void StoreItem(Item item)//将Item存储到slot格子中(把item放在自身下面),1.如果有item了就,amount++。2.如果没有item,就实例化item放在下面
    {
        if(transform.childCount==0)//如果格子为空时
        {
            GameObject itemGameObject=Instantiate(itemPrefab);
            itemGameObject.transform.SetParent(transform);
            itemGameObject.transform.localPosition = Vector3.zero;
            itemGameObject.GetComponent<ItemUI>().SetItem(item);//!!!这里就是将外部的item和slot中的item同步
        }
        else
        {
            transform.GetChild(0).GetComponent<ItemUI>().AddAmount();
        }
    }

   public int GetItemId()//获取到slot下的Item的Id
    {
        return transform.GetChild(0).GetComponent<ItemUI>().Item.Id;
    }

    public bool IsFilled()//判断当前槽是否装满该装备
    {
        ItemUI itemUI = transform.GetChild(0).GetComponent<ItemUI>();
        return itemUI.Amount >= itemUI.Item.Capicity;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemUI : MonoBehaviour
{
   public Item Item { get; private set; }
   public int Amount { get; private set; }

    private Image itemImage;//item中图片和数量
    private Text amountText;

    private void Awake()
    {
        itemImage = GetComponent<Image>();
        amountText=GetComponentInChildren<Text>();
    }

    public void SetItem(Item item,int amount=1)//用参数item设置itemUI中的item
    {
        this.Item = item;
        this.Amount= amount;
        //更新UI
        itemImage.sprite = Resources.Load<Sprite>(item.Sprite);//根据item中的sprite加载Resources文件中的图片并赋值给当前slot中的item
         if(item.Capicity>1)//容量大于1才显示
        amountText.text=Amount.ToString();
        else 
            amountText.text="";
    }
    public void AddAmount(int amount=1)
    {
        this.Amount += amount;
        //更新UI
        amountText.text = Amount.ToString();
    }


}

機器の生成やその他の操作をシミュレートするために使用されるプレーヤー スクリプトもあります。

using UnityEngine;

public class Player : MonoBehaviour
{
    void Update()
    {
        //G 按下G键,随机得到一个物品到背包中
        if (Input.GetKeyDown(KeyCode.G))
        {
            int id = Random.Range(1, 2);//通过生成装备id来表示生成装备
            Knapsack.Instance.StoreItem(id);
        }
    }
}

開発の現段階では、G キーを押すことでアイテムを生成できるという効果が得られます。 

この関数を開発した後、ツールチップ プロンプト関数を開発し、UI をアダプティブ テキスト ボックスにすることができます (ここでは、コードを同期するために 2 つのテキストが使用されています)。

ToolTip スクリプト関数は比較的単純で、情報パネルの表示、非表示、および表示内容の変更を担当します (在庫マネージャーで呼び出す必要があります)。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ToolTip : MonoBehaviour
{
    private Text toolTipText;
    private Text contentText;
    private CanvasGroup canvasGroup;

    private float targetAlpha = 0;
    private float smoothing = 6f;
    private void Start()
    {
        toolTipText = GetComponent<Text>();
        contentText=transform.Find("Content").GetComponent<Text>();
        canvasGroup = GetComponent<CanvasGroup>();
    }
    private void Update()
    {
        if(canvasGroup.alpha!=targetAlpha)
        {
            canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, targetAlpha, smoothing * Time.deltaTime);
            if(Mathf.Abs(canvasGroup.alpha-targetAlpha)<0.01f)
            {
                canvasGroup.alpha=targetAlpha;
            }
        }
    }
    public void Show(string text)//显示提示信息
    {
        targetAlpha = 1;
        toolTipText.text = text;
        contentText.text = text;
    }
    public void Hide()//隐藏提示信息
    {
        targetAlpha = 0;
    }
}

プロンプト パネルを作成したら、プロンプト パネルの表示と非表示をトリガーする必要があります。つまり、マウスがスロットに出入りしたときに判断されます (そのため、スロット スクリプトにはマウス用の 2 つのインターフェイスも実装する必要があります)移動インおよびアウトイベント、IPointerEnterHandlerおよびIPointerExitHandler、およびItemスクリプトもここにあります。プロンプトパネルの内容を取得する関数が追加されました)

スロット スクリプトによって追加されるコンテンツは次のとおりです (IPointerEnterHandler、IPointerExitHandler インターフェイスを実装する必要があります)

public void OnPointerExit(PointerEventDataeventData)//マウスアウトイベント
    {         if (transform.childCount > 0)             InventoryManager.Instance.HideToolTip();     }


    public void OnPointerEnter(PointerEventDataeventData)//マウス移動イベント
    {         if(transform.childCount>0)//グリッドには表示する項目が必要です         {             string toolTipText=transform.GetChild(0).GetComponent<ItemUI>().Item .GetToolTipText ();             InventoryManager.Instance.ShowToolTip(toolTipText);         }     }





        

InventoryManager スクリプトに追加する必要があるものは次のとおりです。

 private ToolTip toolTip;//情報パネル

 private void Start()
    {         ParseItemJson();         toolTip=GameObject.Find("ToolTip").GetComponent<ToolTip>();     }


 public void ShowToolTip(string content)//表示情報パネルを呼び出し、コンテンツを割り当てる
    {         isToolTipsShow = true;         toolsTip.Show(content);     }     public void HideToolTip()     {         isToolTipsShow = false;         toolsTip.Hide();     }







アイテムに追加されたスクリプト:

 /// <summary>
    /// プロンプト パネルに表示されるコンテンツを取得します (まだ完成していません。テスト用です)
    /// </summary>
    /// <returns></returns>
    public virtual string GetToolTipText()
    {         名前を返す;     }

 この手順を実行することで得られる効果

 プロンプト パネルの表示と非表示を確認できました。次のステップでは、マウスに続いてプロンプト パネルの効果を実現します。

ToolTip スクリプトにパネルの位置を設定する関数を追加し、それを在庫マネージャーで呼び出すだけです (これには画面座標と四角形座標の変換が必要です)。

ツールチップ スクリプトは以下を追加します。

public void SetClocalPosition(Vector3position)//情報パネルの位置を設定します
    {         transform.localPosition = Position;     }

 InventoryManager スクリプトは以下を追加します。

    private bool isToolTipsShow = false;//パネルを表示するかどうかを尋ねるフラグ
    private Canvas Canvas;
    private Vector2 toolTipPositionOffset = new Vector2(10, -10);//中心軸によって設定された位置のため、この適切な効果を達成するための偏差

  private void Update()//更新時の座標変換と、パネル位置を設定するための呼び出し
    {         if(isToolTipsShow)         {             Vector2 Position;             RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), Input.mousePosition,null, out Position);             toolTip .SetClocalPosition(位置 + ToolTipPositionOffset);         }     }






効果:

 これにより、json アイテム情報の前の部分が改善され、プロンプト パネル情報の内容が改善されます。

改良したjsonファイルの機器構成情報です。

[
  {     "Id": 1,     "Name": "血液ボトル",     "ItemType": 0,     "Quality": 1,     "Description": "これは血液を増やすために使用されます",     "Capacity": 10,     " BuyPrice ": 10,     "SellPrice": 5,     "Sprite": "スプライト/アイテム/hp",     "Hp": 100,     "Mp": 0   },   {     "Id": 2,     "Name": "ブルーボトル " 、     「ItemType」: 0、     「Quality」: 1、     「Description」: 「これは青を追加するためのものです」、     「Capicity」: 10、     「BuyPrice」: 10、     "SellPrice": 5,     "Sprite": "Sprites/Items/mp",     "Hp": 0,     "Mp": 10   },   {


























    "Id": 3、
    "Name": "胸甲"、
    "ItemType": 1、
    "Quality": 2、
    "Description": "这是一个胸甲"、
    "Capacity": 1、
    "BuyPrice": 20 ,
    "SellPrice": 5、
    "Sprite": "精霊/アイテム/防具"、
    "Strength": 10、
    "Intellect": 4、
    "Agility": 9、
    "Stamina": 1、
    "equipType": 2
  },
  {     "Id": 4、     "Name": "皮腰带"、     "ItemType": 1、     "Quality": 3、     "Description":"この革ベルトはスピードアップできます"、     "Capicity": 1、     "BuyPrice": 20、     "SellPrice": 5、     "Sprite": "スプライト/アイテム/ベルト"、     "Strength": 1、










    "知力": 6,
    "敏捷性": 10,
    "スタミナ": 10,
    "equipType": 8
  },
  {     "Id": 5,     "Name": "靴子",     "ItemType": 1,     "Quality": 4、     「説明」:「这靴子带可以加速」、     「容量」:1、     「買値」:20、     「売値」:10、     「スプライト」:「スプライト/アイテム/ブーツ」、     「強さ」:10、     「知力」:5、     「敏捷性」:0、     「スタミナ」:10、     「装備タイプ」:6   }、   {     "Id": 6,     "Name": "リストバンド",     "ItemType": 1,     "Quality": 2,     "Description": "このブレイサーは防御力を高めることができます",





















    「能力」:1、
    「買値」:20、
    「売値」:10、
    「スプライト」:「スプライト/アイテム/ブレイサー」、
    「力」:1、
    「知力」:2、
    「敏捷性」:3、
    「スタミナ」 ": 4,
    "equipType": 5
  },
  {     "Id": 6,     "Name": "护腕",     "ItemType": 1,     "Quality": 2,     "Description": "这个护腕可以增加防御"、     "容量": 1、     "買値": 20、     "売値": 10、     "スプライト": "スプライト/アイテム/ブレイサー"、     「力」:1、     「知力」:2、     「敏捷性」:3、     「スタミナ」:4、     「装備タイプ」:5   }、















  {     "Id": 7,     "Name": "神奇手套",     "ItemType": 1,     "Quality": 0,     "Description": "这是暴击拳套",     "Capicity": 1,     "BuyPrice" :20、     「SellPrice」:5、     「Sprite」:「スプライト/アイテム/グローブ」、     「Strength」:1、     「Intellect」:2、     「Agility」:3、     「Stamina」:4、     「equipType」:9   },   {     "Id": 8,     "Name": "头盔",     "ItemType": 1,     "Quality": 5,     "Description": "这是头盔"、     "Capacity": 1、     "BuyPrice": 10、     "SellPrice": 5、     "Sprite": "スプライト/アイテム/ヘルメット"、

























    "力": 1、
    "知力": 2、
    "敏捷性": 3、
    "スタミナ": 4、
    "equipType": 0
  },
  {     "Id": 9、     "Name": "项链"、     "ItemType": 1、     「品質」: 5、     「説明」: 「これは很厉害的项链」、     「容量」: 1、     「買値」: 10、     「売値」: 5、     「スプライト」: 「スプライト/アイテム/ネックレス」 、     「力」:1、     「知力」:2、     「敏捷性」:3、     「スタミナ」:4、     「装備種類」:1   },   {     "Id": 10,     "Name": "戒指",     "ItemType": 1,     "Quality": 0,





















    "説明": "これは非常に強力なリングです"、
    "容量": 1、
    "買値": 20、
    "売値": 10、
    "スプライト": "スプライト/アイテム/リング"、
    "強さ": 10、
    "知力: 2、
    敏捷性: 3、
    スタミナ: 4、
    装備タイプ: 3
  },
  {     "ID": 11、     "名前": "パンツ"、     "アイテムタイプ": 1、     "品質": 1 、     「説明」: 「これは素晴らしいパンツです」、     「定員」: 1、     「買値」: 40、     「売値」: 20、     「スプライト」:「スプライト/アイテム/パンツ」、     「力」:20、     「知力」:20、     「敏捷性」:20、     「スタミナ」:40、













    "equipType": 4
  },
  {     "Id": 12,     "Name": "肩パッド",     "ItemType": 1,     "Quality": 4,     "Description": "これは非常に強力な肩パッドです",     " 「能力」:1、     「買値」:100、     「売値」:20、     「スプライト」:「スプライト/アイテム/肩」、     「体力」:20、     「知力」:30、     「敏捷性」:40、     「スタミナ」 : 40,     "equipType": 7   },   {     "Id": 13,     "名前": "ブラックカッター",     "ItemType": 2、     "Quality": 2、     "Description": "半肉戦士に適した​​黒のカット"、     "Capicity": 1、     "BuyPrice": 50、     "SellPrice": 20、
























    "Sprite": "スプライト/アイテム/斧",
    "Damage": 100,
    "weaponType": 1
  },
  {     "Id": 14,     "Name": "Storm Greatsword",     "ItemType": 2,     "Quality " : 3、     「説明」: 「インフィニティブレードの作成に使用」、     「容量」: 1、     「買値」: 100、     「売値」: 50、     「スプライト」: 「スプライト/アイテム/剣」、     「ダメージ」: 50,     "weaponType": 0   },   {     "Id": 15,     "Name": "黒霧の合成攻略",     "ItemType": 3,     「品質」: 5、     「説明」: 「黒のカットを鍛造するために使用」、     「容量」: 2、     「買値」: 100、     「売値」: 99、





















    "Sprite": "スプライト/アイテム/本"
  },
  {     "Id": 16,     "Name": "ヘルムの製作レシピ",     "ItemType": 3,     "Quality": 0,     "Description": "使用済みの鍛造ヘルメット",     "Capicity": 2,     "BuyPrice": 50,     "SellPrice": 10,     "Sprite": "スプライト/アイテム/スクロール"   },   {     "Id": 17,     "Name": "Iron" ,     "ItemType ": 3、     "品質": 0、     "説明": "他のものを鍛造するために使用される素材"、     "能力": 20、     "BuyPrice": 5、     "SellPrice": 4、     "Sprite": "スプライト/アイテム/インゴット"   } ]





















 アイテム スクリプトの GetToolTipText() メソッドを改善しました。このメソッドは、さまざまな種類のアイテムをポイントし、さまざまなコンテンツを表示する仮想メソッドとして記述されています。

                カラー = "マゼンタ";                 壊す;




















            case Quality.Legendary:
                color = "オレンジ";
                壊す;
            case Quality.Artifact:
                color = "red";
                壊す;
        }

        string text = string.Format("<color={4}>{0}</color>\n購入価格:{1}販売価格:{2}\n<color= yellow>{3}</color> " 、名前、買値、売値、説明、色);
        テキストを返します;
    }

 次に、各Item 添字の GetToolTipText() メソッドを書き換えて、さまざまな効果を実現します。

たとえば、コンシューマブル スクリプトで GetToolTipText() メソッドをオーバーライドします。

 public オーバーライド string GetToolTipText()
    {         string text=base.GetToolTipText();         string newText=string.Format("{0}\n\n<color=bulue>加血:{1}\n加蓝:{2}</color>",text, HP,Mp);         newText を返します。     }



 その後の装備や材料などの情報の表示も同様であり、具体的な書き換え方法をいちいち示すことはありません(最終版のコードの内容を参照できます)

 これはバックパック システムの追加機能であるため、ステージングされた関数コードの実装は表示されません。必要に応じて、最終的なソース コードに移動してください。

 これを達成したら、次のステップは、機器をクリックしてドラッグすることです。

ここでの一般的な設計アイデアは、マウスの動きに追従する Item オブジェクトを作成し、それを使用して選択されたアイテムを表すことです。選択されたアイテムが選択された場合、pickedItem はスロット内のアイテムになり、次にスロット内の対応するアイテムになります。破壊または削減するには、現在クリックされているスロットのアイテムと、スロット内でマウスを押したときにマウスに追従してきたアイテムを比較して判断することがポイントです(アイテムを破棄する機能もあります)

 ボックスパネル、パネルの表示と非表示は、コードの結合度が高く複雑であるため、現時点で達成できる効果であるため、機能段階のコードは添付されていません(この部分はバックパックの焦点では​​ないため)システム), この部分の焦点はアイデアの紹介です. ソース コードを参照したい場合は、完全に開発されたソース コードが記事の最後にあります。

キャラクターパネルには、対応する装備のみを対応するスロットに装着できる、マウスの右クリックでワンクリックで装備を装着、ワンクリックでアンインストール、装備の交換などの機能が含まれます。

 キャラクターパネル内のすべてのスロットのアイテム属性を走査し、更新関数を定義することで、キャラクターの属性データを開発します。関数の内容は、キャラクターパネルのすべてのスロットのアイテム属性を走査してそれらを合計することです(したがって、更新の必要はありません)装備を着用するか、装備を脱ぐかを区別します)

 次のステップはストア機能を作成することです。これには、商品の売買、すべての販売、および一部の販売の機能が含まれます。

鍛造システムでは、鍛造システムの設計にはレシピクラスが必要です。レシピクラスには素材のID番号と合成結果のIDが必要です。そして、json形式で設定ファイルが生成されます。jsonファイルの内容はレシピクラスを格納する配列; 鍛造関数 核となるのは、鍛造をクリックしたときの照合に数式配列を使用することです (アルゴリズムの鍵は、手持ちのアイテムのリストとアイテムのリストという 2 つのリストの照合にあります)チートに必要)

 保存およびロード機能。この部分の機能の主な原理は、パネル内のすべてのグリッドの項目を読み取り、文字列の形式で保存し (各グリッドの内容を保存する必要があります)、その後分割を使用することです。異なる文字列コンテンツに従ってグリッドを分割し、最終的に異なる操作を実行します。

 ここでバックパックシステム全体が完成します。バックシステムの追加機能についてはコードは添付されていません。ソースコードを参照できます。(ソースコード内に詳細なコメントがありますので、ソースコードを読むことをお勧めします)

バックパックシステムの核となる機能のデザイン、アイデアを整理する

1. 1 つ目はアイテム クラスの設計です。アイテム クラスは親クラスです。すべての武器クラス、装備クラス、供給カテゴリなどはアイテムから継承されます (アイテムを区別する唯一の識別子は ID)。武器クラス、装備クラスなどにも独自の特性があります。

2. 各アイテム クラスを設計した後、アイテムの構成情報をゲームに読み込み、アイテム情報を json ファイルに構成して、それをゲームで解析する必要があります。json 構成ファイルはアイテムのすべてのアイテムであるためです。サブクラス、コレクションを使用してすべてのアイテムのサブクラスを保存したい場合は、 itemList<Item> リスト コレクションを作成する必要があり、受信したオブジェクトはアイテム クラスです (アイテムのサブクラスも含めることができます。ここでは を参照してください)。上記の変換)、親クラスの List を使用してすべてのサブクラスの装備が保存されるようにします (具体的な実装については、上記の記事を参照してください)。

3. すべての装備情報を解析した後、アイテムの移動やアイテムの取得など、パネルとアイテムの間のインタラクションを実現するために、アイテムスロットとアイテムの構造を設計する必要があります。アイテムスロットとアイテムは作成されます。インタラクションなどの機能を実装する場合 (アイテムをスロットに保存するなど、ロジックはアイテムをスロットのサブオブジェクトとして設定し、ローカル座標を 0 に変更することです)、複数のパネル (バックパック、ストア、その他のパネルなど) を作成する必要がある場合は、Inventory 親クラス (すべてのパネルの親クラス) が必要です。異なるサブクラスを持つパネルは異なる機能を持ち、個別に設定できます。

おすすめ

転載: blog.csdn.net/qq_62947569/article/details/131741190