Recorded Video Session: Text Adventure Game Part 2
Tutorial
·
Beginner
·
+0XP
·
90 mins
·
(280)
Unity Technologies
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this session we will see the finished project and introduce what we aim to learn in this series of sessions.
Languages available:
1. Introduction and Goals
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this session we will see the finished project and introduce what we aim to learn in this series of sessions.
Creating a Text Based Adventure Part 2 - Introduction and Goals [1/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}2. Project Architecture and Review
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will review what we did in the first half of our session and look at an overview of the architecture we will create in part two.
Creating a Text Based Adventure Part 2 - Project Architecture and Review [2/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}3. Displaying Item Descriptions
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will learn how to to display the descriptions of all the items in a room when we enter it.
Creating a Text Based Adventure Part 2 - Displaying Item Descriptions [3/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}4. Examining Items
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will add the ability for the player to examine items and see a second more detailed description of them.
Creating a Text Based Adventure Part 2 - Examining Items [4/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}5. Taking Items
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will add the ability for the player to take items and add them to their inventory.
Creating a Text Based Adventure Part 2 - Taking Items [5/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}6. Displaying Inventory
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will add the ability for the player to display the items they have taken into their inventory.
Creating a Text Based Adventure Part 2 - Displaying Inventory [6/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}7. Action Responses
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will add ActionResponses which we will use to execute functions when the player chooses the Use action with an item.
Creating a Text Based Adventure Part 2 - Action Responses [7/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}8. Preparing The Use Item Dictionary
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will add Action Responses to our system in order to create pluggable functions that will be executed when the player chooses to Use an item.
Creating a Text Based Adventure Part 2 - Preparing The Use Item Dictionary [8/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}9. Creating The Use Action
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will finish adding the capacity for players to change the state of the game based on using an item in the correct room using Action Responses by creating the 'Use' Input Action.
Creating a Text Based Adventure Part 2 - Creating The Use Action [9/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}10. Questions and Answers
In this second session we will continue to learn how to program a text based adventure game in C# by adding items which can be examined, taken and used, along with a very simple inventory system. In this episode we will finish the session by taking questions and answers.
Creating a Text Based Adventure Part 2 - Displaying Inventory [10/10] Live 2017/3/29
InteractableObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/Interactable Object")]
public class InteractableObject : ScriptableObject
{
public string noun = "name";
[TextArea]
public string description = "Description in room";
public Interaction[] interactions;
}Interaction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Interaction
{
public InputAction inputAction;
[TextArea]
public string textResponse;
public ActionResponse actionResponse;
}InteractableItems
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableItems : MonoBehaviour
{
public List<InteractableObject> usableItemList;
public Dictionary<string, string> examineDictionary = new Dictionary<string, string> ();
public Dictionary<string, string> takeDictionary = new Dictionary<string, string> ();
[HideInInspector] public List<string> nounsInRoom = new List<string>();
Dictionary <string, ActionResponse> useDictionary = new Dictionary<string, ActionResponse> ();
List<string> nounsInInventory = new List<string>();
GameController controller;
void Awake()
{
controller = GetComponent<GameController> ();
}
public string GetObjectsNotInInventory(Room currentRoom, int i)
{
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
if (!nounsInInventory.Contains (interactableInRoom.noun))
{
nounsInRoom.Add (interactableInRoom.noun);
return interactableInRoom.description;
}
return null;
}
public void AddActionResponsesToUseDictionary()
{
for (int i = 0; i < nounsInInventory.Count; i++)
{
string noun = nounsInInventory [i];
InteractableObject interactableObjectInInventory = GetInteractableObjectFromUsableList (noun);
if (interactableObjectInInventory == null)
continue;
for (int j = 0; j < interactableObjectInInventory.interactions.Length; j++)
{
Interaction interaction = interactableObjectInInventory.interactions [j];
if (interaction.actionResponse == null)
continue;
if (!useDictionary.ContainsKey (noun))
{
useDictionary.Add (noun, interaction.actionResponse);
}
}
}
}
InteractableObject GetInteractableObjectFromUsableList(string noun)
{
for (int i = 0; i < usableItemList.Count; i++)
{
if (usableItemList [i].noun == noun)
{
return usableItemList [i];
}
}
return null;
}
public void DisplayInventory()
{
controller.LogStringWithReturn ("You look in your backpack, inside you have: ");
for (int i = 0; i < nounsInInventory.Count; i++)
{
controller.LogStringWithReturn (nounsInInventory [i]);
}
}
public void ClearCollections()
{
examineDictionary.Clear();
takeDictionary.Clear ();
nounsInRoom.Clear();
}
public Dictionary<string, string> Take (string[] separatedInputWords)
{
string noun = separatedInputWords [1];
if (nounsInRoom.Contains (noun)) {
nounsInInventory.Add (noun);
AddActionResponsesToUseDictionary ();
nounsInRoom.Remove (noun);
return takeDictionary;
}
else
{
controller.LogStringWithReturn ("There is no " + noun + " here to take.");
return null;
}
}
public void UseItem(string[] separatedInputWords)
{
string nounToUse = separatedInputWords [1];
if (nounsInInventory.Contains (nounToUse)) {
if (useDictionary.ContainsKey (nounToUse)) {
bool actionResult = useDictionary [nounToUse].DoActionResponse (controller);
if (!actionResult) {
controller.LogStringWithReturn ("Hmm. Nothing happens.");
}
} else {
controller.LogStringWithReturn ("You can't use the " + nounToUse);
}
} else
{
controller.LogStringWithReturn ("There is no " + nounToUse + " in your inventory to use");
}
}
}Room
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/Room")]
public class Room : ScriptableObject
{
[TextArea]
public string description;
public string roomName;
public Exit[] exits;
public InteractableObject[] interactableObjectsInRoom;
}GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public Text displayText;
public InputAction[] inputActions;
[HideInInspector] public RoomNavigation roomNavigation;
[HideInInspector] public List<string> interactionDescriptionsInRoom = new List<string> ();
[HideInInspector] public InteractableItems interactableItems;
List<string> actionLog = new List<string>();
// Use this for initialization
void Awake ()
{
interactableItems = GetComponent<InteractableItems> ();
roomNavigation = GetComponent<RoomNavigation> ();
}
void Start()
{
DisplayRoomText ();
DisplayLoggedText ();
}
public void DisplayLoggedText()
{
string logAsText = string.Join ("\n", actionLog.ToArray ());
displayText.text = logAsText;
}
public void DisplayRoomText()
{
ClearCollectionsForNewRoom ();
UnpackRoom ();
string joinedInteractionDescriptions = string.Join ("\n", interactionDescriptionsInRoom.ToArray ());
string combinedText = roomNavigation.currentRoom.description + "\n" + joinedInteractionDescriptions;
LogStringWithReturn (combinedText);
}
void UnpackRoom()
{
roomNavigation.UnpackExitsInRoom ();
PrepareObjectsToTakeOrExamine (roomNavigation.currentRoom);
}
void PrepareObjectsToTakeOrExamine(Room currentRoom)
{
for (int i = 0; i < currentRoom.interactableObjectsInRoom.Length; i++)
{
string descriptionNotInInventory = interactableItems.GetObjectsNotInInventory (currentRoom, i);
if (descriptionNotInInventory != null)
{
interactionDescriptionsInRoom.Add (descriptionNotInInventory);
}
InteractableObject interactableInRoom = currentRoom.interactableObjectsInRoom [i];
for (int j = 0; j < interactableInRoom.interactions.Length; j++)
{
Interaction interaction = interactableInRoom.interactions [j];
if (interaction.inputAction.keyWord == "examine")
{
interactableItems.examineDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
if (interaction.inputAction.keyWord == "take")
{
interactableItems.takeDictionary.Add (interactableInRoom.noun, interaction.textResponse);
}
}
}
}
public string TestVerbDictionaryWithNoun(Dictionary<string, string> verbDictionary, string verb, string noun)
{
if (verbDictionary.ContainsKey (noun))
{
return verbDictionary [noun];
}
return "You can't " + verb + " " + noun;
}
void ClearCollectionsForNewRoom()
{
interactableItems.ClearCollections ();
interactionDescriptionsInRoom.Clear ();
roomNavigation.ClearExits ();
}
public void LogStringWithReturn(string stringToAdd)
{
actionLog.Add (stringToAdd + "\n");
}
}InputAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class InputAction : ScriptableObject
{
public string keyWord;
public abstract void RespondToInput (GameController controller, string[] separatedInputWords);
}Examine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Examine")]
public class Examine : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (controller.interactableItems.examineDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}Take
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Take")]
public class Take : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
Dictionary<string, string> takeDictionary = controller.interactableItems.Take (separatedInputWords);
if (takeDictionary != null)
{
controller.LogStringWithReturn (controller.TestVerbDictionaryWithNoun (takeDictionary, separatedInputWords [0], separatedInputWords [1]));
}
}
}Inventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/InputActions/Inventory")]
public class Inventory : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.DisplayInventory ();
}
}ActionResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}ChangeRoomResponse
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "TextAdventure/ActionResponses/ChangeRoom")]
public class ChangeRoomResponse : ActionResponse
{
public Room roomToChangeTo;
public override bool DoActionResponse (GameController controller)
{
if (controller.roomNavigation.currentRoom.roomName == requiredString)
{
controller.roomNavigation.currentRoom = roomToChangeTo;
controller.DisplayRoomText ();
return true;
}
return false;
}
}Use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu (menuName = "TextAdventure/InputActions/Use")]
public class Use : InputAction
{
public override void RespondToInput (GameController controller, string[] separatedInputWords)
{
controller.interactableItems.UseItem (separatedInputWords);
}
}