1
\$\begingroup\$

I'm trying to come up with a flexible system of level objectives for a Unity game. What I'd like to achieve is to have a system that on each level (scene) can accept a different set of (configurable) success/failure conditions. Conditions can be repeated between levels but on every level a given type of condition should accept different parameters.

For example on one level success conditions would consist of destroying all enemy units and on the other level success conditions would require destroying a specific enemy unit and escorting a friendly unit to a specific place on map. Failure conditions would for example be player death (on all levels) or not reaching a specific destination within a given time.

First I've tried to approach this problem by using ScriptableObjects but abandoned this idea as it's not possible to save scene object references in a ScriptableObject.

So I've come up with a kind of polymorphic system like this (pseudocode):

public interface Condition {

    bool IsFulfilled();
}

public abstract class VictoryCondition : MonoBehaviour, Condition {

    public virtual bool IsFulfilled();
}

public abstract class AllUnitsKilledCondition : VictoryCondition {

    public List<Unit> units;

    public bool IsFulfilled() {
        foreach (Unit unit : units) {
            if (unit.IsAlive) {
                return false;
            }
        }
        return true;
    }
}

public abstract class FailureCondition : MonoBehaviour, Condition {

    public virtual bool IsFulfilled();
}

public abstract class TimeOutCondition : FailureCondition {

    public float timeLeft;

    void Update() {
        timeLeft -= Time.deltaTime;
    }

    public bool IsFulfilled() {
        return timeLeft <= 0;
    }
}

The idea here is to have a level manager that is given a set of victory/failure conditions in the editor and have it continuously monitor all those conditions. In a simplest scenario a level is won if all victory conditions are fulfilled and lost if any failure condition is fulfilled.

Unfortunately, I'm not sure how to create a LevelManager component that would expose those lists letting me add various conditions and configure them (for example letting me add a list of units from scene to AllUnitsDestroyedCondition). I think it would be doable with a set of custom property drawers for each type of condition but I'm wary of digging into this until I'm sure there is no other, easier way.

I've come up with a way of adding various conditions by adding multiple condition components to a GameObject and then dragging those components to victory/failure conditions lists in LevelManager. But this solution seems awkward and inflexible because it's not possible to dynamically add and configure new conditions in runtime and creating more complex conditions (for example some condition activating only after some other condition is fulfilled) seems like a sure way to create a huge pile of unmaintainable condition component mess.

Please, let me know if I'm approaching this problem correctly and if not, what are other, simpler, more flexible solutions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.