public bool Verify() { //Check if only one entry int entryNodes = 0; foreach (var node in this.nodes) { if (node is EntryNode) { entryNodes++; entry = node as EntryNode; } } bool verifed = true; if (entryNodes != 1) { Debug.LogError("DialogueGraph '" + name + "' only supports one entry node! You have " + entryNodes); verifed = false; } //Need to verify that you will never infinite loop without a halt. Aka thing -> combiner -> truth check -> back to that combiner. If the truth check or anything that doesn't halt does not pass an halt before returning to the same //Need to verify that there is always an exit condition, that you will never be looping at any stage of the nodes. //Need to verify if all choices have exits return(verifed); }
public override void MoveNext() { DialogueGraph fmGraph = graph as DialogueGraph; if (fmGraph.current != this) { Debug.LogWarning("Node isn't active"); return; } int totalWeight = 0; for (int i = 0; i < exits.Count; i++) { totalWeight += exits[i]; } int randomWeight = Random.Range(0, totalWeight + 1); string exitName = "exits 0"; for (int i = 0; i < exits.Count; i++) { randomWeight -= exits[i]; if (randomWeight <= 0) { exitName = "exits " + i; break; } } var exitPort = this.GetOutputPort(exitName); if (exitPort == null) { Debug.Log("Invalid exit port '" + exitPort + "' for node " + name); } if (!exitPort.IsConnected) { fmGraph.current = null; return; } int index = Random.Range(0, exitPort.ConnectionCount); var exitNode = exitPort.GetConnection(index); DialogueNodeBase node = exitNode.node as DialogueNodeBase; node.OnEnter(); }
public void Reset() { state = RunningState.Running; _currentNode = null; foreach (var node in nodes) { (node as DialogueNodeBase).Reset(); } }
public void Execute() { if (state == RunningState.Stop) { return; } if (_entryNode == null) { Debug.LogWarning("EntryNode Can't Find"); return; } if (_currentNode == null) { var entryOutput = _entryNode.GetOutputPort().Connection; if (entryOutput != null) { _currentNode = entryOutput.node as DialogueNodeBase; _currentNode.OnEnter(); } } if (_currentNode == null) { Debug.LogWarning("CurrentNode Can't Find"); return; } if (_currentNode.Execute()) { var outPut = _currentNode.GetOutputPort().Connection; if (outPut != null) { _currentNode.OnExit(); _currentNode = outPut.node as DialogueNodeBase; _currentNode.OnEnter(); } else { state = RunningState.Stop; } } }
public override void MoveNext() { DialogueGraph fmGraph = graph as DialogueGraph; if (fmGraph.current != this) { Debug.LogWarning("Node isn't active"); return; } var exitPort = this.GetOutputPort("exit"); if (exitPort == null) { Debug.Log("Invalid exit port '" + exitPort + "' for node " + name); fmGraph.current = null; return; } if (!exitPort.IsConnected) { fmGraph.current = null; return; } int index = Random.Range(0, exitPort.ConnectionCount); var exitNode = exitPort.GetConnection(index); if (exitNode == null) { Debug.Log("Could not find ending for random branch"); fmGraph.current = null; return; } DialogueNodeBase node = exitNode.node as DialogueNodeBase; node.OnEnter(); }
public void Play(DialogueSystem system) { if (!Verify()) { Debug.Log("Failed to play DialogueGraph: " + name); return; } //Get dependencies valueRegistry = MainInstances.Get <ValueRegistry>(); agentRegistry = MainInstances.Get <AgentRegistry>(); stringRegistry = MainInstances.Get <StringRegistry>(); currentSystem = system; current = entry; current.MoveNext(); //We started the graph }
private IEnumerator PresentEnumerator(Action callback) { Debug.Log("Starting Dialogue!"); int currentRate = 0; int maxRateLimit = 50; // How many times can we loop without yielding, so if an infinite loop happens we dont freeze frame while (CurrentGraph.current != null) { currentRate++; CurrentNodeActive = CurrentGraph.current; if (currentRate > maxRateLimit) { yield return(null); currentRate = 0; Debug.LogWarning("Reached rate limit, yielding and reset limit"); } var currentNode = CurrentGraph.current; isNodeWorking = false; Debug.Log("Current node " + currentNode.name); switch (currentNode) { case DialogueNode d: isNodeWorking = true; currentRate = 0; DialogueBox(d); break; case DisplayValueNode v: isNodeWorking = true; currentRate = 0; DialogueBox(v); break; case DisplayStringNode s: isNodeWorking = true; currentRate = 0; DialogueBox(s); break; case ChoiceNode c: isNodeWorking = true; currentRate = 0; StartCoroutine(ChoiceBox(c)); break; case TextEffectNode t: Typer.SetTextEffect(t); break; case AgentNode a: Typer.SetAgent(a); break; case PauseNode p: if (isSkipping) { break; } Debug.Log("Pausing for " + p.PauseTime); float currentTime = 0; while (currentTime < p.PauseTime) { currentTime += Time.unscaledDeltaTime; if (ContinueInput) { isSkipping = true; break; } yield return(null); } //Incase of missed frame if (ContinueInput) { isSkipping = true; } break; } while (isNodeWorking) { yield return(null); } CurrentGraph.Continue(); } Debug.Log("Finished Dialogue!"); currentPresentationCoroutine = null; Typer.Play("Done"); Typer.ResetTyper(); CanvasObject.enabled = false; callback?.Invoke(); }