【问题标题】:Unity - Struggling with Dependency Injection and MonobehaviourUnity - 与依赖注入和单一行为作斗争
【发布时间】:2019-10-31 11:37:57
【问题描述】:

所以我正在尝试使用 DI 并尝试创建一个游戏对象生成器。 该游戏对象生成器根据一些内部逻辑在场景中生成游戏对象。

生成的游戏对象的种类和逻辑可能会有所不同。

我认为我可以创建一个接口并能够根据“独特逻辑”创建一个类(即,对于每个生成器行为,我创建一个类,并且可以在生成许多小对象和几个大对象之间切换,而无需必须使用 if 语句,而是使用多态的力量)。

所以我有类似的东西

GameObjectGenerator : Monobehaviour
IGeneratorType

SmallGenerator : Monobehaviour, IGeneratorType
BigGenerator : Monobehaviour, IGeneratorType

从逻辑的角度来看,这似乎是有道理的。

从这些生成器转换时出现了问题。 我想要某种条件,我从 IGeneratorType 调用方法“TransitionGenerator” 返回一个新的 IGeneratorType。从逻辑上讲,这也有效。

但是,我想跟踪我生成的对象(例如在列表中),因为它们需要稍后被销毁。 转换时,需要将生成的对象列表传递给新的 IGeneratorType。 这就是我发现自己挣扎的地方。

从 IGeneratorType 实现的类也需要扩展 Monobehaviour,因为我需要调用 Instantiate 和 Destroy。

但由于它们是从 Monobehaviour 扩展而来,我似乎无法创建构造函数。

经过一番研究,我发现很多人指向 Awake/Start 或创建 Init 方法。

问题是,使用 Awake/Start 我无法传递任何内容,而使用 Init,我还需要将其放入界面中,从设计的角度来看,这对我来说没有多大意义。

示例代码:

public class GameObjectGenerator : Monobehaviour{
    private IGeneratorType generator;
    public void Start(){
        generator = new SmallGenerator();
    }

    public void Update(){
        generator.Generate();
        if(somecondition){
            generator = generator.Transition();
        }
    }
}

public interface IGeneratorType{
    void Generate();
    IGeneratorType Transition();
}

public class SmallGenerator : Monobehaviour, IGeneratorType{
    private List<GameObject> generatedObjects;
    public SmallGenerator(/*List<GameObject> previousObjects*/){
        //generatedObjects = previousObjects;
    }

    public void Generate(){
        //...
        if(somespecificcond){
            generatedObjects.Add(Instantiate(...));
        }
        if(somecondition){
            Destroy(generatedObjects[0])
        }
    }

    public IGeneratorType Transition(){
        return new BigGenerator(/*generatedObjects*/);
    }
}


public class BigGenerator : Monobehaviour, IGeneratorType{
    private List<GameObject> generatedObjects;
    public BigGenerator(/*List<GameObject> previousObjects*/){
        //generatedObjects = previousObjects;
    }

    public void Generate(){
        //...
        if(somespecificothercond){
            generatedObjects.Add(Instantiate(...));
        }
        if(somecondition){
            Destroy(generatedObjects[0])
        }
    }

    public IGeneratorType Transition(){
        return new SmallGenerator(/*generatedObjects*/);
    }
}

【问题讨论】:

    标签: c# unity3d dependency-injection


    【解决方案1】:

    我刚刚找到了针对这种特定情况的最简单的解决方法:

    public class BigGenerator : IGeneratorType{
        private List<GameObject> generatedObjects;
        public BigGenerator(/*List<GameObject> previousObjects*/){
            //generatedObjects = previousObjects;
        }
    
        public void Generate(){
            //...
            if(somespecificothercond){
                generatedObjects.Add(Object.Instantiate(...));
            }
            if(somecondition){
                Object.Destroy(generatedObjects[0])
            }
        }
    
        public IGeneratorType Transition(){
            return new SmallGenerator(/*generatedObjects*/);
        }
    }
    

    这是因为 Instantiate 和 Destroy 是“Object”的静态方法,“GameObject”继承了这些方法。

    但是,如果一个人真的必须从单一行为继承,这并不能解决问题

    【讨论】:

      猜你喜欢
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多