【问题标题】:Unity3D - Abstract Class, Monobehaviour functionalityUnity3D - 抽象类,单一行为功能
【发布时间】:2016-01-13 01:31:17
【问题描述】:

序言

所以在过去的几周里,我一直在 Unity Answers 论坛上提出这个问题,但没有一个回复。在我看来,这将是一个相对直截了当的问题,所以我想知道这里是否有人可以帮助我代替那里的答案。

所以我有点进退两难。


目标

我想在我的游戏中为枪支使用继承结构。我想创建一个抽象类(枪),然后有枪的子类(激光、步枪、火箭发射器)从它继承,然后创建这些武器的特定实例。目前我将其作为一个抽象类来执行,因为 Gun 的不同子类实现 Shoot() 函数的方式存在很大差异。 (即火箭发射器将实例化 X 火箭游戏对象,而激光可能会使用射线投射来确定即时命中)。

此外,我希望能够在玩家库存中拥有枪支列表,并且不希望依赖于我的玩家的活动武器来添加和删除脚本。如果我可以按以下方式构建它们,那对我来说很好:

Rifle ActiveWeapon = new Rifle(parameters);

我也不想为玩家提供有限数量的武器,但希望能够在运行时生成它们(例如掉落或制作),所以我也不想写一个固定数量武器脚本。


问题

我遇到的问题是我希望能够利用一些衍生自 MonoBehaviours 的方法,例如:

public override void Shoot ()
 {
     if (CanShoot) 
     {
         StartCoroutine(Cooldown());
         Rigidbody bullet = Rigidbody.Instantiate(BulletPrefab, transform.position, transform.rotation);
         ... // Addforce etc.
         ...
     }
 }
public IEnumerator Cooldown()
 {
     CanShoot = false;
     yield return new WaitForSeconds (FireRate);
     CanShoot = true;
 }

显然,由于这不是 MonoBehaviour 类,因此我不能使用 Instantiate 等函数来创建项目符号或使用 WaitForSeconds 来错开它们。

我应该如何解决这个问题?

【问题讨论】:

    标签: c# inheritance unity3d


    【解决方案1】:

    你可以有一个继承自 MonoBehaviour 的抽象类,以下工作正常:

    public abstract class AbstractClass : MonoBehaviour
    {
        protected abstract void pouet();
    }
    
    public class InheritClass : AbstractClass 
    {
    
        // Use this for initialization
        void Start ()
        {
            StartCoroutine(pouetCoroutine());
        }
    
        protected override void pouet()
        {
            Debug.Log("pouet");
        }
    
        private IEnumerator pouetCoroutine()
        {
            yield return null;
            pouet();
        }
    }
    

    如果您不希望抽象类位于 GameObject 中,则可以使用外部游戏对象通过 object pooling system 管理实例化。

    关于协程,您可以使用协程引擎来启动和停止它们。你只需要一个字典和一个公共函数来启动协程,并保留一个 id 作为访问它的键,如果你以后需要停止它。

    private startcoroutine(int id, IEnumerator ienum)
    {
        Coroutine c = StartCoroutine(ienum);
        dictionary.Add(id, c);
    }
    

    【讨论】:

    • 非常感谢您的回复!这对我很有帮助。我可能过于强烈地描绘了 MonoBehaviour 和抽象类之间的二分法。问题是 Unity 对我使用构造函数创建一个派生自 MonoBehaviour 的 Object 提出异议,而是更喜欢我使用 AddComponent() 函数来添加它。我也没有真正看到使用外部游戏对象如何解决这个问题,因为我想动态创建对象。这不是没有他们的位置的问题。
    • @AlecGamble 我认为您有两个解决问题的方法: - 使用继承自 MonoBehaviour 的抽象类,忘记构造函数并使用 init 函数。这不是很好。 - 使用不是 MonoBehaviour 的抽象类,并使用实际的 MonoBehaviour 实例来使用 MonoBehaviour 类方法。例如,您不能在抽象类中使用 Instantiate,但可以使用 Factory 类(继承自 MonoBehaviour)来为您实例化内容。我可能误解了你的问题,如果是,请不要害怕告诉我:)
    • 你可以在非 MonoBehaviour 中使用 Instantiate,你必须使用完整的命名 Object.Instantiate(prefab);
    猜你喜欢
    • 2014-08-27
    • 2011-10-08
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 2013-11-25
    相关资源
    最近更新 更多