[unity learning] RPG Leaning(四)
写这个文章的目的就是为了初学unity,然后更好的掌握unity中的内容【主要是代码】
学习unity的途径是Brackeys 的教程;
接上篇: unity learning RPG Leaning(三).
本次目标
这次的目标就是做一个Item类和一个Inventory类;
场景:点击物体,当player到该物体附近后,使物体从世界中消失,并放入到Inventory(库存)中。
具体实现流程
一、创建一个cube,应用一个script类:ItemPickup,ItemPickup为继承Interactable类的类。
Interactable类中的方法Interative() 要复写
Interactable类:
public virtual void Interative()
{
//this method is meant to be overwritten
Debug.Log("Interactive with " + transform.name);
}
ItemPickup:
public override void Interative()
{
base.Interative();
PickUp(); //调用自身一个方法
}
二、创建一个Item类,作用:这里的类是一个对象,所以在创建这个类的时候,应该为
public class Item : ScriptableObject{ … },这个对象里面放置所需要的各个物体参数:例如名字、是否为默认的Item等;
这里值得注意的是一个unity 类型:Sprite(雪碧??哈哈哈哈哈)
public Sprite icon = null;
这里是第一次知道这个类型,Sprite类型是和UI界面有关,具体的可以参考
CSDN: Sprite 和Texture 的区别.
Unity:unity.Api.
三、把这个物体放到unity的create菜单中
[CreateAssetMenu(fileName = “New Item”, menuName = “Inventory/Item”)]
//效果如图所示,New Item就是创建的Item的name属性,menuName就是放置的位置了。
四、绑定Item到ItemPickup类中:
public Item item;//就只有这样而已,就把Item类放了出来,在界面中手动绑定就好了
五、创建一个GameManager(Empty)到世界中,然后添加一个Inventory类。作为Item的容器:添加Item、移除Item
注意的是
1、C#中的数组对象的使用方法和Java类似:
public List<Item> items = new List<Item>();
且需要用到using System.Collections.Generic;
2、我们需要抛出这个Inventory类中一个实体到世界;
所以我们使用了Awake()的方法:
*
在加载场景时初始化包含脚本的活动GameObject时,或者在将先前非活动的GameObject设置为活动时,或者在初始化用Object.Instantiate创建的GameObject之后,将调用Awake
。在应用程序启动之前,使用Awake初始化变量或状态。在脚本实例的生存期内, Unity
仅调用一次Awake。脚本的生命周期将持续到卸载包含脚本的场景为止。如果再次加载场景,则Unity将再次加载脚本实例,因此将再次调用Awake。如果场景多次加载,则Unity会加载多个脚本实例,因此请唤醒将被调用多次(每个实例一次)。
Unity:MonoBehaviour.Awake().
所以在Awake中创建实体;指向自己:
void Awake()
{
if (instance != null)
{
Debug.LogWarning("More than one instance of inventory found!");
return;
}
instance = this;
}
后面调用的时候直接使用 Inventory.instance即可调用;
3、用 #region来整理代码块
Windows:#region的使用.
#region Singleton
...
#endregion
4、delegate的使用(委托)
具体的操作还需进一步学习
但是下面的链接值得参考
1、在unity中如何使用delegate.
2、unity官方教学视频.
感觉有点说不上来,,,可能还需要进一步的学习。。。
代码
ItemPickup:继承Interactable类
using UnityEngine;
public class ItemPickup : Interactable
{
public Item item;
public override void Interative()
{
base.Interative();
PickUp();
}
void PickUp()
{
Debug.Log("Picking up " + item.name);
bool isAdd = Inventory.instance.AddItem(item);
if (isAdd)
{
Destroy(gameObject);
}
}
}
Item 类型为ScriptableObject
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
new public string name = "new Item";
public Sprite icon = null;
public bool isDefaultItem = false;
}
Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
#region Singleton
public delegate void OnItemChanged();
public OnItemChanged onItemCHangedCallback;
public static Inventory instance;
void Awake()
{
if (instance != null)
{
Debug.LogWarning("More than one instance of inventory found!");
return;
}
instance = this;
}
#endregion
public List<Item> items = new List<Item>();
public int space = 20;
public bool AddItem(Item item)
{
if (!item.isDefaultItem)
{
if (items.Count >= space)
{
Debug.Log("No enough room!");
return false;
}
items.Add(item);
if (onItemCHangedCallback != null)
{
onItemCHangedCallback.Invoke();
}
}
return true;
}
public void RemoveItem(Item item)
{
items.Remove(item);
if (onItemCHangedCallback != null)
{
onItemCHangedCallback.Invoke();
}
}
}