在Unity中使用可脚本化对象的项目/能力系统

时间:2018-08-17 00:10:31

标签: c# unity3d

我是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;


}

1 个答案:

答案 0 :(得分:1)

如果您的问题是“如何在我的项目中创建Item的实例”,则可以通过在“项目”视图中右键单击,然后选择Create -> Item来实现。然后将您从“项目”视图创建的Item资产拖到检查器中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类为非抽象类,或使其抽象化并创建适当的非抽象派生类(WeaponPotion等)。我在下面举一个例子。

如果您要这么做,则不能将MonoBehaviour附加到ScriptableObject上。 ScriptableObject基本上只是一个与场景无关的数据/方法容器。 MonoBehaviour必须存在于场景中的对象上。但是,您可以做的是在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);
      }
   }
}