一、开发操作
1、创立Iventory Manager 文件办理数据,并增加InventoryManager脚本
2、创立ItemBase文件,增加Item脚本
二、脚本编程
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_SO
和 ItemDetails
是两个用于存储物品数据的结构体,别离表明物品列表和物品详细信息。
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)