Unity3D - 抽象类,单一行为功能

Ale*_*ble 6 c# inheritance unity-game-engine

前言

因此,过去几周我一直在 Unity Answers 论坛上讨论这个问题,但没有得到任何答复。在我看来,这将是一个相对直接的问题,所以我想知道这里是否有人可以帮助我代替那里的答案。

所以我有点进退两难。


目标

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

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

Rifle ActiveWeapon = new Rifle(parameters);
Run Code Online (Sandbox Code Playgroud)

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


问题

我遇到的问题是我希望能够利用一些从 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;
 }
Run Code Online (Sandbox Code Playgroud)

显然,因为这不是 MonoBehaviour 类,所以我不能使用诸如 Instantiate 之类的函数来创建项目符号或使用 WaitForSeconds 来错开它们。

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

小智 6

您可以拥有一个继承自 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不希望您的抽象类位于 GameObject 中,您可以使用外部游戏对象来管理对象池系统的实例化。

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

private startcoroutine(int id, IEnumerator ienum)
{
    Coroutine c = StartCoroutine(ienum);
    dictionary.Add(id, c);
}
Run Code Online (Sandbox Code Playgroud)