Architectural Show/Talk on UI Presentation

My game is doing a bunch of interesting extensions on the course, but one area I keep running into problems with is how to present data to the UI. Here’s an example with showing quest objective status in the UI.

I have different “types” of objectives in my game. Each objective type is represented by a different scriptable object class. For example an objective says you need to defeat N number of spawned enemies. I want this objective to display its own status in a nicely formatted way. Here are the constraints

  • I don’t think my Quest UI should know how every objective wants to format itself. I want to be able to add different kinds of objectives and have an unchanging common interface to the UI layer
  • I don’t want my objective to worry about details the UI should worry about.

I want to implement this in a scalable way so here is what I came up with. The SpawningConditionalObjective sorta straddles the lines between a “model” and “presenter” (model-view-presenter pattern).

Note below my subclass extends “AbstractQuestObjective” and my UI layer only knows to how to interface with AbstractQuestObjective and doesn’t know anything about all the different subclasses.

Question: I keep running into many MANY different UI presentation problems that have this sort of nature. Wondering what is the most scalable way to address them or if this seems reasonable?

 public class SpawningConditionalObjective : AbstractQuestObjective, ISerializationCallbackReceiver
        [SerializeField] private string objectiveDescriptionPrefix = "Knock Out";
        [SerializeField] private int goalToKnockOut;  // set in inspector
        [SerializeField] private string objectiveDescriptionSuffix = "Enemies";
        [SerializeField] private string uniqueID = null; //set via OnBeforeSerialize

//other code snipped

        public override string GetFormattedObjectiveStatus()
// I don't null check for a counter, because I have other code that guarantees it will be there.
            AchievementCounter counter = GameObject.FindWithTag("Player").GetComponent<AchievementCounter>();

            string numerator = "<color=green>" + counter.GetCounterValue(uniqueID) + "</color>";
            string goal = "<color=green>" + goalToKnockOut + "</color>";

            return objectiveDescriptionPrefix + " " + goal + " " + objectiveDescriptionSuffix + ": "
                   + numerator + " / " + goal;

Privacy & Terms