Displaying Item Descriptions
版本检查: 5.5
-
难度: 新手
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.


Displaying Item Descriptions
新手 Scripting
Download the assets for this training here
InteractableObject
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
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
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ActionResponse : ScriptableObject
{
public string requiredString;
public abstract bool DoActionResponse(GameController controller);
}
ChangeRoomResponse
Code snippet
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
Code snippet
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);
}
}