c# - 在 Unity 中使用脚本对象的项目/能力系统
问题描述
我是 Unity 的新手,在为项目创建可编写脚本的对象以在我的项目中拾取和使用时遇到了一些麻烦。我已经创建了初始设置,以使用我可以即插即用的变量制作项目。
我想做的是:
1 - 在使用时为每个新项目的行为插入一个单一行为脚本。
2 - 允许玩家在碰撞时捡起物品并在键盘命令中使用该物品。玩家一次只能携带一件物品。
这是我到目前为止所拥有的。
可编写脚本的对象 (itemObject.cs)
[CreateAssetMenu(fileName = "New Item", menuName = "Item")]
public abstract class Item : ScriptableObject {
public new string name;
public string description;
public int damageAmount;
public int affectDelay;
public int affectDuration;
public int affectRange;
public float dropChance;
public float itemLife;
}
我有一个脚本,如果播放器与对象 (itemDisplay.cs) 发生碰撞,将触发该脚本。目前,除了破坏该项目之外,这不会做任何事情。
public class itemDisplay : MonoBehaviour {
public Item item;
public static bool isActive = false;
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
var playerPickUp = other.gameObject;
var playerScript = playerPickUp.GetComponent<Player>();
var playerItem = playerScript.playerItem;
playerScript.pickUpItem();
bool isActive = true;
Object.Destroy(gameObject);
}
}
void Start () {
}
void Update(){
}
}
目前,我的播放器脚本(Player.cs)正在处理一个拾取功能和一个使用项目功能。目前,这只是切换一个布尔值,表示它在项目碰撞时做了一些事情。我的大问题是我应该如何/在哪里创建和引用项目能力,以及如何将它传递给这里的播放器脚本?
public void pickUpItem()
{
playerItem = true;
//itemInHand = itemInHand;
Debug.Log("You Picked Up An Item!");
// Debug.Log(playerItem);
if(playerItem == true){
Debug.Log("This is an item in your hands!");
}
}
public void useItem()
{
//use item and set
//playerItem to false
playerItem = false;
}
解决方案
如果您的问题是“如何Item
在我的项目中创建一个实例”,您可以通过右键单击项目视图,然后选择Create -> Item
. 然后将Item
您从 Project 视图中创建的资产拖到Inspector 中的ItemDisplay
场景对象字段中。item
关于如何拾取物品,您可以将物品Player
从您的脚本传递给您的ItemDisplay
脚本。你已经把大部分东西都连接好了。
public class ItemDisplay : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
var playerPickUp = other.gameObject;
var playerScript = playerPickUp.GetComponent<Player>();
var playerItem = playerScript.playerItem;
// This is where you would pass the item to the Player script
playerScript.pickUpItem(this.item);
bool isActive = true;
Object.Destroy(gameObject);
}
}
}
然后在你的Player
脚本中......
public class Player : MonoBehaviour
{
public void PickUpItem(Item item)
{
this.playerItem = true;
this.itemInHand = item;
Debug.Log(string.Format("You picked up a {0}.", item.name));
}
public void UseItem()
{
if (this.itemInHand != null)
{
Debug.Log(string.Format("You used a {0}.", this.itemInHand.name));
}
}
}
您还应该使您的Item
类成为非抽象类,或者将其保留为抽象类并创建适当的非抽象派生类(Weapon
、Potion
等)。我在下面举了一个例子。
如果那是您要执行的操作,则不能将 a 附加MonoBehaviour
到 a上。ScriptableObject
AScriptableObject
基本上只是一个与场景无关的数据/方法容器。AMonoBehaviour
必须生活在场景中的对象上。但是,您可以做的是向您的类添加一个“使用”方法,并在玩家使用项目时Item
从场景中调用该方法。MonoBehaviour
public abstract class Item : ScriptableObject
{
// Properties that are common for all types of items
public int weight;
public Sprite sprite;
public virtual void UseItem(Player player)
{
throw new NotImplementedException();
}
}
[CreateAssetMenu(menuName = "Items/Create Potion")]
public class Potion : Item
{
public int healingPower;
public int manaPower;
public override void UseItem(Player player)
{
Debug.Log(string.Format("You drank a {0}.", this.name));
player.health += this.healingPower;
player.mana += this.manaPower;
}
}
[CreateAssetMenu(menuName = "Items/Create Summon Orb")]
public class SummonOrb : Item
{
public GameObject summonedCreaturePrefab;
public override void UseItem(Player player)
{
Debug.Log(string.Format("You summoned a {0}", this.summonedCreaturePrefab.name));
Instantiate(this.summonedCreaturePrefab);
}
}
然后更改您的UseItem
方法Player
:
public class Player : MonoBehaviour
{
public void UseItem()
{
if (this.itemInHand != null)
{
this.itemInHand.UseItem(this);
}
}
}