First Person Narrative Coding
Hey everyone I'm brand new to 3d development and am dipping my toe by trying to construct a few small, simple first person narrative experiences.
My question is a simple one but something I've not been able to find scouring the internet for a few days.... What coding magic do I need for the player to click on an object in the world and have an associated text prompt come up on the GUI (think reading a note in any modern narrative game). I've done my homework on raycasting and currently have a ray that projects from my player and can log the console when the the ray is touching something and the player presses mouse down, but nothing else.
I know it's a simple request but any help would be gladly appreciated!
Answer by Statement · Dec 20, 2015 at 01:21 AM
I'm brand new to 3d development and am dipping my toe
Ok, I'll tune the answer for simplicity. There are many ways to solve problems but I think making simple steps to achieve behaviour is a good way forward. Then the solution can be improved further at a later point, should the need arise.
What coding magic do I need for the player to click on an object in the world and have an associated text prompt come up on the GUI
The object should have a mechanism to support clicking on them, and handling the click event to generate a response. The absolutely simplest way to achieve this is probably using OnMouseDown, but since you have a Raycast going on, let's move on from there.
A simple way onward after determining you've hit an object is to tell the object it was clicked through SendMessage.
I present three scripts that hopefully is simple to understand:
Interact.cs
The idea is that you'll call Interact.With(hit.collider.gameObject)
from your code that already logs the ray is touching someting.
using UnityEngine;
public static class Interact
{
public static void With(GameObject go)
{
// Call the function "Interact" on all scripts that have it on the game object
go.SendMessage("Interact", SendMessageOptions.DontRequireReceiver);
}
}
Note.cs
Note implements Interact
and decides what to do when it has been interacted with. For this simple example, we just want to tell the note reader to read the message of the note but it could do more things like playing audio as well as tell the reader to read the message.
using UnityEngine;
public class Note : MonoBehaviour
{
public string message = "The note is empty";
public NoteReader reader;
public void Interact()
{
reader.ReadNote(message);
}
}
NoteReader
The NoteReader accepts a message and outputs the message somewhere to the user. In this example, I decided it could just set the text of a Text component but it could have more complicated behaviour like making typewriter-like sounds and revealing the text one character at a time for instance.
using UnityEngine;
using UnityEngine.UI;
public class NoteReader : MonoBehaviour
{
public Text messageText;
public void ReadNote(string message)
{
messageText.text = message;
}
}
To put it all together, you'd first create a UI Text object in the scene where the message will appear. Next, you'd probably want to add the NoteReader component to the same Text object, although it is not necessary. The NoteReader must know of the Text component, so drag it into place using the inspector.
Next, go to your note game object and add the Note component to it. Edit the message if you wish. The note must know of a NoteReader so it can tell the reader to present the message of the note when it has been interacted with, so make sure you drag the NoteReader you created earlier to the reader field on the Note component.
Repeating what has been said
It may look like a lot of hoops, but in essence the solution would do something like this:
When user click the mouse, a raycast test says it hit something. User want to interact with that object. In this case it happened to be a Note. Interacting with a note causes a reader to read the note message to the user. Reading a message is just setting the text contents of a Text UI component, which renders it to the user.
I find it that reading through the same information twice but at a different level of speech, it's easier to grok the solution.
Thank you for the very thorough reply! I developed a couple 2d games with Unity when I was in school so most of your reply made sense right off the bat, in large part to your simple explanations. Thank you again! @Statement
Answer by nickriccardi · Dec 23, 2015 at 09:55 PM
@Statement I don't know if you'll see this, but after a few days these scripts stopped working and I'm not sure what I did. From what I can tell the two things not working as intended are:
I can no longer drag NoteReader onto the Reader component of Note
I was never able to drag NoteReader onto my ui text object either
The interact script doesn't seem to do... Anything. My ray now only casts when the mouse button is clicked down, so that might have something to do with it?
I'm not at home and don't have access to a computer so I'll keep it short.
$$anonymous$$ake sure you don't have any compile errors
$$anonymous$$ake sure each code listing is in a separate cs code file and that the name of the file match the class name.
$$anonymous$$ake sure you call Interact.With on the collides game object of the ray cast result.
If you manage to put everything together but that the interact call doesn't work, debug what doesn't work and figure out why. But also look for errors in the console to help you narrow down the issue.
Your answer
Follow this Question
Related Questions
TextUI text changes size if resolution changes 1 Answer
Displaying GUIText on top of Unity UI Image? 0 Answers
How can I update UI Text score using PlayerPrefs.Getint() on startup? 1 Answer
GUI Text not showing up :( 7 Answers
Offset between mouse cursor position and "hit" position with worldspace UI's 1 Answer