Here basically what I want to do.
I need a messagebox system for my game. In every map there are npcs so we’re talking about a lot of dialogues.
I want a script able to manage the size of the viewport where the text is shown, the speed of the dialogue and the image used as messagebox.
I want this script to make me able to set up the coordinates in the npc’s ispector, to search a dialogue in an array from an external file. (Dialogues.txt for example).
I’m new to js and I don’t really know how to set up this script. Can somebody help me?
Well, that a big request without any code to start with. ![]()
I would suggest to break it up into parts.
- Create a window to show some text. (If you have absolutely no idea where to start see these tutorials: Learn game development w/ Unity | Courses & tutorials in game design, VR, AR, & Real-time 3D | Unity Learn)
- Add the management stuff like size and image and so on
- Load data from an external file
Then build you messagebox system from the parts.
[e]
If you’re not familar with scripting js/c# at all, you should learn the basics first. I guess that’s not what you would like to hear, but you won’t get far without this knowledge.
The tutorials section has a full range of beginner tutorials for scripting.
I’m already studying js and C#. I have some basics. I just needed a little help like you just did.
I still don’t have a trained mind in terms of coding, but break it up into parts it’s a good idea.
Now I would like to calculate the distance between the player and the npc. I set a variable:
var playerPos:Vector3 = playerObject.transform.position;
But I don’t know how to make the same with the npc.
The idea is to subtract the npc position from the player position to get a distance. If it’s the right distance the dialogue happens.
I guess you NPC is a gameobject? Then you’ll have to get a reference to the npc gameobject to access its transform component. GameObject.Find describes how to do this. Once you have the npc gameobject use Vector3.Distance (or Vector2.Distance if you’re on 2D) to calculate the distance to the player.
I tried something like this but I don’t know:
#pragma strict
var ViewportHeight = float;
var ViewportWidth = float;
var DialogueSpeed = int;
var NpcPos = GameObject.FindGameObjectWithTag("npc");
var playerPos:Vector3 = playerObject.transform.position;
var Distance = float;
function Update () {
Distance= (NpcPos-PlayerPos);
if (Input.GetKeyDown(KeyCode.C)){
if (Distance <= 1){
dialogue ();
}
}
}
function dialogue () {
Debug.Log ("You're too close");
}
First of all, I am bad with Javascript. So, I don’t take my code as working.![]()
Second, with my limited JavaScript skills you code looks weird. Whats for example
var ViewportHeight = float;
meant to be? Is this really valid JavaScript code? ![]()
I guess you’re code should be something like this:
#pragma strict
var Npc : GameObject;
var Distance : float;
function Start () {
NpcPos = GameObject.FindGameObjectWithTag("npc");
}
function Update () {
Distance = (Npc.transform.position - this.transform.position);
if (Input.GetKeyDown(KeyCode.C)){
if (Distance <= 1){
dialogue ();
}
}
}
function dialogue () {
Debug.Log ("You're too close");
}
(assuming that the script is attached to the player gameobject)
Use the start() function to assign external references to you variables. Don’t do it at global declaration. The object in question might not even exist at this time.
On a side note: if you’re starting from a scratch without any reasonable programming skills (?) it probably could be more usefull to learn C# instead ob Javascript. Imho there are way more examples, code snippets, etc out there for C# than for Javascript (at least when it comes to Unity). But that’s only my feeling. If you’re happy with Javascript just ignore me. ![]()
I worked few weeks with C#, it was easy but i prefer Js, It seems more clean.
Here what I did:
function Update () {
if (Input.GetKeyDown(KeyCode.C)){
TalkToNPC ();
}
}
function TalkToNPC () {
gameObject.Find ("npc").SendMessage ("dialogue");
}
That reminds to a function in a script bound with the npc recalled:
function dialogue () {
Debug.Log("" + message);
}
This shows me the message I set in the ispector:
It’s a good compromise 'till I don’t understand how to call an array from an external file.
But I can’t set a CallObject.Find for every npc in the game. Does exists a way to call a function from the nearest object with the tag “npc”?
I think I should also check the distance to avoid the player to be talking with the closest npc at 3 kilometers.
How could I do?
EDIT:
I’ve succesfully calculated the distance between the npc and the player, I used it in if condition to recall to the dialogue script with a var message I can edit for every npc in the inspector.
The problem is that the script detects the closest npc but when i press the action button to talk, the debug shows this error:
That’s why I set the name of the object instead of the tag in GameObject.Findwithtag. I don’t know how to refer to an object both with tag and name.
I tried this but it doesn’t work.
GameObject.FindWithTag("npc").Find("" + closest).SendMessage ("dialogue");
This gives me this error back:
![]()
The “closest” that you see it’s a var with the name of the closest object and I converted it to a string before.
Thank you man ![]()
Nothing…
I literally tried all night to solve the problem but it stays.
I share the complete code.
Attacked to the player :
function Update () {
//Dialogue-----------------------------------------------
if (Input.GetKeyDown(KeyCode.C)){
TalkToNPC ();
}
//-------------------------------------------------------
}
function TalkToNPC () {
//;
// Find all game objects with tag npc
var npcs : GameObject[];
npcs = GameObject.FindGameObjectsWithTag("npc");
var closest : GameObject;
var distance = Mathf.Infinity;
var position = transform.position;
// Find the closest one
for (var chara : GameObject in npcs) {
var diff = (chara.transform.position - position);
var curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = chara;
closest.ToString();
distance = curDistance;
}
}
if (distance < 800) {
Debug.Log ("The closest npc is" + closest)
GameObject.FindWithTag("npc").Find("" + closest).SendMessage ("dialogue");
}
}
Attacked to the npc:
var message: String;
function dialogue () {
Debug.Log (message);
}
The error given by the console is this, when I’m near to an npc and press C:
Nobody knows how to solve ?
Unfortunately there’s no line 35 in you code. ![]()
I am assuming that the error is about line 31:
GameObject.FindWithTag("npc").Find("" + closest).SendMessage ("dialogue");
This line is kind of strange. First you’re looking for a gameobject with tag “npc”, just to use this gameobject to find another gameobject with the Name “” + closest. That’s one step to much. ![]()
This would do the job:
GameObject.Find("" + closest).SendMessage ("dialogue");
The error complains about a missing object. So, either GameObject.FindWithTag or GameObject.Find does not return an object.
However you don’t need to find the gameobject again, as you already have a valid reference to it in the variable chara.
This code should do the job:
function TalkToNPC () {
//;
// Find all game objects with tag npc
var npcs : GameObject[];
npcs = GameObject.FindGameObjectsWithTag("npc");
var closest : GameObject;
var distance = Mathf.Infinity;
var position = transform.position;
// Find the closest one
for (var chara : GameObject in npcs) {
var diff = (chara.transform.position - position);
var curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = chara;
distance = curDistance;
}
}
if (distance < 800) {
Debug.Log ("The closest npc is" + closest)
chara.SendMessage ("dialogue");
}
}
It works!!! Thank you so much. I spent the whole night trying to solve this…
Now i can think to the external .txt file.
I created a .txt file called “Dialogues” and I placed it in the “Assets” folder.
Looking around I found this code:
var textFile : TextAsset;
var dialogLines : string[];
function Start()
{
// Make sure there is a text
// file assign before continuing
if(textfile)
{
// Add each line of the text file
// to the array using the new line
// as the delimiter
dialogLines = (textFile.text.Split("\n"[0]));
}
}
// Assign the first string
// in the array to a variable
var dialog : string = dialogLines[0];
But I don’t really understand how this works. Some tips?
Thanks for the help guys, I’m learning so much.
This answer shows the basics and has Javascript example code: How can I read data from a text file, putting a large amount of data into structures - Questions & Answers - Unity Discussions
It works! Thank you Duugu.
I still need your help guys. I tried to follow the video that BoredMormon kindly sent me. But I can only set messagebox always on the screen! I used the UI.
I need the messagebox to appear only when the npc and the player are talking.
And I can’t show the text in the messagebox. How can I do it? I also tried the function OnGUI but doesn’t work…
I solved the problem, I set the GUI.Box as trigger and I can draw a message in it. But when I try to set one of the dialogues in the .txt I get a Null Reference Exception error. I know what that means but I don’t know how to set my array as a reference type to use in GUI.Box.
var dataFile : TextAsset;
var dataPairs : Array;
var msg : int;
var ShowGUI : boolean;
var player : Object;
function dialogue () {
//Divide il documento in più dialoghi-------------
player = GameObject.FindWithTag("Player");
var returnChar = "\n"[0];
var commaChar = "|"[0];
var dataLines = dataFile.text.Split(returnChar);
var buildDataPairs = new ArrayList();
for (var dataLine in dataLines) {
var dataPair = dataLine.Split(commaChar);
buildDataPairs.Add(dataPair);
}
var dataPairs = buildDataPairs.ToArray();
//------------------------------------------------
ShowGUI = true;
Debug.Log(dataPairs[msg][0]);
}
function OnGUI () {
if (ShowGUI) {
//Draw Text letter by letter------------------
//--------------------------------------------
GUI.Box (Rect (Screen.width/68, Screen.height/1.465, 390, 70), dataPairs[msg][0]);
if (Input.GetKeyDown(KeyCode.X)){
ShowGUI = false;
player.SendMessage ("Update");
}
}
}
I post the code just to clear how i build up the script. The var I’m talking about is “dataPairs[msg][0]”.
How can I set this var to a reference type and use it correctly?