- Tutoriales
- Scripting
- Action Responses
Action Responses
Revisado con versión: 5.5
-
Dificultad: Principiante
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.


Action Responses
Principiante 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);
}
}