Created
January 17, 2016 20:34
-
-
Save sustained/ea442b96cc1e3f561aec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.UI; | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
/* | |
* This code is not particularly good (and the "story" is even worse, it's only supposed to be amusing). | |
* | |
* I'd even go so far as to say that the code is fairly bad. For one, it uses reflection when it probably | |
* doesn't need to, not if I had done things differently at least but it *does* function. I only wanted | |
* to learn a bit more about C# and make it slightly less cumbersome to add states, which has been achieved. | |
* | |
* I was thinking about making the system more advanced but I want to move on to section four and beyond. | |
* That said, maybe I'll come back to this later on and try to make it a little more advanced. If nothing | |
* else, it is good practise for learning C# and improving at programming. In any case, feel free to do | |
* whatever you want with it. Share how you'd do things differently or improve it yourself, if you'd like. | |
* | |
* | |
* One idea was that the first sentence which tells you *where you are* could change depending on if it | |
* was your first time in the area (A) or not (B). For example: | |
* | |
* A: You walk out into the hall. It is rather dark and dingy. | |
* B: You return back to the dimly lit hall. | |
* | |
* | |
* Another idea was to make it so that options could have requirements. For example, you might need to find a | |
* key before you can use a door. This could be handled by just having more states but if you do it that way | |
* then complexity would quickly begin to spiral out of control. | |
* | |
* | |
* A further idea was to make it so that you could have states that were sort of connected, which would be useful | |
* if you had a lot of text. With the current system, if you had to split a state in two due to the length of the | |
* text there would have to be a "continue reading" choice which is clunky. | |
* | |
* | |
* One last idea was to make it so that instead of the choices being based soley on the state names, instead | |
* you could specify the text. This would make the choices for the state "cell", for example, more natural: | |
* | |
* 1: Use the computer | |
* 2: Speak to the butler | |
* 3: Approach the door | |
*/ | |
public class TextController : MonoBehaviour { | |
public Text text; | |
private struct State { | |
public string[] Choices; | |
public State(string[] choices) { | |
Choices = choices; | |
} | |
} | |
private Dictionary<string, State> States = new Dictionary<string, State> { | |
{"intro", new State(new string[] {"cell"})}, | |
{"tryagain", new State(new string[] {"intro"})}, | |
{"cell", new State(new string[] {"computer", "butler", "bed", "door"})}, | |
{"computer", new State(new string[] {"playgame", "cell"})}, | |
{"butler", new State(new string[] {"cell"})}, | |
{"bed", new State(new string[] {"patterns", "cell"})}, | |
{"playgame", new State(new string[] {"panic"})}, | |
{"panic", new State(new string[] {"tryagain"})}, | |
{"patterns", new State(new string[] {"crackcode", "cell"})}, | |
{"crackcode", new State(new string[] {"rest", "dontrest", "cell"})}, | |
{"rest", new State(new string[] {"tryagain"})}, | |
{"dontrest", new State(new string[] {"cell"})}, | |
{"door", new State(new string[] {"cell", "hall"})}, | |
{"hall", new State(new string[] {"left", "cell"})}, | |
{"left", new State(new string[] {"pickup", "hall"})}, | |
{"right", new State(new string[] {"hall"})}, | |
{"pickup", new State(new string[] {"read", "drop"})}, | |
{"read", new State(new string[] {"gameover"})}, | |
{"drop", new State(new string[] {"left"})}, | |
{"gameover", new State(new string[] {"intro"})} | |
}; | |
private bool stateSetup = false; | |
private string currentState = "intro"; | |
public void StateIntro() { | |
SetText( | |
"You are in prison for a crime you didn't commit. By starting you in a prison, we can then " + | |
"compare our story to The Elder Scrolls, which makes our game sound better than it is but I " + | |
"digress....\n\nYou are in a prison. This would be all well and good (it's a Norwegian prison) " + | |
"however there is one problem. The world is about to end and only you know how to stop it..."); | |
} | |
public void StateTryagain() { | |
SetText( | |
"You had one job. You have disappointed more than seven billion people and you should feel bad."); | |
} | |
public void StateCell() { | |
SetText( | |
"You are in your cell and you should probably try to to escape, so that you can save the world. " + | |
"In your cell, there is a gaming PC, a king size bed and your personal butler."); | |
} | |
public void StateComputer() { | |
SetText("This is no time to be playing video games!"); | |
} | |
public void StatePlaygame() { | |
SetText( | |
"You become immersed in an open-world story-driven RPG and the next thing you know, almost an hour " + | |
"has passed."); | |
} | |
public void StatePanic() { | |
SetText( | |
"Through the window, the skies are beginning to turn red like blood. All of a sudden, there is a bang " + | |
"so loud that it ruptures your eardrums. You fall to the floor and begin to writhe around in intense " + | |
"pain, holding your bleeding ears. There is an unfathomably bright flash and then... nothing."); | |
} | |
public void StateBed() { | |
SetText( | |
"The bed is a king size canopy bed, with red silk curtains. They are adorned with the most " + | |
"wonderful golden patterns which are almost entrancing in their nature..."); | |
} | |
public void StatePatterns() { | |
SetText( | |
"You study the patterns more closely. You can't shake the feeling that there is some kind of code " + | |
"hidden within them."); | |
} | |
public void StateCrackcode() { | |
SetText( | |
"After some time, you determine that the idea of the curtains containing some kind of hidden code " + | |
"is preposterous. You are feeling quite sleepy now, though. Perhaps you should rest your head?"); | |
} | |
public void StateRest() { | |
SetText( | |
"Your lay on the bed. It is so indescribably comfortable and you quickly fall into a deep sleep, " + | |
"during which the world ends."); | |
} | |
public void StateDontrest() { | |
SetText("It's good that you seem to have your priorities in order."); | |
} | |
public void StateButler() { | |
SetText("You don't actually have a butler. Sorry. We shouldn't lie to you like that."); | |
} | |
public void StateDoor() { | |
SetText("You walk up to the door. It is open, for whatever reason."); | |
} | |
public void StateHall() { | |
SetText( | |
"You are in the hall. You can either turn left and walk down the hall, or you can go back " + | |
"into your cell."); | |
} | |
public void StateLeft() { | |
SetText("You head towards the left. After a few moments you come upon a letter, laid on the floor."); | |
} | |
public void StatePickup() { | |
SetText("You bend down and pick up the letter. It is adressed to 'Player'"); | |
} | |
public void StateDrop() { | |
SetText("You throw the letter back on the floor. Although you should probably reconsider..."); | |
} | |
public void StateRead() { | |
SetText( | |
"You read the letter...\n\n" + | |
"Dear Player\n" + | |
"We ran out of funding for the game at this point in the development cycle...\n" + | |
"Our most sincere apologies. I guess this means that you win.\n\n" + | |
"Congratulations?" | |
); | |
} | |
public void StateGameover() { | |
SetText("You win!"); | |
} | |
private void Update () { | |
if (States.ContainsKey(currentState)) { | |
if (stateSetup == false) { | |
this.GetType().GetMethod("State" + FirstCharToUpper(currentState)).Invoke(this, null); | |
this.AddChoices(); | |
} | |
HandleInput(); | |
} | |
} | |
private void SetText(string input) { | |
text.text = input + "\n\n"; | |
} | |
private void AddChoices() { | |
int index = 0; | |
State current = States[currentState]; | |
text.text += "What would you like to do?\n\n"; | |
foreach(string state in current.Choices) { | |
index++; | |
text.text += "\t" + index + ": " + state + "\n"; | |
} | |
stateSetup = true; | |
} | |
private void HandleInput() { | |
int index = 0; | |
State current = States[currentState]; | |
foreach(string state in current.Choices) { | |
index++; | |
if (Input.GetKeyDown((KeyCode) Enum.Parse(typeof(KeyCode), "Alpha" + index)) | |
|| Input.GetKeyDown((KeyCode) Enum.Parse(typeof(KeyCode), "Keypad" + index))) { | |
stateSetup = false; | |
currentState = state; | |
} | |
} | |
} | |
private static string FirstCharToUpper(string input) | |
{ | |
if (String.IsNullOrEmpty(input)) { | |
throw new ArgumentException("String input is null or empty."); | |
} | |
return input.First().ToString().ToUpper() + input.Substring(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment