2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
6.5 KiB
C#

using System.Collections.Generic;
using Articy.Unity;
using Articy.Unity.Interfaces;
using Articy.Unity.Utils;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(ArticyFlowPlayer))]
public class ArticyDebugFlowPlayer : MonoBehaviour, IArticyFlowPlayerCallbacks
{
[Header("UI")]
// a prefab used to instantiate a branch
public GameObject branchPrefab;
// the display name label, used to show the name of the current paused on node
public Text displayNameLabel;
// the main text label, used to show the text of the current paused on node
public Text textLabel;
// our 3 info labels in the middle of the panel, displaying basic information about the current pause.
public Text typeLabel;
public Text technicalNameLabel;
public Text idLabel;
// the ui target for our vertical list of branch buttons
public RectTransform branchLayoutPanel;
// the preview image ui element. A simple 64x64 image that will show the articy preview image or speaker, depending on the current pause.
public Image previewImagePanel;
[Header("Options")]
// you can set this to true to see false branches in red, very helpful for debugging.
public bool showFalseBranches = false;
// the flow player component found on this game object
private ArticyFlowPlayer flowPlayer;
// Used to initializes our debug flow player handler.
void Start()
{
// you could assign this via the inspector but this works equally well for our purpose.
flowPlayer = GetComponent<ArticyFlowPlayer>();
Debug.Assert(flowPlayer != null, "ArticyDebugFlowPlayer needs the ArticyFlowPlayer component!.");
// by clearing at start we can safely have a prefab instantiated in the editor for our convenience and automatically get rid of it when we play.
ClearAllBranches();
// just a little reminder text to actually set a start on object, otherwise the Flowplayer won't do anything and just idles.
if (flowPlayer != null && flowPlayer.StartOn == null)
textLabel.text = "<color=green>No object selected in the flow player. Navigate to the ArticyflowPlayer and choose a StartOn node.</color>";
}
// This is called everytime the flow player reaches and object of interest.
public void OnFlowPlayerPaused(IFlowObject aObject)
{
if(aObject != null)
{
typeLabel.text = aObject.GetType().Name;
// reset, just in case we don't have any
idLabel.text = string.Empty;
technicalNameLabel.text = string.Empty;
var articyObj = aObject as IArticyObject;
if(articyObj != null)
{
idLabel.text = articyObj.Id.ToHex();
technicalNameLabel.text = articyObj.TechnicalName;
}
}
// To show the displayname in the ui of the current node
var modelWithDisplayName = aObject as IObjectWithDisplayName;
if (modelWithDisplayName != null)
displayNameLabel.text = modelWithDisplayName.DisplayName;
else
displayNameLabel.text = string.Empty;
// To show text in the ui of the current node
// we just check if it has a text property by using the object property interfaces, if it has the property we use it to show the text in our main text label.
var modelWithText = aObject as IObjectWithText;
if (modelWithText != null)
textLabel.text = modelWithText.Text;
else
textLabel.text = string.Empty;
// this will make sure that we find a proper preview image to show in our ui.
ExtractCurrentPausePreviewImage(aObject);
}
// called everytime the flow player encounteres multiple branches, or paused on a node and want to tell us how to continue.
public void OnBranchesUpdated(IList<Branch> aBranches)
{
// we clear all old branch buttons
ClearAllBranches();
// for every branch provided by the flow player, we will create a button in our vertical list
foreach (var branch in aBranches)
{
// if the branch is invalid, because a script evaluated to false, we don't create a button, unless we want to see false branches.
if (!branch.IsValid && !showFalseBranches) continue;
// we create a our button prefab and parent it to our vertical list
var btn = Instantiate(branchPrefab);
var rect = btn.GetComponent<RectTransform>();
rect.SetParent(branchLayoutPanel, false);
// here we make sure to get the Branch component from our button, either by referencing an already existing one, or by adding it.
var branchBtn = btn.GetComponent<ArticyDebugBranch>();
if(branchBtn == null)
branchBtn = btn.AddComponent<ArticyDebugBranch>();
// this will assign the flowplayer and branch and will create a proper label for the button.
branchBtn.AssignBranch(flowPlayer, branch);
}
}
// convenience method to clear everything underneath our branch layout panel, this should only be our dynamically created branch buttons.
private void ClearAllBranches()
{
foreach (Transform child in branchLayoutPanel)
Destroy(child.gameObject);
}
// method to find a preview image to show in the ui.
private void ExtractCurrentPausePreviewImage(IFlowObject aObject)
{
IAsset articyAsset = null;
previewImagePanel.sprite = null;
// to figure out which asset we could show in our preview, we first try to see if it is an object with a speaker
var dlgSpeaker = aObject as IObjectWithSpeaker;
if (dlgSpeaker != null)
{
// if we have a speaker, we extract it, because now we have to check if it has a preview image.
ArticyObject speaker = dlgSpeaker.Speaker;
if (speaker != null)
{
var speakerWithPreviewImage = speaker as IObjectWithPreviewImage;
if (speakerWithPreviewImage != null)
{
// our speaker has the property for preview image and we assign it to our asset.
articyAsset = speakerWithPreviewImage.PreviewImage.Asset;
}
}
}
// if we have no asset until now, we could try to check if the target itself has a preview image.
if (articyAsset == null)
{
var objectWithPreviewImage = aObject as IObjectWithPreviewImage;
if (objectWithPreviewImage != null)
{
articyAsset = objectWithPreviewImage.PreviewImage.Asset;
}
}
// and if we have an asset at this point, we load it as a sprite and show it in our ui image.
if (articyAsset != null)
{
previewImagePanel.sprite = articyAsset.LoadAssetAsSprite();
}
}
public void CopyTargetLabel(BaseEventData aData)
{
var pointerData = aData as PointerEventData;
if (pointerData != null)
GUIUtility.systemCopyBuffer = pointerData.pointerPress.GetComponent<Text>().text;
Debug.LogFormat("Copied text \"{0}\" into clipboard!", GUIUtility.systemCopyBuffer);
}
}