// Copyright (c) Pixel Crushers. All rights reserved.
using UnityEngine;
namespace PixelCrushers.DialogueSystem
{
///
/// A static utility class for Sequencer.
///
public static class SequencerTools
{
///
/// Sequencer commands usually specify a subject to which the command applies (e.g., where to
/// aim the camera). This utility function that returns the specified subject.
///
///
/// The transform of the specified subject, or null if the specifier names a game
/// object that isn't in the scene.
///
///
/// "speaker", "listener", or the name of a game object in the scene.
///
///
/// Speaker.
///
///
/// Listener.
///
///
/// Default subject.
///
public static Transform GetSubject(string specifier, Transform speaker, Transform listener, Transform defaultSubject = null)
{
if (string.IsNullOrEmpty(specifier))
{
return defaultSubject ?? speaker;
}
else if (string.Compare(specifier, SequencerKeywords.Speaker, System.StringComparison.OrdinalIgnoreCase) == 0)
{
return speaker;
}
else if (string.Compare(specifier, SequencerKeywords.Listener, System.StringComparison.OrdinalIgnoreCase) == 0)
{
return listener;
}
else
{
GameObject go = FindSpecifier(specifier);
return (go != null) ? go.transform : defaultSubject;
}
}
///
/// Returns true if specifier specifies a tag ('tag=foo').
///
public static bool SpecifierSpecifiesTag(string specifier)
{
return !string.IsNullOrEmpty(specifier) && specifier.StartsWith("tag=", System.StringComparison.OrdinalIgnoreCase);
}
///
/// Assumes specifier specifies a tag ('tag=foo'). Returns the tag.
///
public static string GetSpecifiedTag(string specifier)
{
return specifier.Substring("tag=".Length);
}
///
/// Finds a game object with the specified name, returning any match in scene before
/// trying to return any non-scene matches in the project. Checks GameObjects registered
/// with the specifier as its actor name first.
///
///
/// The specified game object.
///
///
/// The name to search for.
///
/// Only search active objects in the scene.
public static GameObject FindSpecifier(string specifier, bool onlyActiveInScene = false)
{
if (string.IsNullOrEmpty(specifier)) return null;
// Check for 'tag=' keyword:
if (SpecifierSpecifiesTag(specifier))
{
var tag = GetSpecifiedTag(specifier);
var taggedGO = GameObject.FindGameObjectWithTag(tag);
if (taggedGO != null) return taggedGO;
var results = Tools.FindGameObjectsWithTagHard(tag);
return (results.Length > 0) ? results[0] : null;
}
// Search registered actors:
var t = CharacterInfo.GetRegisteredActorTransform(specifier);
if (t != null) return t.gameObject;
// Search for active objects in scene:
var match = GameObject.Find(specifier);
if (match != null) return match;
if (onlyActiveInScene) return null;
// Search for all objects in scene, including inactive as long as it's a child of an active object:
match = Tools.GameObjectHardFind(specifier);
if (match != null) return match;
// Search for all objects, including loaded-but-not-instantiated (i.e., prefabs):
foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
{
if (string.Compare(specifier, go.name, System.StringComparison.OrdinalIgnoreCase) == 0)
{
return go;
}
}
return null;
}
///
/// Gets the default camera angle for a subject.
///
/// The default camera angle. If the subject doesn't have a DefaultCameraAngle
/// component, returns "Closeup".
/// Subject.
public static string GetDefaultCameraAngle(Transform subject)
{
var defaultCameraAngle = (subject != null) ? subject.GetComponentInChildren() : null;
return (defaultCameraAngle != null) ? defaultCameraAngle.cameraAngle : "Closeup";
}
///
/// Gets parameters[i].
///
///
/// parameters[i], or the specified default value if i is out of range.
///
///
/// An array of parameters.
///
///
/// The index into parameters[]
///
///
/// The default value to return if i is out of range.
///
public static string GetParameter(string[] parameters, int i, string defaultValue = null)
{
return ((parameters != null) && (i < parameters.Length)) ? parameters[i] : defaultValue;
}
///
/// Gets parameters[i] as the specified type. Culture invariant (i.e., floats use '.' for
/// decimal point).
///
///
/// parameters[i] as type T, or the specified default value if i is out of range
/// or parameters[i] can't be converted to type T.
///
///
/// An array of parameters.
///
///
/// The index into parameters[]
///
///
/// The default value to return if i is out of range or the parameter can't be converted
/// to type T.
///
///
/// The type to convert the parameter to.
///
///
/// // Get parameters[1] as a float, defaulting to 5f:
/// float duration = GetParameterAs(parameters, 1, 5f);
///
public static T GetParameterAs(string[] parameters, int i, T defaultValue)
{
try
{
return ((parameters != null) && (i < parameters.Length))
? (T)System.Convert.ChangeType(parameters[i], typeof(T), System.Globalization.CultureInfo.InvariantCulture)
: defaultValue;
}
catch (System.Exception)
{
return defaultValue;
}
}
///
/// Gets the i-th parameter as a float.
///
///
/// The parameter as float, or defaultValue if out of range.
///
///
/// The array of parameters.
///
///
/// The zero-based index of the parameter.
///
///
/// The default value to use if the parameter doesn't exist or isn't valid for the type.
///
public static float GetParameterAsFloat(string[] parameters, int i, float defaultValue = 0)
{
return GetParameterAs(parameters, i, defaultValue);
}
///
/// Gets the i-th parameter as an int.
///
///
/// The parameter as an int, or defaultValue if out of range.
///
///
/// The array of parameters.
///
///
/// The zero-based index of the parameter.
///
///
/// The default value to use if the parameter doesn't exist or isn't valid for the type.
///
public static int GetParameterAsInt(string[] parameters, int i, int defaultValue = 0)
{
return GetParameterAs(parameters, i, defaultValue);
}
///
/// Gets the i-th parameter as a bool.
///
///
/// The parameter as bool, or defaultValue if out of range.
///
///
/// The array of parameters.
///
///
/// The zero-based index of the parameter.
///
///
/// The default value to use if the parameter doesn't exist or isn't valid for the type.
///
public static bool GetParameterAsBool(string[] parameters, int i, bool defaultValue = false)
{
return GetParameterAs(parameters, i, defaultValue);
}
///
/// Gets the audio source on a subject, using the Dialogue Manager as the subject if the
/// specified subject is null. If no audio source exists on the subject, this
/// method adds one.
///
/// The audio source.
/// Subject.
public static AudioSource GetAudioSource(Transform subject)
{
GameObject go = (subject != null) ? subject.gameObject : DialogueManager.instance.gameObject;
AudioSource audio = go.GetComponentInChildren();
return (audio != null) ? audio : go.AddComponent();
}
///
/// Checks if a Lua variable "Mute" is true.
///
/// true if audio is muted; otherwise, false.
public static bool IsAudioMuted()
{
return DialogueLua.GetVariable("Mute").asBool;
}
}
}