Articy:Draft sample integration

This script shows one way in which articy:draft flows can be made to work with AC's dialogue and conversation system. It is able to display articy speech and conversation trees in AC.

NOTE: For a thorough and robust link between AC and articy:draft, try Dialogue System on the Asset Store.

To use this script, paste it in a C# file named ArticyFlowIntegration, attach it to an Articy Flow Player component in your scene (provided by articy's own Unity integration package), and invoke its RunFlow method to run it. using System.Collections; using System.Collections.Generic; using UnityEngine; using Articy.Unity; using Articy.Unity.Interfaces; namespace AC { [RequireComponent (typeof (ArticyFlowPlayer))] public class ArticyFlowIntegration : MonoBehaviour, IArticyFlowPlayerCallbacks { 		public IArticyObject startObject; private ArticyFlowPlayer articyFlowPlayer; private Branch autoRunBranch; private Speech currentSpeech; private IList conversationBranches; private Conversation conversation; private NPC[] npcs; private bool isRunning; private bool isPaused; private void OnEnable { 			// Hook into the OnClickConversation event, which we'll use to handle conversation clicks EventManager.OnClickConversation += OnClickConversation; // Assign and disable the ArticyFlowPlayer component until we're ready for it 			articyFlowPlayer = GetComponent ; articyFlowPlayer.enabled = false; // Get a collection of NPCs to refer to later npcs = FindObjectsOfType ; } 		private void Update { 			if (isPaused) { 				UpdateFlow ; } 		}  		// Call this function externally to run the ArticyFlowPlayer public void RunFlow { 			// Place the game into scripted-cutscene mode KickStarter.stateHandler.StartCutscene ; // Make sure a Conversation component is attached, and is set to rely on script for its interactions if (conversation == null) { 				conversation = gameObject.AddComponent ; } 			conversation.interactionSource = InteractionSource.CustomScript; // Enable the ArticyFlowPlayer component articyFlowPlayer.enabled = true; isRunning = true; // Record the StartOn IArticyObject, or restore it if this has already been played once if (startObject == null) { 				startObject = articyFlowPlayer.StartOn; } 			else { 				articyFlowPlayer.StartOn = startObject; } 		}  		private void OnDisable { 			// Unhook from the OnClickConversation event EventManager.OnClickConversation -= OnClickConversation; } 		private void UpdateFlow { 			// Wait for no Speech or Conversation to be active if ((currentSpeech == null || !currentSpeech.isAlive) && KickStarter.playerInput.activeConversation == null) { 				currentSpeech = null; if (autoRunBranch != null) { 					// Play the next branch automatically articyFlowPlayer.Play (autoRunBranch); } 				else if (conversationBranches != null) { 					// Show the branches as a Conversation conversation.Interact ; } 				else if (KickStarter.playerInput.activeConversation == null) { 					// Can't find anything else to run, so stop the flow StopRunning ; } 			}  		}  		public void OnFlowPlayerPaused (IFlowObject aObject) { 			if (aObject is IDialogue) { 				articyFlowPlayer.Play ; return; } 			isPaused = true; currentSpeech = null; // Check for a speaking character var dlgSpeaker = aObject as IObjectWithSpeaker; if (dlgSpeaker != null) { 				Sprite portraitGraphic = null; string displayName = ""; string speechText = ""; // Grab the speaker's portrait graphic if (dlgSpeaker.Speaker != null) { 					IAsset speakerAsset = ((dlgSpeaker.Speaker as IObjectWithPreviewImage).PreviewImage.Asset as IAsset); if (speakerAsset != null) { 						portraitGraphic = speakerAsset.LoadAssetAsSprite ; } 				}  				// Grab the speaker's name var modelWithDisplayName = aObject as IObjectWithDisplayName; if (modelWithDisplayName != null) { 					displayName = modelWithDisplayName.DisplayName; } 				// Assign the portrait graphic and name to the correct AC character Char speaker = GetCharacterWithName (dlgSpeaker.Speaker.TechnicalName); if (speaker != null) { 					if (!string.IsNullOrEmpty (displayName)) { 						speaker.speechLabel = displayName; } 					if (portraitGraphic != null && portraitGraphic.texture != null) { 						speaker.portraitIcon.texture = portraitGraphic.texture; } 				}  				// Extract the dialogue text and play it in AC  				var txtObj = aObject as IObjectWithText; if (txtObj != null) { 					speechText = txtObj.Text; currentSpeech = KickStarter.dialog.StartDialog (speaker, speechText); } 			}  		}  		public void OnBranchesUpdated (IList aBranches) { 			conversationBranches = null; autoRunBranch = null; if (aBranches.Count == 1) { 				// Only one branch, so prepare to run it automatically autoRunBranch = aBranches[0]; } 			else if (aBranches.Count > 1) { 				// Multiple branches, so prepare them as a Conversation conversationBranches = aBranches; conversation.interactionSource = InteractionSource.CustomScript; conversation.options.Clear ; for (int i=0; i<aBranches.Count; i++) { 					string optionText = "Option " + i.ToString ; var obj = aBranches[i].Target as IObjectWithMenuText; if (obj != null) { 						optionText = obj.MenuText; } 					ButtonDialog buttonDialog = new ButtonDialog (i, optionText, true); conversation.options.Add (buttonDialog); } 			}  		}  		private void StopRunning { 			if (isRunning) { 				// End the flow, and exit scripted-cutscene mode isRunning = false; articyFlowPlayer.enabled = false; conversationBranches = null; currentSpeech = null; KickStarter.stateHandler.EndCutscene ; } 		}  		private void OnClickConversation (Conversation _conversation, int optionID) { 			if (conversation == _conversation) { 				// Run the Branch if the object's own Conversation component was interacted with KickStarter.playerInput.EndConversation ; articyFlowPlayer.Play (conversationBranches[optionID]); conversationBranches = null; } 		}  		private Char GetCharacterWithName (string technicalName) { 			if (!string.IsNullOrEmpty (technicalName)) { 				foreach (NPC npc in npcs) { 					if (npc.gameObject.name == technicalName) { 						return npc; } 				}  				if (KickStarter.player) { 					if (KickStarter.player.gameObject.name == technicalName) { 						return KickStarter.player; } 				}  			}  			return null; } 		public bool IsRunning { 			get { 				return isRunning; } 		}  	}  }

Additionally, this script allows for your articy project's language to be automatically synced with AC's language: using System.Collections; using System.Collections.Generic; using UnityEngine; using Articy.Unity; namespace AC { public class ArticyLanguageSync : MonoBehaviour { 		public string[] languageNames; private void OnEnable { 			EventManager.OnChangeLanguage += OnChangeLanguage; OnChangeLanguage (Options.GetLanguage ); } 		private void OnDisable { 			EventManager.OnChangeLanguage -= OnChangeLanguage; } 		private void OnChangeLanguage (int index) { 			if (languageNames != null && languageNames.Length > index) { 				string languageName = languageNames[index]; ArticyDatabase.Localization.Language = languageName; ACDebug.Log ("Articy:Draft - changed language to " + languageName, this); } 			else { 				ACDebug.LogWarning ("Articy:Draft - cannot change language because languageNames does not have " + (index+1) + " elements.", this); } 		}  	}  }