I’ve seen a few other topics on this, but ran into some issues implementing some of the changes. It’s probably an easy fix, but I’ve had one too many late nights and can’t quite figure it out.
I started by implementing the changes detailed here: Dialogue only showing up within a certain distance? - Unity Courses / Ask - GameDev.tv
The line I ran into issue with was this one:
PlayerConversant.StartDialogueAction(dialogue, speaker);
Speaker does not exist in the current context (inside AIConversant), so I’m wondering if I’ve missed a step. I’ll post my scripts below:
The PlayerConversant.cs
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using RPG.Core;
using RPG.Movement;
namespace RPG.Dialogue
{
public class PlayerConversant : MonoBehaviour, IAction
{
[SerializeField] string playerName;
Dialogue currentDialogue;
DialogueNode currentNode = null;
AIConversant currentConversant = null;
AIConversant targetConversant;
bool isChoosing = false;
public event Action onConversationUpdated;
public void StartDialogueAction(Dialogue dialogue, AIConversant speaker)
{
Debug.Log($"StartDialogueAction {speaker}/{dialogue}");
if (currentConversant != null && currentConversant == speaker) return;
if (currentDialogue != null) Quit();
if (dialogue == null)
{
return;
}
GetComponent<ActionScheduler>().StartAction(this);
targetConversant = speaker;
currentDialogue = dialogue;
}
private void Update()
{
if (targetConversant)
{
if (Vector3.Distance(targetConversant.transform.position, transform.position) > 3)
{
GetComponent<Mover>().MoveTo(targetConversant.transform.position, 1);
}
else
{
GetComponent<Mover>().Cancel();
StartDialogue();
}
}
}
public void StartDialogue()
{
currentConversant = targetConversant;
targetConversant = null;
currentNode = currentDialogue.GetRootNode();
TriggerEnterAction();
onConversationUpdated();
}
public void Quit()
{
currentDialogue = null;
TriggerExitAction();
currentNode = null;
isChoosing = false;
currentConversant = null;
onConversationUpdated();
}
public bool IsActive()
{
return currentDialogue != null;
}
public bool IsChoosing()
{
return isChoosing;
}
public string GetText()
{
if (currentNode == null)
{
return "";
}
return currentNode.GetText();
}
public string GetCurrentConversantName()
{
if (isChoosing)
{
return playerName;
}
else
{
return currentConversant.GetName();
}
}
public IEnumerable<DialogueNode> GetChoices()
{
return currentDialogue.GetPlayerChildren(currentNode);
}
public void SelectChoice(DialogueNode chosenNode)
{
currentNode = chosenNode;
TriggerEnterAction();
isChoosing = false;
// Short Responses (As Shown On Button):
Next();
// Longer Response Event Trigger:
// onConversationUpdated();
}
public void Next()
{
int numPlayerResponses = currentDialogue.GetPlayerChildren(currentNode).Count();
if (numPlayerResponses > 0)
{
isChoosing = true;
TriggerExitAction();
onConversationUpdated();
return;
}
DialogueNode[] children = currentDialogue.GetAIChildren(currentNode).ToArray();
if (children.Length > 0)
{
int randomIndex = UnityEngine.Random.Range(0, children.Count());
TriggerExitAction();
currentNode = children[randomIndex];
TriggerEnterAction();
onConversationUpdated();
}
else
{
Quit();
}
}
public bool HasNext()
{
return currentDialogue.GetAllChildren(currentNode).Count() > 0;
}
private void TriggerEnterAction()
{
if (currentNode != null)
{
TriggerAction(currentNode.GetOnEnterAction());
}
}
private void TriggerExitAction()
{
if (currentNode != null)
{
TriggerAction(currentNode.GetOnExitAction());
}
}
private void TriggerAction(string action)
{
if (action == "") { return; }
foreach (DialogueTrigger trigger in currentConversant.GetComponents<DialogueTrigger>())
{
trigger.Trigger(action);
}
}
public void Cancel()
{
GetComponent<Mover>().Cancel();
Quit();
}
}
}
The AIConversant
using UnityEngine;
using RPG.Control;
using RPG.Attributes;
namespace RPG.Dialogue
{
public class AIConversant : MonoBehaviour, IRaycastable
{
[SerializeField] Dialogue dialogue = null;
[SerializeField] string conversantName;
public CursorType GetCursorType()
{
return CursorType.Dialogue;
}
public bool HandleRaycast(PlayerController callingController)
{
if (dialogue == null)
{
return false;
}
if (GetComponent<Health>().IsDead())
{
return false;
}
if (Input.GetMouseButtonDown(0))
{
callingController.GetComponent<PlayerConversant>().StartDialogueAction(dialogue, speaker);
}
return true;
}
public string GetName()
{
return conversantName;
}
}
}
Thank you for being such a great help throughout the project thus far!