2024-01-19 16:30:05 +01:00
//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
/ /
// Purpose: Part of the My Behaviour Tree Controller Code
/ /
//=============================================================================
using System.Collections ;
using System.Collections.Generic ;
using UnityEngine ;
using UnityEngine.Video ;
using MyBT ;
using System.Linq ;
#if FMOD_AVAILABLE
using FMODUnity ;
# endif
#if UNITY_EDITOR
using UnityEditor ;
using UnityEditor.SceneManagement ;
[CustomEditor(typeof(BTC))]
public class BehaviourTreeControllerInspector : Editor {
public override void OnInspectorGUI ( ) {
BTC myTarget = ( BTC ) target ;
if ( GUILayout . Button ( "ClearObjects" ) ) {
myTarget . ClearObjects ( ) ;
SetDirty ( myTarget ) ;
}
if ( GUILayout . Button ( "UpdateObjects" ) ) {
myTarget . UpdateObjects ( ) ;
SetDirty ( myTarget ) ;
}
DrawDefaultInspector ( ) ;
}
public void SetDirty ( BTC myTarget ) {
EditorUtility . SetDirty ( myTarget ) ;
EditorSceneManager . MarkSceneDirty ( myTarget . gameObject . scene ) ;
}
}
# endif
public class BTC : MonoBehaviour {
static BTC _instance = null ;
public static BTC Instance {
get {
if ( _instance ! = null ) {
return _instance ;
}
if ( _instance = = null ) {
_instance = Resources . FindObjectsOfTypeAll < BTC > ( ) . FirstOrDefault ( ) ;
if ( _instance = = null ) {
_instance = new GameObject ( "BTC" , typeof ( BTC ) ) . GetComponent < BTC > ( ) ;
}
}
return _instance ;
}
}
public List < ComponentController > namedObjects = new List < ComponentController > ( ) ;
#region update list of objects in rooms
public void ClearObjects ( ) {
namedObjects = new List < ComponentController > ( ) ;
}
public T GetNamedObject < T > ( string objectName ) where T : ComponentController {
for ( int i = namedObjects . Count - 1 ; i > = 0 ; i - - ) {
T ngo = namedObjects [ i ] as T ;
if ( ngo ! = null ) {
// if name equals
if ( ngo . objectName = = objectName ) {
return ngo ;
}
}
}
return null ;
}
public List < ComponentHandler > GetHandlers ( string objectName ) {
ComponentController ctrl = GetNamedObject < ComponentController > ( objectName ) ;
if ( ctrl ! = null )
return ctrl . handlers . ToList ( ) ;
return new List < ComponentHandler > ( ) ;
}
public bool autoUpdateAllObjects = true ;
public void UpdateObjects ( ) {
// iterate all objects in scene
foreach ( ComponentController namedObject in Resources . FindObjectsOfTypeAll < ComponentController > ( ) ) {
if ( autoUpdateAllObjects ) {
namedObject . UpdateObject ( ) ;
}
// get object room id, create if not existing
// RoomData roomData = GetRoomData(namedObject.roomId);
// if (roomData != null) {
// if room contains object (name equals), overwrite
bool objectIdFound = false ;
bool objectNameFound = false ;
for ( int i = 0 ; i < namedObjects . Count ; i + + ) {
if ( namedObjects [ i ] . GetInstanceID ( ) = = namedObject . GetInstanceID ( ) ) {
namedObjects [ i ] = namedObject ;
objectIdFound = true ;
// if (objectIdFound) {
// Debug.Log($"object {namedObject.name} already in list as {namedObject.GetInstanceID()}");
// }
}
// else {
// Debug.Log("UpdateObjects: match check failed "+roomData.namedObjects[i].objectName+" != "+namedObject.objectName );
// }
if ( namedObjects [ i ] . objectName = = namedObject . objectName ) {
objectNameFound = true ;
}
}
// if object not found, append to list
if ( objectNameFound & & ! objectIdFound ) {
Debug . LogWarning ( $"Object with name {namedObject.name} already exists, adding a unque id" ) ;
namedObject . uniqueId = namedObject . GetInstanceID ( ) . ToString ( ) ;
namedObject . UpdateObject ( ) ;
}
if ( ! objectIdFound & & ! objectNameFound ) {
namedObjects . Add ( namedObject ) ;
}
if ( ! objectNameFound & & objectIdFound ) {
Debug . LogWarning ( $"Found obsolete object {namedObject.name}, refresh data" ) ;
}
// }
// else {
// Debug.LogError("should not happen: roomData undefined");
// }
}
}
# endregion
#region general play, pause, unpause, stop
[Task]
public void Run ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Run ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.Run: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void Abort ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Abort ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.Abort: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void IsRunning ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . All ( handler = > handler . IsRunning ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.IsRunning: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void Show ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Show ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.Show: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void Hide ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Hide ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.Hide: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void FadeIn ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . FadeIn ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.FadeIn: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void FadeOut ( string objectName ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . FadeOut ( Task . getState ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.FadeOut: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void Set ( string objectName , string key , string value ) {
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Set ( Task . getState , key , value ) ) ;
if ( handlers . Count = = 0 ) {
Debug . LogWarning ( $"BTC.Set: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
2024-08-21 17:15:24 +02:00
[Task]
public void Enable ( string objectName )
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Enable ( Task . getState ) ) ;
if ( handlers . Count = = 0 )
{
Debug . LogWarning ( $"BTC.Enable: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void Disable ( string objectName )
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . Disable ( Task . getState ) ) ;
if ( handlers . Count = = 0 )
{
Debug . LogWarning ( $"BTC.Disable: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
public void SetPosition ( string objectName , float newX , float newY , float newZ )
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . SetPosition ( Task . getState , newX , newY , newZ ) ) ;
if ( handlers . Count = = 0 )
{
Debug . LogWarning ( $"BTC.SetPosition: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
2024-09-23 17:11:21 +02:00
[Task]
public void AbortEventListener ( string objectName )
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . AbortEventListener ( Task . getState ) ) ;
if ( handlers . Count = = 0 )
{
Debug . LogWarning ( $"BTC.AbortEventListener: no components under the name '{objectName}'" ) ;
Task . SetSucceeded ( ) ;
}
}
2024-09-24 17:33:08 +02:00
[Task]
public void ListenToEvent ( string objectName )
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
handlers . ForEach ( handler = > handler . ListenToEvent ( Task . getState ) ) ;
if ( handlers . Count = = 0 )
{
Debug . LogWarning ( $"BTC.ListenToEvent: no components under the name '{objectName}'" ) ;
2024-12-12 18:54:11 +01:00
Task . SetSucceeded ( ) ;
}
}
[Task]
2024-12-16 20:19:12 +01:00
public void StopSound ( string objectName )
2024-12-12 18:54:11 +01:00
{
List < ComponentHandler > handlers = GetHandlers ( objectName ) ;
2024-12-16 20:19:12 +01:00
handlers . ForEach ( handler = > handler . StopSound ( Task . getState ) ) ;
2024-12-12 18:54:11 +01:00
if ( handlers . Count = = 0 )
{
2024-12-16 20:19:12 +01:00
Debug . LogWarning ( $"BTC.StopSound: no components under the name '{objectName}'" ) ;
2024-12-12 18:54:11 +01:00
Task . SetSucceeded ( ) ;
}
}
2024-01-19 16:30:05 +01:00
# endregion
#region video & sound tasks
#if FMOD
[Task]
public void PlayVideoAndSound ( string videoName , string soundName ) {
NamedStudioEventEmitter sound = GetNamedObject < NamedStudioEventEmitter > ( soundName ) ;
NamedVideoPlayer player = GetNamedObject < NamedVideoPlayer > ( videoName ) ;
if ( ( player ! = null ) & & ( sound ! = null ) ) {
int val = - 1 ;
FMOD . RESULT res = sound . sound . EventInstance . getTimelinePosition ( out val ) ;
Task . log = "audio " + res . ToString ( ) + " " + val + " video playing=" + player . video . isPlaying + " isPrepared=" + player . video . isPrepared ;
// on start, play
if ( Task . isStarting ) {
Debug . Log ( "PlayVideoAndSound.isStarting : starting video='" + videoName + "' and sound='" + soundName + "'" ) ;
player . HideNow ( ) ;
player . FadeInStart ( ) ;
player . video . Play ( ) ;
sound . sound . Play ( ) ;
}
else {
// if stopped playing
if ( ! player . video . isPrepared ) {
// not even prepared
return ;
}
if ( ( ! player . video . isPlaying ) & & ( ! sound . sound . IsPlaying ( ) ) ) {
player . ShowNow ( ) ;
player . FadeOutStart ( ) ;
Task . SetSucceeded ( ) ;
}
}
if ( Input . GetKeyDown ( KeyCode . Backspace ) ) {
player . HideNow ( ) ;
player . video . Stop ( ) ;
sound . sound . Stop ( ) ;
Task . SetSucceeded ( ) ;
}
}
else {
Debug . LogError ( "PlayVideoAndSound: Play Error: " + roomId + " video='" + videoName + "' (" + player + ") sound='" + soundName + "' (" + sound + ")" ) ;
}
}
[Task]
public void AbortVideoAndSound ( string videoName , string soundName ) {
if ( Task . isStarting ) {
NamedVideoPlayer player = GetNamedObject < NamedVideoPlayer > ( videoName ) ;
if ( player ! = null ) {
player . FadeOutStart ( ) ;
player . video . Stop ( ) ;
}
NamedStudioEventEmitter sound = GetNamedObject < NamedStudioEventEmitter > ( soundName ) ;
if ( sound ! = null ) {
sound . sound . Stop ( ) ;
}
}
Task . SetSucceeded ( ) ;
}
# endif
# endregion
#region gameobject tasks
// This structure is used to store data for rotation tweening.
struct QuaternionData {
public Quaternion startQuaternion ;
}
[Task]
public void TrackerRotatedAtLeast ( string gameObjectName , float successRotation ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
QuaternionData rd ;
if ( Task . isStarting ) {
Debug . Log ( "TrackerRotatedAtLeast.isStarting : gameObject=" + ngo . name ) ;
rd . startQuaternion = ngo . transform . rotation ;
Task . data = rd ;
}
rd = ( QuaternionData ) Task . data ;
float angleOffset = Quaternion . Angle ( rd . startQuaternion , ngo . transform . rotation ) ;
Task . log = string . Format ( angleOffset + " " + rd . startQuaternion + " " + ngo . transform . rotation ) ;
if ( angleOffset > successRotation ) {
Task . SetSucceeded ( ) ;
}
}
}
}
[Task]
public void TrackerRotatedAtMax ( string gameObjectName , float successRotation ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
QuaternionData rd ;
if ( Task . isStarting ) {
Debug . Log ( "TrackerRotatedAtMax.isStarting : trackerId=" + ngo . name + " status " + Task . getState + " " ) ;
rd . startQuaternion = ngo . transform . rotation ;
Task . data = rd ;
}
rd = ( QuaternionData ) Task . data ;
float angleOffset = Quaternion . Angle ( rd . startQuaternion , ngo . transform . rotation ) ;
Task . log = string . Format ( angleOffset + " " + rd . startQuaternion + " " + ngo . transform . rotation ) ;
if ( angleOffset < successRotation ) {
Task . SetSucceeded ( ) ;
}
}
}
}
[Task]
public void TrackerRotatedToAngle ( string gameObjectName , float targetAngleFloat , float maxOffset ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
Quaternion targetAngle = Quaternion . Euler ( 0 , targetAngleFloat , 0 ) ;
float angleOffset = Quaternion . Angle ( targetAngle , ngo . transform . rotation ) ;
Task . log = string . Format ( angleOffset + " < " + maxOffset + " ? " + ngo . transform . rotation . eulerAngles + " " + targetAngle . eulerAngles ) ;
if ( angleOffset < maxOffset ) {
Task . SetSucceeded ( ) ;
}
}
}
}
struct FloatData {
public float startFloat ;
}
[Task]
public void TrackerMovedY ( string gameObjectName , float successMovement ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
//if ((trackerId >= 0) && (trackerId < GetRoomData(roomId).trackers.Count)) {
//TrackerDataApplier tda = GetRoomData(roomId).trackers[trackerId];
FloatData pd ;
if ( Task . isStarting ) {
Debug . Log ( "TrackerRotated.isStarting : gameObjectName=" + ngo . go . name ) ;
pd . startFloat = ngo . go . transform . position . y ;
Task . data = pd ;
}
pd = ( FloatData ) Task . data ;
float positionOffset = Mathf . Abs ( pd . startFloat - ngo . go . transform . position . y ) ;
Task . log = string . Format ( positionOffset + " " + pd . startFloat + " " + ngo . go . transform . position . y ) ;
if ( positionOffset > successMovement ) {
Task . SetSucceeded ( ) ;
}
}
}
}
struct DataFloat2 {
public float startTime ;
public float startY ;
}
[Task]
public void MoveObjectY ( string gameObjectName , float startY , float finalY , float timer ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
NodeState thisNodeState = Task . getState ;
switch ( thisNodeState ) {
case NodeState . FirstRun :
Task . data = new DataFloat2 ( ) { startTime = Time . time , startY = ngo . transform . localPosition . y } ;
goto case NodeState . Running ;
case NodeState . Running :
DataFloat2 data = ( DataFloat2 ) Task . data ;
float elapsed = Time . time - data . startTime ;
float newY = finalY ;
if ( timer > 0 ) {
// newY = finalY;
//} else {
float interpolation = Mathf . Pow ( elapsed / timer , 1f / 7f ) ;
newY = Mathf . Lerp ( startY , finalY , interpolation ) ;
}
ngo . transform . localPosition = new Vector3 ( ngo . transform . localPosition . x , newY , ngo . transform . localPosition . z ) ;
if ( elapsed > = timer ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
ngo . transform . localPosition = new Vector3 ( ngo . transform . localPosition . x , finalY , ngo . transform . localPosition . z ) ;
break ;
}
}
else {
Debug . LogError ( $"MoveObjectY {gameObjectName} not found" ) ;
Task . SetFailed ( ) ;
}
}
}
[Task]
public void SendGameObjectMessage ( string gameObjectName , string methodName ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
NodeState thisNodeState = Task . getState ;
switch ( thisNodeState ) {
case NodeState . FirstRun :
ngo . SendMessage ( methodName ) ;
goto case NodeState . Running ;
case NodeState . Running :
Task . SetSucceeded ( ) ;
break ;
case NodeState . Aborting :
break ;
}
}
else {
Debug . LogError ( $"SendGameObjectMessage {gameObjectName} {methodName}" ) ;
Task . SetFailed ( ) ;
}
}
}
# endregion
#region camera or player tracking
[Task]
public bool CameraNearPosition ( float x , float y , float z , float range ) {
Vector3 position = new Vector3 ( x , y , z ) ;
float positionOffset = ( Camera . main . transform . position - position ) . magnitude ;
Task . log = $"{positionOffset} {Camera.main.transform.position} {position}" ; // string.Format(positionOffset + " " + Camera.main.transform.position + " " + position);
if ( positionOffset < range ) {
Task . SetSucceeded ( ) ;
return true ;
}
return false ;
}
[Task]
public void CameraXZNearPosition ( float x , float z , float range ) {
Vector3 cameraPos = Camera . main . transform . position ;
Vector3 position = new Vector3 ( x , cameraPos . y , z ) ;
float positionOffset = ( cameraPos - position ) . magnitude ;
Task . log = $"{positionOffset} {cameraPos} {position}" ; // string.Format(positionOffset + " " + cameraPos + " " + position);
if ( positionOffset < range ) {
Task . SetSucceeded ( ) ;
}
}
[Task]
public void SetCameraRootPosition ( float x , float y , float z ) {
if ( Task . isStarting ) {
Camera . main . transform . root . position = new Vector3 ( x , y , z ) ;
}
Task . SetSucceeded ( ) ;
}
# endregion
#region MegapointCache
#if MEGAFIERS
[Task]
public void PlayMegaPointCache ( string string gameObjectName , float startTime , bool playing , float playRate ) {
NamedMegaPointCache nmpc = GetNamedObject < NamedMegaPointCache > ( gameObjectName ) ;
if ( nmpc ! = null ) {
if ( Task . isStarting ) {
nmpc . SetFrame ( startTime ) ;
nmpc . SetPlay ( playing ) ;
nmpc . SetPlayRate ( playRate ) ;
Task . SetSucceeded ( ) ;
}
}
}
/// <summary>
/// attack: animation time to ease in the animation
/// delay: animation time at full speed
/// release: animation time to ease out the animation
///
/// attack * 2 + delay + release * 2 = animation play rate
/// </summary>
public float gletscherFrame = 0 ;
[Task]
public void PlayMegaPointCacheTimeline ( string objectName , float start , float attack , float delay , float release , float duration ) {
NamedMegaPointCache nmpc = GetNamedObject < NamedMegaPointCache > ( objectName ) ;
if ( nmpc ! = null ) {
float overallTime = Mathf . Abs ( attack * 2 + delay + release * 2 ) ; // for example: 0.2 * 2 + 0.6 + 0.2 * 2 = 1.4, after 10 seconds of real time, the internal counter needs to have run 1.4 seconds
float timeScale = overallTime / duration ; // for example: 1.4 / 10 = 0.14
float internalCounter = 0 ; // between 0 and overallTime
float animationTime = start ; // final time written to animation
string state = "undefined" ;
// only for debugging
gletscherFrame = nmpc . GetFrame ( ) ;
switch ( Task . getState ) {
case NodeState . FirstRun : // equals isStarting
Task . data = Time . time ; // store starttime
nmpc . SetPlay ( false ) ;
nmpc . SetPlayRate ( 0 ) ;
Debug . Log ( "BTC.PlayMegaPointCacheTimeline: start " + start + " attack " + attack + " delay " + delay + " release " + release + " duration " + duration + " timeScale " + timeScale + " frame " + Time . frameCount ) ;
break ;
case NodeState . Running :
float startTime = ( float ) Task . data ; // for example 33
internalCounter = ( Time . time - startTime ) * timeScale ; // for example: (33-35) * 0.14 = 0.28
if ( internalCounter > = overallTime ) {
//Debug.Log("BTC.PlayMegaPointCacheTimeline.running: finished " + nmpc.GetFrame() + " " + internalCounter);
state = "finished" ;
animationTime + = overallTime ;
Task . SetSucceeded ( ) ;
//return;
}
// in release
else if ( internalCounter > = Mathf . Abs ( attack * 2 + delay ) ) { // for example: 0.28 > (0.2*2+0.6) = false
internalCounter - = Mathf . Abs ( attack * 2 + delay ) ;
float t = internalCounter / ( 2 * release ) ;
animationTime + = attack + delay + release * IntegralEasing . EaseOutCubic ( t ) ;
//Debug.Log("BTC.PlayMegaPointCacheTimeline: release " + animationTime + " i " + internalCounter + " t " + t);
state = "release" ;
}
// in delay
else if ( internalCounter > = Mathf . Abs ( attack * 2 ) ) { // for example: 0.28 > (0.2*2) = false
internalCounter - = Mathf . Abs ( attack * 2 ) ;
float t = internalCounter / delay ;
animationTime + = attack + delay * t ;
//Debug.Log("BTC.PlayMegaPointCacheTimeline: delay " + animationTime + " i " + internalCounter + " t " + t);
state = "delay" ;
}
// in attack
else { // for example: true
internalCounter = internalCounter ; // for example: 0.28 = 0.28
float t = internalCounter / ( 2 * attack ) ;
animationTime + = attack * IntegralEasing . EaseInCubic ( t ) ;
//Debug.Log("BTC.PlayMegaPointCacheTimeline: attack " + animationTime + " i " + internalCounter + " t " + t);
state = "attack" ;
}
break ;
case NodeState . Aborting :
//Debug.Log("BTC.PlayMegaPointCacheTimeline.stopping: " + nmpc.GetFrame() + " " + internalCounter);
internalCounter = overallTime ;
//Debug.Log("BTC.PlayMegaPointCacheTimeline: stop ");
state = "stop" ;
animationTime + = attack + delay + release ;
// prevent applying the time
return ;
break ;
}
//Task.log = "t " + animationTime + " i " + internalCounter + " s " + timeScale + " o " + overallTime;
float delta = ( animationTime - nmpc . GetFrame ( ) ) / timeScale ;
//Debug.Log("BTC.PlayMegaPointCacheTimeline: " + state + " " + animationTime + " delta " + delta + " i " + internalCounter);
nmpc . SetFrame ( animationTime ) ;
}
}
# endif
# endregion
2024-09-17 17:10:28 +02:00
#region Speech Intent Recognizer and Speech Synthesizer
2024-09-16 20:37:29 +02:00
private ViaggioAIManager _speechMng { get { return ViaggioAIManager . Instance ; } }
private RequestDataModel _requestDataModel = new RequestDataModel ( ) ;
private string _recognizedIntentID = "" ;
private bool _onIntentRecognitionSucceededEventTriggered = false ;
private bool _onUserSpeechInputStartedEventTriggered = false ;
private bool _onIntentRecognitionFailedEventTriggered = false ;
2024-09-17 17:10:28 +02:00
private bool _onSpeechOutputStartedEventTriggered = false ;
private bool _onSpeechOutputEndedEventTriggered = false ;
2024-09-23 17:11:21 +02:00
private bool _abortSpeechEventListener = false ;
2024-09-16 20:37:29 +02:00
2024-09-18 16:48:09 +02:00
void OnDisable ( )
2024-09-16 20:37:29 +02:00
{
2024-09-18 16:48:09 +02:00
UnsubscribeFromEvents ( ) ;
2024-09-17 17:10:28 +02:00
}
2024-09-18 16:48:09 +02:00
private void SubscribeToEvents ( )
2024-09-17 17:10:28 +02:00
{
2024-09-18 16:48:09 +02:00
if ( _speechMng ! = null )
{
// Speech Intent Recognizer Events
_speechMng . OnUserSpeechInputStartedEvent + = UserSpeechInputStartedEventHandler ;
_speechMng . OnIntentRecognitionSucceededEvent + = IntentRecognitionSucceededEventHandler ;
_speechMng . OnIntentRecognitionFailedEvent + = IntentRecognitionFailedEventHandler ;
// Speech Output Events
_speechMng . OnSpeechOutputStartedEvent + = SpeechOutputStartedEventHandler ;
_speechMng . OnSpeechOutputEndedEvent + = SpeechOutputEndedEventHandler ;
Debug . Log ( "SubscribeToEvents successfull." ) ;
}
}
private void UnsubscribeFromEvents ( )
{
if ( _speechMng ! = null )
{
_speechMng . OnIntentRecognitionSucceededEvent - = IntentRecognitionSucceededEventHandler ;
_speechMng . OnUserSpeechInputStartedEvent - = UserSpeechInputStartedEventHandler ;
_speechMng . OnIntentRecognitionFailedEvent - = IntentRecognitionFailedEventHandler ;
_speechMng . OnSpeechOutputStartedEvent - = SpeechOutputStartedEventHandler ;
_speechMng . OnSpeechOutputEndedEvent - = SpeechOutputEndedEventHandler ;
}
2024-09-16 20:37:29 +02:00
}
private void IntentRecognitionSucceededEventHandler ( object sender , string intentID )
{
_onIntentRecognitionSucceededEventTriggered = true ;
_recognizedIntentID = intentID ;
}
private void UserSpeechInputStartedEventHandler ( object sender , object e )
{
_onUserSpeechInputStartedEventTriggered = true ;
}
private void IntentRecognitionFailedEventHandler ( object sender , bool e )
{
_onIntentRecognitionFailedEventTriggered = true ;
}
2024-09-17 17:10:28 +02:00
private void SpeechOutputStartedEventHandler ( object sender , bool e )
{
_onSpeechOutputStartedEventTriggered = true ;
}
private void SpeechOutputEndedEventHandler ( object sender , bool e )
{
_onSpeechOutputEndedEventTriggered = true ;
}
2024-09-18 16:48:09 +02:00
[Task]
public async void InitializeSpeechManager ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
while ( _speechMng = = null )
{
await System . Threading . Tasks . Task . Delay ( 10 ) ;
}
SubscribeToEvents ( ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
2024-09-16 20:37:29 +02:00
[Task]
2024-11-12 20:26:38 +01:00
public void AddPossbileSpeechIntent ( string id )
2024-09-16 20:37:29 +02:00
{
2024-09-17 14:44:02 +02:00
if ( Task . getState = = NodeState . FirstRun )
2024-09-16 20:37:29 +02:00
{
2024-11-12 20:26:38 +01:00
_requestDataModel . PossibleIntents . Add ( id , SpeechData . intents [ id ] ) ;
2024-09-17 14:44:02 +02:00
foreach ( var r in _requestDataModel . PossibleIntents )
{
Debug . Log ( $"Possible Intent: {r.Key}, {r.Value}" ) ;
}
Task . SetSucceeded ( ) ;
return ;
2024-09-16 20:37:29 +02:00
}
}
[Task]
public void StartSpeechIntentRecognition ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
_onUserSpeechInputStartedEventTriggered = false ;
_speechMng . StartIntentRecognition ( _requestDataModel . PossibleIntents ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
2024-09-17 14:18:12 +02:00
public void UserStartedSpeechInput ( )
2024-09-16 20:37:29 +02:00
{
if ( Task . getState = = NodeState . FirstRun )
{
_onIntentRecognitionSucceededEventTriggered = false ;
_onIntentRecognitionFailedEventTriggered = false ;
}
2024-09-17 14:18:12 +02:00
if ( _onUserSpeechInputStartedEventTriggered )
{
Task . SetSucceeded ( ) ;
2024-09-23 17:11:21 +02:00
Debug . Log ( "UserStartedSpeechInput succeded." ) ;
return ;
}
if ( _abortSpeechEventListener )
{
Task . SetFailed ( ) ;
Debug . Log ( "UserStartedSpeechInput failed." ) ;
_abortSpeechEventListener = false ;
2024-09-17 14:18:12 +02:00
return ;
}
}
[Task]
public void SpeechIntentRecognized ( )
{
2024-09-16 20:37:29 +02:00
if ( _onIntentRecognitionSucceededEventTriggered )
{
Task . SetSucceeded ( ) ;
Debug . Log ( "SpeechIntentRecognized successfull" ) ;
return ;
}
if ( _onIntentRecognitionFailedEventTriggered )
{
Task . SetFailed ( ) ;
Debug . Log ( "SpeechIntentRecognized failed" ) ;
return ;
}
}
2024-09-17 14:18:12 +02:00
[Task]
public void CompareUserSpeechInputStarted ( bool value )
{
if ( Task . getState = = NodeState . FirstRun )
{
if ( _onUserSpeechInputStartedEventTriggered = = value )
{
Debug . Log ( $"CompareUserSpeechInputStarted with {value} = equal" ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( $"CompareUserSpeechInputStarted with {value} = not equal" ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
2024-09-16 20:37:29 +02:00
[Task]
public void CompareIntentID ( string intentID )
{
2024-09-17 17:10:28 +02:00
if ( Task . getState = = NodeState . FirstRun )
2024-09-16 20:37:29 +02:00
{
if ( _recognizedIntentID = = intentID )
{
Debug . Log ( $"CompareIntentID {_recognizedIntentID} with {intentID} = equal" ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( $"CompareIntentID {_recognizedIntentID} with {intentID} = not equal" ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
2024-09-23 17:11:21 +02:00
[Task]
public void AbortSpeechEventListener ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
_abortSpeechEventListener = true ;
Task . SetSucceeded ( ) ;
return ;
}
}
2024-09-16 20:37:29 +02:00
[Task]
public void ClearPossbileSpeechIntents ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
_requestDataModel . PossibleIntents . Clear ( ) ;
2024-09-17 14:44:02 +02:00
_recognizedIntentID = "" ;
2024-09-16 20:37:29 +02:00
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void StopSpeechIntentRecognition ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
_speechMng . StopIntentRecognition ( ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
2024-09-18 16:48:09 +02:00
2024-09-17 17:10:28 +02:00
[Task]
2024-09-18 16:48:09 +02:00
public void SetSpeechRecognitionLanguage ( string languageCode )
{
if ( Task . getState = = NodeState . FirstRun )
{
_speechMng . SetSpeechRecognitionLanguage ( languageCode ) ;
2024-11-12 20:26:38 +01:00
SpeechData . languageCode = languageCode ;
2024-09-18 16:48:09 +02:00
Debug . Log ( $"Set Speech Recognition Language to {languageCode}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
2024-11-12 20:26:38 +01:00
public void SetVoiceName ( string voiceName )
{
if ( Task . getState = = NodeState . FirstRun )
{
SpeechData . voiceName = voiceName ;
Debug . Log ( $"Set VoiceName to {voiceName}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void SynthesizeText ( string text )
2024-09-17 17:10:28 +02:00
{
if ( Task . getState = = NodeState . FirstRun )
{
_onSpeechOutputStartedEventTriggered = false ;
_onSpeechOutputEndedEventTriggered = false ;
2024-09-18 16:48:09 +02:00
2024-11-12 20:26:38 +01:00
_speechMng . SynthesizeText ( text , SpeechData . languageCode , SpeechData . voiceName ) ;
2024-09-17 17:10:28 +02:00
}
2024-09-16 20:37:29 +02:00
2024-09-17 17:10:28 +02:00
if ( _onSpeechOutputStartedEventTriggered )
{
Debug . Log ( "SynthesizeText: Speech Output started." ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
2024-09-17 14:44:02 +02:00
2024-09-17 17:10:28 +02:00
[Task]
public void SpeechOutputEnded ( )
{
if ( _onSpeechOutputEndedEventTriggered )
{
Debug . Log ( "SynthesizeText: Speech Output ended." ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
2024-09-17 14:44:02 +02:00
# endregion
2024-09-26 16:59:42 +02:00
#region Visited Stories Manager
[Task]
public void StoryAVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
if ( VisitedStories . StoryA )
{
Debug . Log ( "Story A was visited." ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( "Story A was not visited." ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
[Task]
public void StoryBVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
if ( VisitedStories . StoryB )
{
Debug . Log ( "Story B was visited." ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( "Story B was not visited." ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
[Task]
public void StoryCVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
if ( VisitedStories . StoryC )
{
Debug . Log ( "Story C was visited." ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( "Story C was not visited." ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
[Task]
public void SetStoryAVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
VisitedStories . StoryA = true ;
Debug . Log ( $"Set Visited Story A = {VisitedStories.StoryA}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void SetStoryBVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
VisitedStories . StoryB = true ;
Debug . Log ( $"Set Visited Story B = {VisitedStories.StoryB}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void SetStoryCVisited ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
VisitedStories . StoryC = true ;
Debug . Log ( $"Set Visited Story C = {VisitedStories.StoryC}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void IncrementRepetitionVisitedCounter ( )
{
if ( Task . getState = = NodeState . FirstRun )
{
VisitedStories . RepetitionCounter + + ;
Debug . Log ( $"Set Visited Repetition Counter = {VisitedStories.RepetitionCounter}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
}
[Task]
public void CompareRepetitionVisitedCounter ( int number )
{
if ( Task . getState = = NodeState . FirstRun )
{
if ( VisitedStories . RepetitionCounter = = number )
{
Debug . Log ( $"Visited Repetition Counter equals {number}" ) ;
Task . SetSucceeded ( ) ;
return ;
}
else
{
Debug . Log ( $"Visited Repetition Counter not equals {number}" ) ;
Task . SetFailed ( ) ;
return ;
}
}
}
# endregion
2024-01-19 16:30:05 +01:00
#region Oculus Input
2024-09-16 20:37:29 +02:00
#if OCULUSVR_AVAILABLE
2024-01-19 16:30:05 +01:00
[Task]
public void OVRInputGetDown ( string buttonName ) {
if ( System . Enum . TryParse ( buttonName , out OVRInput . Button button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
if ( OVRInput . GetDown ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"OVRInputGetDown: unknown button {buttonName}" ) ;
Task . SetError ( ) ;
}
}
[Task]
public void OVRInputGetUp ( string buttonName ) {
if ( System . Enum . TryParse ( buttonName , out OVRInput . Button button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
if ( OVRInput . GetUp ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"OVRInputGetUp: unknown button {buttonName}" ) ;
Task . SetError ( ) ;
}
}
[Task]
public void OVRInputGet ( string buttonName ) {
if ( System . Enum . TryParse ( buttonName , out OVRInput . Button button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
if ( OVRInput . Get ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
} else {
Task . SetFailed ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"OVRInputGet: unknown button {buttonName}" ) ;
Task . SetError ( ) ;
}
}
# endif
# endregion
#region keyboard input
[Task]
public void GetKeyDown ( string buttonName ) {
KeyCode button ;
if ( System . Enum . TryParse ( buttonName , out button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
// Debug.Log($"GetKey: checking {button}");
if ( UnityEngine . Input . GetKeyDown ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"GetKeyDown: unknown key {buttonName}" ) ;
Task . SetError ( ) ;
}
}
[Task]
public void GetKeyUp ( string buttonName ) {
KeyCode button ;
if ( System . Enum . TryParse ( buttonName , out button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
// Debug.Log($"GetKey: checking {button}");
if ( UnityEngine . Input . GetKeyUp ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"GetKeyUp: unknown key {buttonName}" ) ;
Task . SetError ( ) ;
}
}
[Task]
public void GetKey ( string buttonName ) {
KeyCode button ;
if ( System . Enum . TryParse ( buttonName , out button ) ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
// Debug.Log($"GetKey: checking {button}");
if ( UnityEngine . Input . GetKey ( button ) ) {
Task . SetSucceeded ( ) ;
return ;
} else {
Task . SetFailed ( ) ;
return ;
}
break ;
case NodeState . Aborting :
case NodeState . NotRunning :
break ;
}
} else {
Debug . LogError ( $"GetKey: unknown key {buttonName}" ) ;
Task . SetError ( ) ;
}
}
# endregion
#region SC
public Transform cameraRoot ;
//public Transform[] cameraRootPositions;
[Task]
void ReparentCameraToGameObject ( string gameObjectName ) {
foreach ( NamedGameObject ngo in GetHandlers ( gameObjectName ) ) {
// NamedGameObject ngo = GetNamedObject<NamedGameObject>(gameObjectName);
if ( ngo ! = null ) {
if ( Task . isStarting ) {
cameraRoot . transform . parent = ngo . transform ;
cameraRoot . localPosition = Vector3 . zero ;
Debug . Log ( $"BTC.ReparentCameraToGameObject: reparent camera to {ngo.name}" ) ;
}
Task . SetSucceeded ( ) ;
return ;
}
Task . SetFailed ( ) ;
}
}
[Task]
public void Wait ( float timer ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
Task . data = Time . time ;
break ;
case NodeState . Running :
float startTime = ( float ) Task . data ;
float elapsed = Time . time - startTime ;
Task . log = "" + timer ;
if ( elapsed > timer ) {
Task . SetSucceeded ( ) ;
return ;
}
break ;
case NodeState . Aborting :
break ;
}
//if (debug)
// Debug.Log("TestScript.Timer: " + timer + " " + thisNodeState);
}
[Task]
public void RestartBT ( ) {
switch ( Task . getState ) {
case NodeState . FirstRun :
case NodeState . Running :
GetComponent < TaskController > ( ) . Restart ( ) ;
// dont succeeed, wait for restart
break ;
case NodeState . Aborting :
break ;
}
}
# endregion
#region Blackboard
Dictionary < string , bool > boolValueDictionary = new Dictionary < string , bool > ( ) ;
[Task]
void ClearBool ( string key ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
Debug . Log ( $"ClearBool {key}" ) ;
boolValueDictionary . Remove ( key ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void SetBool ( string key ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
SetBool ( key , true ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void SetBool ( string key , bool value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
Debug . Log ( $"SetBool {key} to {value}" ) ;
boolValueDictionary [ key ] = value ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void CompareBool ( string key ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
CompareBool ( key , true ) ;
}
}
[Task]
void CompareBool ( string key , bool value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
if ( boolValueDictionary . ContainsKey ( key ) ) {
if ( boolValueDictionary [ key ] = = value ) {
Debug . Log ( $"CompareBool {key} with {value} = equal" ) ;
Task . SetSucceeded ( ) ;
return ;
}
else {
Debug . Log ( $"CompareBool {key} with {value} = not equal" ) ;
Task . SetFailed ( ) ;
return ;
}
} else {
Task . SetFailed ( ) ;
return ;
}
}
}
Dictionary < string , float > floatValueDictionary = new Dictionary < string , float > ( ) ;
[Task]
void ClearFloat ( string key ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
floatValueDictionary . Remove ( key ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void AddFloat ( string key , float value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
if ( ! floatValueDictionary . ContainsKey ( key ) ) {
floatValueDictionary [ key ] = 0 ;
}
floatValueDictionary [ key ] + = value ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void SetFloat ( string key , int value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
floatValueDictionary [ key ] = value ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void CompareFloatBigger ( string key , float compareValue ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
float value = 0 ;
if ( floatValueDictionary . ContainsKey ( key ) ) {
value = floatValueDictionary [ key ] ;
}
else {
Debug . LogError ( $"FloatBigger: no value defined for {key}" ) ;
}
if ( value > compareValue ) {
Task . SetSucceeded ( ) ;
}
else {
Task . SetFailed ( ) ;
}
}
}
Dictionary < string , int > intDictionary = new Dictionary < string , int > ( ) ;
[Task]
void ClearInt ( string key ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
intDictionary . Remove ( key ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void AddInt ( string key , int value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
if ( ! intDictionary . ContainsKey ( key ) ) {
intDictionary [ key ] = 0 ;
}
intDictionary [ key ] + = value ;
Debug . Log ( $"IndAdd {key} {intDictionary[key]}" ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void SetInt ( string key , int value ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
intDictionary [ key ] = value ;
Debug . Log ( "IntSet " + key + " " + intDictionary [ key ] ) ;
Task . SetSucceeded ( ) ;
}
}
[Task]
void CompareIntBigger ( string key , float compareValue ) {
if ( ( Task . getState = = NodeState . FirstRun ) | | ( Task . getState = = NodeState . Running ) ) {
int value = 0 ;
if ( intDictionary . ContainsKey ( key ) ) {
value = intDictionary [ key ] ;
}
else {
Debug . LogError ( "CounterBigger: no value defined for " + key ) ;
}
Debug . Log ( "IntBigger " + key + " " + value + " > " + compareValue ) ;
if ( value > compareValue ) {
Task . SetSucceeded ( ) ;
}
else {
Task . SetFailed ( ) ;
}
}
}
[Task]
void LogMessage ( string logMessage ) {
Debug . Log ( logMessage ) ;
Task . SetSucceeded ( ) ;
}
# endregion
#region Succeed and fail
[Task]
void Fail ( ) {
Task . SetFailed ( ) ;
}
[Task]
void Succeed ( ) {
Task . SetSucceeded ( ) ;
}
# endregion
}