Unity 3 D(UGUI)ベースのリュックサックシステム完結編


         (UI)      ,           (             )。PS:      UML    。


**①      :        Json     。**
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

/// 
///       
/// 
public class InventroyManager : MonoBehaviour {
    //    
    private static InventroyManager _instance;
    public static InventroyManager Instance 
    {
        get {
            if (_instance == null)
            {
                _instance = GameObject.Find("InventroyManager").GetComponent();
            }
           return _instance;
        }
    }
    private List itemList;//  json         

    private ToolTip toolTip;//  ToolTip  ,      
    private bool isToolTipShow = false;//          
    private Canvas canvas;//Canva  
    private Vector2 toolTipOffset =new Vector2(15, -10);//              

    private ItemUI pickedItem;//            ,         
    public ItemUI PickedItem { get { return pickedItem; } }
    private bool isPickedItem = false;//         
    public bool IsPickedItem { get { return isPickedItem; } }

    void Awake() 
    {
        ParseItemJson();
    }

    void Start() 
    {
        toolTip = GameObject.FindObjectOfType();//      
        canvas = GameObject.Find("Canvas").GetComponent();
        pickedItem = GameObject.Find("PickedItem").GetComponent();
        pickedItem.Hide();//       
    }

    void Update() 
    {
        if (isToolTipShow == true && isPickedItem == false) //           
        {
            Vector2 postionToolTip;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out postionToolTip);
            toolTip.SetLocalPosition(postionToolTip+toolTipOffset);//        ,               Z   0
        }
        else if (isPickedItem == true) //         UI      
        {
            Vector2 postionPickeItem;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out postionPickeItem);
            pickedItem.SetLocalPosition(postionPickeItem);//       ,               Z   0
        }
        //      :
        if (isPickedItem == true && Input.GetMouseButtonDown(0) && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(-1) == false )//UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(-1) == false            UI 
        {
            isPickedItem = false;
            pickedItem.Hide();
        }
    }

    /// 
    ///   Json  
    /// 
    public void ParseItemJson() 
    {
        itemList = new List();
        //   unity   TextAsset  
        TextAsset itemText = Resources.Load("Item");//  json  
        string itemJson = itemText.text;//  json       
        //bug.Log(itemJson);
        JSONObject j = new JSONObject(itemJson);
        foreach (var temp in j.list)
        {
            //              
            Item.ItemType type = (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), temp["type"].str);
            //print(type);
            //             :id,name,quality。。。 :temp["id"].n   .n,.str  json     ,    
            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 equiType = (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,equiType);
                    break;
                case Item.ItemType.Weapon:
                    int damage = (int)(temp["damage"].n);
                    Weapon.WeaponType weaponType = (Weapon.WeaponType)System.Enum.Parse(typeof(Weapon.WeaponType), temp["weaponType"].str);
                    item = new Weapon(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, damage, weaponType);
                    break;
                case Item.ItemType.Material:
                    item = new Material(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite);
                    break;
            }
            itemList.Add(item);//                 
            //Debug.Log(item);
        }
    }

    //     id   Item
    public Item GetItemById(int id) 
    {
        foreach (Item item in itemList)
        {
            if (item.ID == id)
            {
                return item;
            }
        }
        return null;
    }

    //       
    public void ShowToolTip(string content) 
    {
        if (this.isPickedItem == true) return;//             ,            
        toolTip.Show(content);
        isToolTipShow = true;
    }
    //       
    public void HideToolTip() {
        toolTip.Hide();
        isToolTipShow = false;
    }

    //  (  )          (amount)  UI
    public void PickUpItem(Item item,int amount)
    {
        PickedItem.SetItem(item, amount);
        this.isPickedItem = true;
        PickedItem.Show();//               (            )    
        this.toolTip.Hide();//           

        //         UI      
            Vector2 postionPickeItem;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out postionPickeItem);
            pickedItem.SetLocalPosition(postionPickeItem);//       ,               Z   0

    }

    //      (  )       
    public void ReduceAmountItem(int amount = 1) 
    {
        this.pickedItem.RemoveItemAmount(amount);
        if (pickedItem.Amount <= 0)
        {
            isPickedItem = false;
            PickedItem.Hide();//               
        }
    }

    //      ,        
    public void SaveInventory() 
    {
        Knapscak.Instance.SaveInventory();
        Chest.Instance.SaveInventory();
        CharacterPanel.Instance.SaveInventory();
        Forge.Instance.SaveInventory();
        PlayerPrefs.SetInt("CoinAmount", GameObject.FindGameObjectWithTag("Player").GetComponent().CoinAmount);//      
    }

    //      ,      
    public void LoadInventory() 
    {
        Knapscak.Instance.LoadInventory();
        Chest.Instance.LoadInventory();
        CharacterPanel.Instance.LoadInventory();
        Forge.Instance.LoadInventory();
        //      
        if (PlayerPrefs.HasKey("CoinAmount") == true)
        {
            GameObject.FindGameObjectWithTag("Player").GetComponent().CoinAmount = PlayerPrefs.GetInt("CoinAmount");
        }
    }
}

②物品槽基类(Slot):重点实现了物品槽里物品的各个交互功能

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

/// 
///     
/// 
public class Slot : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler{

    public GameObject itemPrefab;//         

    /// 
    ///(  )        (  )  ,         Item ,  Item.amount++;
    ///     ,    ItemPrefab      Item,     
    /// 
    public void StoreItem(Item item) 
    {
        if (this.transform.childCount == 0)//            ,         
        {
            GameObject itemGO = Instantiate(itemPrefab) as GameObject;
            itemGO.transform.SetParent(this.transform);//            
            itemGO.transform.localScale = Vector3.one;//           
            itemGO.transform.localPosition = Vector3.zero;//         ,            
            itemGO.GetComponent().SetItem(item);//  ItemUI
        }
        else
        {
            transform.GetChild(0).GetComponent().AddItemAmount();//      
        }
    }

    //                  
    public Item.ItemType GetItemType() 
    {
        return transform.GetChild(0).GetComponent().Item.Type;
    }

    //                ID
    public int GetItemID()
    {
        return transform.GetChild(0).GetComponent().Item.ID;
    }

    //                Capacity
    public bool isFiled() 
    {
        ItemUI itemUI = transform.GetChild(0).GetComponent();
        return itemUI.Amount >= itemUI.Item.Capacity; //true            ,false          
    }

    //       ,       
    public void OnPointerEnter(PointerEventData eventData)
    {
        if (this.transform.childCount > 0)
        {
            string toolTipText = this.transform.GetChild(0).GetComponent().Item.GetToolTipText();
            InventroyManager.Instance.ShowToolTip(toolTipText);//     
        }
    }
    //       ,       
    public void OnPointerExit(PointerEventData eventData)
    {
        if (this.transform.childCount > 0)
        {
            InventroyManager.Instance.HideToolTip();//     
        }
    }

    public virtual void OnPointerDown(PointerEventData eventData)//    ,    EquipmentSlot  
    {
        if (eventData.button == PointerEventData.InputButton.Right)//            ,     
        {
            if (transform.childCount > 0 && InventroyManager.Instance.IsPickedItem == false)//         ,          ,     :       ,                    。
            {
                ItemUI currentItemUI = transform.GetChild(0).GetComponent();
                if (currentItemUI.Item is Equipment || currentItemUI.Item is Weapon)//            
                {
                    Item currentItem = currentItemUI.Item;//        ,    UI         
                    currentItemUI.RemoveItemAmount(1);//           1 
                    if (currentItemUI.Amount <= 0)//          
                    {
                        DestroyImmediate(currentItemUI.gameObject);//           
                        InventroyManager.Instance.HideToolTip();//         
                    }
                    CharacterPanel.Instance.PutOn(currentItem);//    
                }
            }
        }
        if (eventData.button != PointerEventData.InputButton.Left) return;  //              
        //      :
        // :    
                ///1.pickedItem != null( IsPickedItem == true),pickedItem      
                        ////①  Ctrl ,             
                        ////②    Ctrl ,            
                ///2.pickedItem==null( IsPickedItem == false),      
        // :     
                ///1.pickedItem != null(  IsPickedItem == true)
                        ////①   id == pickedItem.id
                                //////A.  Ctrl ,             
                                //////B.    Ctrl ,            
                                       ///////a.      
                                       ///////b.         
                        ////②   id != pickedItem.id,pickedItem       
               ///2.pickedItem == null( IsPickedItem == false)
                        ////①  Ctrl ,             
                        ////②    Ctrl ,                

        if (transform.childCount > 0) // :     
        {
            ItemUI currentItem = transform.GetChild(0).GetComponent();//       
            if (InventroyManager.Instance.IsPickedItem == false)///2.pickedItem == null。            ,          
            {
                if (Input.GetKey(KeyCode.LeftControl))////①  Ctrl ,             
                {
                    int amountPicked = (currentItem.Amount + 1) / 2;//              ,             
                    InventroyManager.Instance.PickUpItem(currentItem.Item, amountPicked);
                    int amountRemained = currentItem.Amount - amountPicked;//          
                    if (amountRemained<=0)//              ,   ItemUI
                    {
                        Destroy(currentItem.gameObject);
                    }
                    else//             ,              
                    {
                        currentItem.SetAmount(amountRemained);
                    }
                }
                else      ////②    Ctrl ,                
                {
                    //InventroyManager.Instance.PickedItem.SetItemUI(currentItem);//             PickedItem(      )
                    //InventroyManager.Instance.IsPickedItem = true;//              
                    InventroyManager.Instance.PickUpItem(currentItem.Item, currentItem.Amount);
                    Destroy(currentItem.gameObject);//                
                }
            }
            else
            {
                ///1.pickedItem != null(  IsPickedItem == true)
                    ////①   id == pickedItem.id
                        //////A.  Ctrl ,             
                        //////B.    Ctrl ,            
                                 ///////a.      
                                 ///////b.         
                ////②   id != pickedItem.id,pickedItem       
                if (currentItem.Item.ID == InventroyManager.Instance.PickedItem.Item.ID)
                {
                    if (Input.GetKey(KeyCode.LeftControl))
                    {
                        if (currentItem.Item.Capacity > currentItem.Amount)//                   ,            
                        {
                            currentItem.AddItemAmount();//          
                            InventroyManager.Instance.ReduceAmountItem();//           (      )
                        }
                        else//                   ,             
                        {
                            return;
                        }
                    }
                    else 
                    {
                        if (currentItem.Item.Capacity > currentItem.Amount)//                   ,            
                        {
                            int itemRemain = currentItem.Item.Capacity - currentItem.Amount;//           
                            if (itemRemain >= InventroyManager.Instance.PickedItem.Amount)//                       ,                                        
                            {
                                currentItem.AddItemAmount(InventroyManager.Instance.PickedItem.Amount);
                                InventroyManager.Instance.ReduceAmountItem(itemRemain);
                            }
                            else//         
                            {
                                currentItem.AddItemAmount(itemRemain);
                                InventroyManager.Instance.PickedItem.RemoveItemAmount(itemRemain);
                            }
                        }
                        else//                   ,             
                        {
                            return;
                        }
                    }
                }
                else//②   id != pickedItem.id,pickedItem       
                {
                    //          ,            
                    Item pickedItemTemp = InventroyManager.Instance.PickedItem.Item;
                    int pickedItemAmountTemp = InventroyManager.Instance.PickedItem.Amount;

                    //           ,           
                    Item currentItemTemp = currentItem.Item;
                    int currentItemAmountTemp = currentItem.Amount;
                    //    
                    currentItem.SetItem(pickedItemTemp, pickedItemAmountTemp);//              
                    InventroyManager.Instance.PickedItem.SetItem(currentItemTemp, currentItemAmountTemp);//               
                }
            }
        }
        else// :    
        { 
            ///1.pickedItem != null( IsPickedItem == true),pickedItem      
                ////①  Ctrl ,             
                ////②    Ctrl ,            
            ///2.pickedItem==null( IsPickedItem == false),      
            if (InventroyManager.Instance.IsPickedItem == true)
            {
                if (Input.GetKey(KeyCode.LeftControl))
                {
                    this.StoreItem(InventroyManager.Instance.PickedItem.Item);
                    InventroyManager.Instance.ReduceAmountItem();
                }
                else//②    Ctrl ,            
                {
                    for(int i = 0 ; ithis.StoreItem(InventroyManager.Instance.PickedItem.Item);
                    }
                    InventroyManager.Instance.ReduceAmountItem(InventroyManager.Instance.PickedItem.Amount);
                }
            }
            else
            {
                return;
            }
        }
    }
}

③处理角色面板的物品槽类(EquipmentSlot),继承自Slot类:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

/// 
///               (      Slot:      ),                  。
/// 
public class EquipmentSlot :Slot
{
    public Equipment.EquipmentType equipmentSoltType;//               。                 ,      ,   ,       ,          。       。
    public Weapon.WeaponType wpType;//    ,           ,   Null



    public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)//    Slot   
    {
        if (eventData.button == PointerEventData.InputButton.Right)//            ,     
        {
            if (transform.childCount > 0 && InventroyManager.Instance.IsPickedItem == false)//         ,          ,     :       ,                    。
            {
                ItemUI currentItemUI = transform.GetChild(0).GetComponent();
                Item item = currentItemUI.Item;//        ,          
                DestroyImmediate(currentItemUI.gameObject);//           
                transform.parent.SendMessage("PutOff", item);//         (      )
                InventroyManager.Instance.HideToolTip();//         
            }
        }
        if (eventData.button != PointerEventData.InputButton.Left) return;  //              
        //    :
                // :      
                        //1.        
                        //2.        
               // :       
                        //1.        
                       //2.        (      )
        bool isUpdataProperty = false;//          
        if (InventroyManager.Instance.IsPickedItem == true)// :      
        {
            ItemUI pickedItemUI = InventroyManager.Instance.PickedItem;//      
            if (transform.childCount > 0)//1.        
            {
                ItemUI currentItemUI = transform.GetChild(0).GetComponent();//         
                if (IsRightItem(pickedItemUI.Item) && pickedItemUI.Amount == 1)//                              ,    ,      
                {
                    pickedItemUI.Exchange(currentItemUI);
                    isUpdataProperty = true;//        
                }
            }
            else//2.        
            {
                if (IsRightItem(pickedItemUI.Item))//                 ,            ,            ,      
                {
                    this.StoreItem(pickedItemUI.Item);
                    InventroyManager.Instance.ReduceAmountItem(1);
                    isUpdataProperty = true;//        
                }
            }
        }
        else// :       
        {
            if (transform.childCount>0) //1.        ,        ,         
            {
                ItemUI currentItemUI = transform.GetChild(0).GetComponent();
                InventroyManager.Instance.PickUpItem(currentItemUI.Item, currentItemUI.Amount);
                Destroy(currentItemUI.gameObject);
                isUpdataProperty = true;//        
            } //2.        (      )
        }
        if (isUpdataProperty == true)
        {
            transform.parent.SendMessage("UpdatePropertyText");
        }
    }

    //                 
    public bool IsRightItem(Item item) 
    {
        if ((item is Equipment && ((Equipment)(item)).EquipType == this.equipmentSoltType) || (item is Weapon && ((Weapon)(item)).WpType == this.wpType))//                                                                    ,           ,     。
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

④处理商店购买物品面板的物品槽类(VendorSlot),同样继承自Slot类:

using UnityEngine;
using System.Collections;

public class VendorSlot : Slot {

    //    Slot       ,        ,       ,       
    public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)
    {
        if (eventData.button == UnityEngine.EventSystems.PointerEventData.InputButton.Right)//               
        {
            if (transform.childCount > 0 && InventroyManager.Instance.IsPickedItem == false)//        ,         
            {
                Item currentItem = transform.GetChild(0).GetComponent().Item;//            
                transform.parent.parent.SendMessage("BuyItem",currentItem);
            }
        }
        else if (eventData.button == UnityEngine.EventSystems.PointerEventData.InputButton.Left && InventroyManager.Instance.IsPickedItem == true)//             
        {
            transform.parent.parent.SendMessage("SellItem");
        }
    }
}

⑤物品UI処理類(ItemUI):using UnityEngine; using System.Collections; using UnityEngine.UI; public class ItemUI : MonoBehaviour { public Item Item { get; private set; } //UI public int Amount { get; private set; }// private Image itemImage;// item Image private Text amountText;// item private float targetScale = 1f;// private Vector3 animationScale = new Vector3(1.4f, 1.4f, 1.4f); private float smothing = 4f;// void Awake() // get { itemImage = this.GetComponent(); amountText = this.GetComponentInChildren(); } void Update() { if (this.transform.localScale.x != targetScale)// { float scaleTemp = Mathf.Lerp(this.transform.localScale.x, targetScale, smothing*Time.deltaTime); this.transform.localScale = new Vector3(scaleTemp, scaleTemp, scaleTemp); if (Mathf.Abs(transform.localScale.x-targetScale) < 0.02f)// , , { this.transform.localScale = new Vector3(targetScale, targetScale, targetScale); } } } /// /// item UI , 1 /// /// public void SetItem(Item item, int amount = 1) { this.transform.localScale = this.animationScale;// UI, this.Item = item; this.Amount = amount; this.itemImage.sprite = Resources.Load(item.Sprite); // UI if (this.Amount > 1) { this.amountText.text = Amount.ToString(); } else { this.amountText.text = ""; } } /// /// item /// /// public void AddItemAmount(int num = 1) { this.transform.localScale = this.animationScale;// UI, this.Amount += num; if (this.Amount> 1)// UI { this.amountText.text = Amount.ToString(); } else { this.amountText.text = ""; } } // item public void SetAmount(int amount) { this.transform.localScale = this.animationScale;// UI, this.Amount = amount; if (this.Amount > 1)// UI { this.amountText.text = Amount.ToString(); } else { this.amountText.text = ""; } } // public void RemoveItemAmount(int amount = 1) { this.transform.localScale = this.animationScale;// UI, this.Amount -= amount; if (this.Amount > 1)// UI { this.amountText.text = Amount.ToString(); } else { this.amountText.text = ""; } } // public void Show() { gameObject.SetActive(true); } // public void Hide() { gameObject.SetActive(false); } // public void SetLocalPosition(Vector3 position) { this.transform.localPosition = position; } // (UI) (UI) public void Exchange(ItemUI itemUI) { Item itemTemp = itemUI.Item; int amountTemp = itemUI.Amount; itemUI.SetItem(this.Item, this.Amount); this.SetItem(itemTemp, amountTemp); } }
⑥情報提示枠類(Tooltip)、提示枠の各種機能を処理する:using UnityEngine; using System.Collections; using UnityEngine.UI; /// /// /// public class ToolTip : MonoBehaviour { private Text toolTipText;// Text, private Text contentText;// Text, private CanvasGroup toolTipCanvasGroup;// CanvasGroup , private float targetAlpha = 0.0f ;// Alpha ,0 ,1 public float smothing = 1.0f;// void Awake() { toolTipText = this.GetComponent(); contentText = this.transform.Find("Content").GetComponent(); toolTipCanvasGroup = this.GetComponent(); } // Update is called once per frame void Update () { if (toolTipCanvasGroup.alpha != targetAlpha) { toolTipCanvasGroup.alpha = Mathf.Lerp(toolTipCanvasGroup.alpha, targetAlpha, smothing*Time.deltaTime); if (Mathf.Abs(targetAlpha - toolTipCanvasGroup.alpha) < 0.01f)// Alpha Alpha , { toolTipCanvasGroup.alpha = targetAlpha; } } } // public void Show(string text) { this.toolTipText.text = text; this.contentText.text = text; this.targetAlpha = 1; } // public void Hide() { this.targetAlpha = 0; } // public void SetLocalPosition(Vector3 postion) { this.transform.localPosition = postion; } }
⑦模擬主役行為類(Player):using UnityEngine; using System.Collections; using UnityEngine.UI; /// /// /// public class Player : MonoBehaviour { // : private int basicStrength = 10; public int BasicStrength { get { return basicStrength;} }// private int basicIntellect = 10; public int BasicIntellect { get { return basicIntellect; } }// private int basicAgility = 10; public int BasicAgility { get { return basicAgility; } }// private int basicStamina = 10; public int BasicStamina { get { return basicStamina; } }// private int basicDamage = 10; public int BasicDamage { get { return basicDamage; } }// private Text coinText;// Text private int coinAmount = 100;// , public int CoinAmount { get { return coinAmount; } set { coinAmount = value; coinText.text = coinAmount.ToString(); } } // Use this for initialization void Start () { coinText = GameObject.Find("Coin").GetComponentInChildren(); coinText.text = coinAmount.ToString(); } // Update is called once per frame void Update () { // G if (Input.GetKeyDown(KeyCode.G)) { int id = Random.Range(1, 23); Knapscak.Instance.StoreItem(id); } // B if (Input.GetKeyDown(KeyCode.B)) { Knapscak.Instance.DisplaySwitch(); } // H if (Input.GetKeyDown(KeyCode.H)) { Chest.Instance.DisplaySwitch(); } // V if (Input.GetKeyDown(KeyCode.V)) { CharacterPanel.Instance.DisplaySwitch(); } // N if (Input.GetKeyDown(KeyCode.N)) { Vendor.Instance.DisplaySwitch(); } // M if (Input.GetKeyDown(KeyCode.M)) { Forge.Instance.DisplaySwitch(); } } // public bool ConsumeCoin(int amount) { if (coinAmount >= amount) { coinAmount -= amount; coinText.text = coinAmount.ToString();// return true;// } return false;// } // public void EarnCoin(int amount) { this.coinAmount += amount; coinText.text = coinAmount.ToString();// } }
はい、比較的完全なリュックサックシステムが整理されました.もしその中に間違いがあったら、私とすぐに連絡して修正してください.あなたと交流することを期待しています.ソースプロジェクトの工事が必要な場合は、メッセージを残してください.