Reputation: 225
I have been working on getting a dialog system to work for the past few days but I am having a few problems with it. The first problem is that I need a button press while the text is being typed to finish immediately before moving onto the next sentence, when I tried it just came out with some weird bugs so I reverted it. The second problem I keep running into is that when I copy the NPC and change the dialog of the second NPC, they both just say what the first NPC's dialog is set to.
Currently, I have a collider around the sides of the player and when the player's side colliders touch the NPC's while the space bar is pressed it triggers the conversation. Here is my code:
Player script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : Character
{
public BasicNPCPrototype NPCPrototype;
private bool nearNPC = false;
// Use this for initialization
protected override void Start()
{
// This needs to be here because the Override normally would override the Character Start function so we have this here to tell the Character Start function to go
base.Start();
}
// Update is called once per frame
protected override void Update() // Because the parent script (The Character script) is using protected virtual update it will Override the local update function (This one) so you have to write protected override to make sure they both run
{
// Call the GetInput Function
GetInput();
CheckIfNear();
// This needs to be here because the Override normally would override the Character Update function so we have this here to tell the Character Update function to go
base.Update();
}
void GetInput()
{
// If the player is active (playerActive is a protected bool in the "Character" script)
if(playerActive)
{
// Normalize "direction" so moving in both directions won't speed up the character (May not be nessisary when using Input.GetAxis, Needs testing)
direction = Vector2.zero;
// Get the horizontal Axis and put in the X value of "direction"
direction.x = Input.GetAxisRaw("Horizontal");
// Get the Vertical Axis and put in the Y value of "direction"
direction.y = Input.GetAxisRaw("Vertical");
}
}
// When the players trigger collider touches somthing
void OnTriggerEnter2D(Collider2D collision)
{
// Check to see if it has the "NPC" tag
if(collision.tag == "NPC")
{
// Set "nearNPC" bool to tue
nearNPC = true;
}
}
// When the players trigger collider exits somthing
void OnTriggerExit2D(Collider2D collision)
{
// Check to see if it has the "NPC" tag
if (collision.tag == "NPC")
{
// Set "nearNPC" bool to false
nearNPC = false;
}
}
private void CheckIfNear()
{
// If nearNPC bool is true
if (nearNPC == true)
{
// If the "Jump" Keybind is press
if (Input.GetButtonUp("Jump"))
{
// Call the Speak function in the NPCPrototype script
NPCPrototype.Speak();
}
}
}
}
NPC Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasicNPCPrototype : MonoBehaviour
{
public Dialogue dialogue;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
public void Speak()
{
// Call the "StartDialogue" function in the DialogueManager and pass in our dialogue variable
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
}
}
Here's my Dialog Manager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
public float waitBeforeDisable = 1f;
public GameObject dialogueBox;
public Text nameText;
public Text dialogueText;
public Animator animator;
private Queue<string> sentences;
private bool conversationActive = false;
// Use this for initialization
void Start()
{
//dialogueBox.SetActive(false);
sentences = new Queue<string>();
}
public void StartDialogue(Dialogue dialogue)
{
if (conversationActive == false)
{
dialogueBox.SetActive(true);
conversationActive = true;
animator.SetBool("isOpen", true);
nameText.text = dialogue.name;
sentences.Clear();
foreach (string sentence in dialogue.sentences)
{
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
if (conversationActive == true)
{
DisplayNextSentence();
}
}
public void DisplayNextSentence()
{
if (sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
StopAllCoroutines();
StartCoroutine(TypeSentence(sentence));
}
void EndDialogue()
{
animator.SetBool("isOpen", false);
StartCoroutine("DisableDialogueBox");
conversationActive = false;
}
IEnumerator TypeSentence(string sentence)
{
dialogueText.text = "";
foreach (char letter in sentence.ToCharArray())
{
dialogueText.text += letter;
yield return null;
}
}
IEnumerator DisableDialogueBox()
{
yield return new WaitForSeconds (waitBeforeDisable);
dialogueBox.SetActive(false);
}
}
I'm realitivly new to coding, if I could get some help that would be great! If you have questions about my question feel free to ask.
Upvotes: 1
Views: 2931
Reputation: 15951
NPCPrototype
referenceWhere are you setting the value of NPCPrototype? – Draco18s
@Draco18s In the inspector – Ultra Gamer
Because you set it in the inspector (and no where else) it is never going to change. If you want the dialog to be from a specific NPC, you need to get the component from that NPC when the "am I nearby?" check/collision. eg.:
void OnTriggerEnter2D(Collider2D collision)
{
// Check to see if it has the "NPC" tag
if(collision.tag == "NPC")
{
// Set "nearNPC" bool to tue
nearNPC = true;
NPCPrototype = collision.gameObject.GetComponent<BasicNPCPrototype>();
}
}
Upvotes: 2