Unity3D 游戏开发:物品在界面中显示功能逻辑(19)

2,137 阅读7分钟

一、开发操作

1、创建Iventory Manager 文件管理数据,并添加InventoryManager脚本

image.png

image.png

2、创建ItemBase文件,添加Item脚本

image.png

image.png image.png

二、脚本编程

1、InventoryManager C#文件

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

namespace MFarm.Iventory
{  
    public class InventoryManager : Singleton<InventoryManager>
    {
        public ItemDataList_SO itemDataList_SO;

        public ItemDetails GetItemDetails(int ID)
        {
            return itemDataList_SO.itemDetailsList.Find(i=>i.itemID==ID);      
        }

    }
}

这段代码定义了一个名为 InventoryManager 的类,用于管理游戏中的物品,是单例模式的实现类。

  • namespace MFarm.Inventory { },定义了该类所在的命名空间为 MFarm.Iventory,这是一种组织代码的方式,用于避免不同类之间命名冲突的情况。

  • public class InventoryManager : Singleton<InventoryManager> { },定义了一个名为 InventoryManager 的公共类,并继承自 Singleton<InventoryManager> 类,从而实现单例模式。InventoryManager 类有以下两个字段和方法:

    • public ItemDataList_SO itemDataList_SO;,定义了一个公共的 ItemDataList_SO 类型的字段 itemDataList_SO,用于存储所有物品的详细信息列表。
    • public ItemDetails GetItemDetails(int ID) { },定义了一个公共方法 GetItemDetails,它接收一个整数类型的参数 ID,用于根据物品 ID 号获取该物品的详细信息。在该方法内部,它使用 itemDataList_SO.itemDetailsList.Find() 方法来查找并返回 itemDataList_SO 中符合条件的物品详细信息。其中,itemDataList_SO.itemDetailsList 表示从 ItemDataList_SO 中获取物品详细信息列表,而 Find(i=>i.itemID==ID) 表示在该列表中查找符合 itemID 与参数 ID 相等的物品详细信息。
  • Singleton<InventoryManager> 则是一个自定义的泛型类,实现了单例模式。它具有以下功能:

    • private static T _instance;,定义了一个私有静态泛型字段 _instance,用于存储单例对象的引用。
    • public static T Instance { get { return _instance; } },定义了一个公共静态泛型属性 Instance,用于获取单例对象的唯一入口。如果 _instance 为 null,则通过 GameObject.FindObjectOfType<T>() 方法查找场景中是否已经存在该类型的单例对象。如果不存在,则使用 new GameObject().AddComponent<T>() 方法创建一个新的游戏对象并添加该类型的组件,将其作为单例对象并返回;否则直接返回已存在的单例对象。
  • ItemDataList_SO 和 ItemDetails 是两个自定义的数据结构,分别表示物品列表和物品详细信息。其中,itemDetailsList 是 ItemDataList_SO 的公共字段,表示物品详细信息的列表。ItemDetails 包括了物品的 ID 号、物品名称、物品图标和物品描述等相关信息。

综上,InventoryManager 类是一个用于管理游戏中的物品的类,使用单例模式实现。它包括了存储所有物品的详细信息列表、根据物品 ID 号获取物品详细信息的方法以及单例对象的创建和获取等功能。ItemDataList_SOItemDetails 是两个用于存储物品数据的结构体,分别表示物品列表和物品详细信息。

2、Singleton C#文件,单例

using UnityEngine;

public class Singleton <T>: MonoBehaviour where T : Singleton <T>
{
    private static T instance;
        
    public static T Instance
    { 
        get => instance; 
    }
    protected virtual void Awake()
    {
        if (instance != null)
            Destroy(gameObject);
        else 
            instance = (T)this;
    }

    protected virtual void OnDestory()
    { 
        if(instance==this)
            instance = null;
    }
}

这段代码实现了一个单例模式的基类 Singleton<T>,使用泛型来实现多个不同类的单例。下面是逐行解释每个参数的含义和功能:

  • using UnityEngine; 引入 Unity 引擎的命名空间。
  • public class Singleton<T> : MonoBehaviour where T : Singleton<T> 定义了一个公共类 Singleton<T>,它继承自 Unity 引擎的组件(Component)基类 MonoBehaviour,并使用泛型类型参数 <T>,确保只有继承自 Singleton <T> 的子类才能使用此单例模板。定义中使用 where T : Singleton<T> 约束,强制所有声明为 Singleton<T> 泛型类型参数的类都必须继承自 Singleton<T>
  • private static T instance; 定义一个私有静态字段 instance,用于存储单例对象的唯一实例。
  • public static T Instance { get => instance; } 定义一个公共静态属性 Instance,它返回 instance 字段的值。在其他类中只需调用 Singleton<T>.Instance 即可获取 T 类型的唯一实例对象。
  • protected virtual void Awake() 定义了一个受保护的虚方法 Awake(),它在脚本对象被创建时自动调用。在该方法中,如果 instance 字段已经被赋值,说明该类型的对象已经存在,当前对象不是唯一实例,因此需要销毁该对象;否则将当前对象的引用赋值给 instance 字段。
  • protected virtual void OnDestroy() 定义了一个受保护的虚方法 OnDestroy(),它在脚本对象被销毁时自动调用。在该方法中,如果 instance 字段的值等于当前对象,则将 instance 字段置为 null,以确保下次获取单例对象的时候能够重新创建新的实例。

这段代码实现了基于泛型的单例模式,可以用于多个不同的类中。Singleton<T> 类中定义了一个静态的 instance 字段,用于保存唯一实例的引用,并提供了一个公共的 Instance 属性,让其他类可以获取这个唯一实例。在 Awake() 方法中,会判断 instance 是否已经被赋值,如果是,则销毁当前对象,如果不是,则将当前对象的引用赋值给 instance 字段。在 OnDestroy() 方法中,会判断 instance 是否等于当前对象,如果是,则将 instance 置为 null,以便下次获取实例时可以再次创建。

3、Item C#文件

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

namespace MFarm.Iventory
{
    public class Item : MonoBehaviour
    {
        public int itemID;

        private SpriteRenderer spriteRenderer;

        private ItemDetails itemDetails;

        private BoxCollider2D coll;


        private void Awake()
        {
            spriteRenderer = GetComponentInChildren <SpriteRenderer>();

            coll = GetComponent<BoxCollider2D>();
        }

        private void Start()
        {
            if (itemID !=0)
            {
              Init(itemID );
            }
        }

        public void Init(int ID)
        { 
            itemID = ID;

            itemDetails = InventoryManager.Instance.GetItemDetails(itemID);

            if (itemDetails != null)
            {
                spriteRenderer.sprite = itemDetails.itemOnWorldSprite != null ? itemDetails.itemOnWorldSprite :itemDetails.itemIcon ;

                //修改Box Collider尺寸
                Vector2 newSize = new Vector2(spriteRenderer.sprite.bounds.size.x, spriteRenderer.sprite.bounds.size.y);
                coll.size = newSize;
                coll.offset = new Vector2(0,spriteRenderer.sprite.bounds .center.y );
            }
        }
    }
}

这段代码定义了一个名为 Item 的类,用于在游戏中表示一个物品。

  • namespace MFarm.Iventory { },定义了该类所在的命名空间为 MFarm.Iventory,这是一种组织代码的方式,用于避免不同类之间命名冲突的情况。

  • public class Item : MonoBehaviour { },定义了一个名为 Item 的公共类,并继承自 MonoBehaviour 类,从而使该类可以被添加到 Unity 的 GameObject 上。Item 类有以下四个成员:

    • public int itemID;,定义了一个公共整数类型的字段 itemID,表示该物品的 ID 号。
    • private SpriteRenderer spriteRenderer;,定义了一个私有的 SpriteRenderer 类型的字段 spriteRenderer,用于引用和修改该物品的 Sprite 渲染组件。
    • private ItemDetails itemDetails;,定义了一个私有的 ItemDetails 类型的字段 itemDetails,用于存储该物品的详细信息。
    • private BoxCollider2D coll;,定义了一个私有的 BoxCollider2D 类型的字段 coll,用于引用和修改该物品的碰撞盒组件。
    • private void Awake() { },定义了一个私有方法 Awake(),它会在对象被创建后立即执行。在该方法内部,它使用 GetComponentInChildren<T>() 方法来获取该物品的 Sprite 渲染组件和碰撞盒组件,分别存储到 spriteRenderer 和 coll 字段中。
    • private void Start() { },定义了一个私有方法 Start(),它会在对象被启用后立即执行。在该方法内部,如果 itemID 不为 0,则调用 Init(itemID) 方法来初始化该物品的数据。
    • public void Init(int ID) { },定义了一个公共方法 Init,它接收一个整数类型的参数 ID,用于初始化该物品的数据。在该方法内部,它首先将 ID 存储到 itemID 字段中,并调用 InventoryManager.Instance.GetItemDetails(itemID) 方法来获取该物品的详细信息。如果成功获取到了详细信息,则根据详细信息中的 Sprite 渲染组件来更新该物品的 Sprite 渲染器,并根据 Sprite 渲染器的尺寸动态修改碰撞盒的大小和偏移量。

Item 类是一个用于表示游戏中物品的类,它包含了物品的 ID 号、Sprite 渲染器、碰撞盒组件以及物品的详细信息等数据。在 Awake() 方法中,它使用 GetComponentInChildren<T>() 方法获取该物品的 Sprite 渲染器和碰撞盒组件;在 Start() 方法中,如果该物品的 ID 号不为 0,则调用 Init(itemID) 方法来初始化该物品的数据;在 Init(int ID) 方法中,它使用 InventoryManager.Instance.GetItemDetails(itemID) 方法获取该物品的详细信息,并根据详细信息来更新该物品的 Sprite 渲染器和碰撞盒组件,以便在游戏中正确地显示该物品的外观和尺寸。

三、初步了解脚本编程

未完待续......

阅读更多作者文章:

# Unity3D 游戏开发:物品数据库填写规则(18)