【问题标题】:Show variable herited from interface on Unity inspector在 Unity 检查器上显示从接口继承的变量
【发布时间】:2015-08-02 19:44:41
【问题描述】:

我想在 Unity 中创建一些游戏,我首先创建了一个类层次结构,以便能够使用多态性。所以我创建了一些接口,其中包含方法和变量。

正如C# interfaces documentation 中所说,我已经使用这样的变量创建了我的界面

public interface IUnit : ISelectable {
  int   healthPoint { get; set; }
  bool  isIndestructible { get; set; }
  /******************************/
  void  takeDamage(int dmg);
  void  die();
}

现在,我正在一个类中实现我的接口:

[System.Serializable]
public class BasicUnit : MonoBehaviour, IUnit {

  private int       _healthPoint;
  public int        HealthPoint         { get { return (_healthPoint); } set { _healthPoint = value; } }
  private bool      _isIndestructible;
  public bool       isIndestructible    { get { return (_isIndestructible); } set { _isIndestructible = value; } }

  public void   takeDamage (int dmg)
  {
      if (this.isIndestructible == false) {
          this.HealthPoint -= dmg;
          if (this.HealthPoint <= 0) {
              die();
          }
      }
  }

  public void die()
  {
      Destroy(gameObject);
  }
}

我的问题是我的变量healthPointisIndestructible 没有显示在 Unity 的检查器中,尽管它们是公共变量。我尝试过使用[System.Serializable],但它不起作用。

我的问题很简单,我应该如何在 Unity 的检查器中显示我继承的变量?

注意:我正在尝试编写漂亮且可读的代码,所以如果可能的话,我想将我的 IUnit 类保留为接口,并将我的变量保留在我的 IUnit 中。

【问题讨论】:

    标签: c# unity3d interface


    【解决方案1】:

    隐藏的不是您继承的代码。继承对字段的显示没有任何影响。
    相反,真正发生的是您有两个可序列化的字段,但标记为私有(_healthPoint 和 _isIndestructible),
    和两个公共属性。不幸的是,Unity 无法处理和显示开箱即用的属性。

    幸运的是,这是一个简单的解决方案。我在 Unity Wiki 上找到了这个,并为这种情况保存了它:)

    Expose Proerties in Inspector from Unity Wiki

    工作原理
    基本上,您希望在其上公开属性的任何 Monobehavior 都应继承自 ExposableMonoBehaviour 以及
    1. 私有字段(如您的 _healthPoint)应具有 [SerializeField, HideInInspector] 属性 2.公共属性(如HealthPoint)应该有[ExposeProperty]属性

    部分示例

    public class BasicUnit : ExposableMonoBehaviour, IUnit {
    
        [SerializeField, HideInInspector]
        private int _healthPoint;
        [ExposeProperty]
        public int HealthPoint { 
            get { return (_healthPoint); } 
            set { _healthPoint = value; } 
        }
    
    
    }
    

    【讨论】:

    • 正如@Venkat 提到的,[ExposeProperty] 似乎是您问题的正确答案。
    • 很好的答案,抱歉我不能早点尝试 =)
    【解决方案2】:

    我找到了,您可以在要在检查器中显示的任何字段上使用[SerializeField]。但是,它必须用于您要序列化的私有变量,而不是公共变量。

    public class BasicUnit : MonoBehaviour, IUnit {
    
      [SerializeField]
      private int       _healthPoint;
      public int        HealthPoint         { get { return (_healthPoint); } set { _healthPoint = value; } }
      [SerializeField]
      private bool  _isIndestructible;
      public bool       isIndestructible    { get { return (_isIndestructible); } set { _isIndestructible = value; } }
    }
    

    【讨论】:

    • 虽然您的回答在技术上确实解决了问题,但它违背了将变量设为私有的目的。
    【解决方案3】:

    如果仍然有人在设置从检查器中的接口继承的变量的值时遇到问题,感谢 Jetbrains Rider,我找到了解决方案。只需在子脚本中引入变量之前使用 [field: SerializeField] 即可。

    示例:

    public interface IAlive
    {
        float HealthPoint { get; set;}
    }
    public class Cat : MonoBehaviour , IAlive
    {
        [field: SerializeField] float HealthPoint { get; set;}
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 2011-01-17
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 2011-02-17
      相关资源
      最近更新 更多