So for the purpose of this example, I’ve make a simple XML structure to represent the type of data you might be using
<Chapter TotalScenes="2">
<Scene Title="Amazing Castle" NumActions="3" BG="1" Music="5">
<Desc>The wonderful castle is so pretty it make my face hurt... blah blah blah.</Desc>
<Action type="0" flag="0">Enter the Castle</Action>
<Action type="0" flag="0">Punch the Castle</Action>
<Action type="1" flag="6">Blow up the Castle!</Action>
</Scene>
<Scene Title="Evil Forest of Spiders" NumActions="1" BG="5" Music="3">
...
</Scene>
</Chapter>
Some of the data here may or may not be needed. This comes down to the specifics of whatever you use to read your XML into unity. For example, TotalScenes may not be needed as the XML parser will probably hold the Scenes as some form of array that you can get the length from. Since you need this size for creating your data in Unity, I’ve kept it in the example for clarity.
The rest of the data is a very simple representation of the Scene / Action concept. Each Scene has a title, some data to indicate what music and background image you want to use, then a simple text description and actions as child elements. You could expand this to have elements to indicate different character art appearing and moving, effects or sounds firing - pretty much anything you want, as long as you expand your system to handle this data and produce the results inside Unity. A simple example might be replacing Desc with multiple paragraphs of text and including a timing attribute for each one to delay them being displayed.
For the Actions, I’ve included a type and a flag attribute. This allows us to have different types of actions and gives us a place to put any extra data that might be needed. In this example, type 0 simply means it’s an Action that is always displayed (and thus the flag data is ignored), and type 1 means that the Action requires us to have a certain item, where the flag then becomes a unique ID for that item. Type 2 might require a certain quest to be finished and the flag becomes the ID of the quest, or be something else entirely.
On the Unity side of things, these are the Classes that would handle this data:
class Scene {
//Scene specific data
string title;
string desc;
int background;
int music;
Action actions[];
void SetData (int numActions, string myTitle, string myDesc, int myBG, int myMusic)
{
title = myTitle;
desc = myDesc;
background = myBG;
music = myMusic;
actions[] = new Action[numActions];
}
}
class Action {
//Action specific data
int actionType;
int actionFlag;
Scene nextScene;
void SetData (int myType, int myFlag, Scene myScene)
{
nextScene = myScene;
actionType = myType;
actionFlag = myFlag;
}
}
At this point they are little more than Data Classes with simple data setting functions, everything from the XML is mirrored in the Class data. Also, in my example I’ve allowed for the number of actions for each Scene to be dynamically created.
Taking in the XML data and creating our Class data would be done somewhere during your setup / loading phase, perhaps like this:
Scene allScenes[];
Initialise () {
XMLData = GetXMLData;
//Make an array of scenes
allScenes[] = new Scene[XMLData.TotalScenes];
//Set scene data
for (int counter; counter < allScenes.Length(); counter++)
{
allScenes[counter].SetData(XMLData.Scenes[counter].NumActions, XMLData.Scenes[counter].Title, ... etc)
//Set action data
for (int counter2; counter2 < allScenes[counter].actions.Length(); counter2++)
{
allScenes[counter].actions[counter2].SetData(XMLData...);
//Note: For the Scene parameter of SetData you'll want to use the nextScene from the action in the XML as the index into allScenes, and pass that
}
}
}
We create the allScenes array using the TotalScenes from our XML data, then simple go through each setting the data, creating the Actions, and setting the action data. Pretty straight forward. The rest of your system then becomes about simply displaying the text / images / flying pigs associated with the current scene and displaying the right Actions to allow the player to move on.
Speaking of the Action Class, one of the benefits of using classes is that we can make them responsible for certain things in our system. So for example we could add this function to our Action class:
//Valid test
bool IsValid (CharData myChar)
{
if (type == 0)
return true;
if (type == 1) {
if (myChar.HasItem(flag)) {
return true;
}
}
return false;
}
We pass the Action a link to our character data and let the Action be responsible for checking to see if they should be shown. We’d have to test these type/flag combos somewhere, but by doing it here we keep other parts of our system clean and readable. For example, displaying our Actions could be as simple as this:
//Show Actions
if (TimeToShowAtions){
for (int counter; counter < allScenes[currentScene].actions.Length(); counter++){
if (allScenes[currentScene].actions[counter].IsValid(myData)){
//Create / Enable UI button to let people click this action
}
}
}
Of course there are other ways of doing some of the things I’ve done, but perhaps some of this rambling helps shed some light on one way to approach it, and clarifies what I was talking about before. It’s pseudo code and it’s rough, but hopefully it helps.
I’m not typing at 8am this time, so no excuses if I don’t make any sense!