315 lines
12 KiB
C#
315 lines
12 KiB
C#
using UnityEngine;
|
|
#if MULTIPLAYER_ENABLED
|
|
using DarkTonic.MasterAudio.Multiplayer;
|
|
#endif
|
|
|
|
/*! \cond PRIVATE */
|
|
// ReSharper disable once CheckNamespace
|
|
namespace DarkTonic.MasterAudio {
|
|
// ReSharper disable once CheckNamespace
|
|
public class MechanimStateCustomEvents : StateMachineBehaviour {
|
|
[Tooltip("Select for event to re-fire each time animation loops without exiting state")]
|
|
[Header("Retrigger Events Each Time Anim Loops w/o Exiting State")]
|
|
public bool RetriggerWhenStateLoops = false;
|
|
|
|
#if MULTIPLAYER_ENABLED
|
|
[Header("Select For Events To Be Received By All Connected Players")]
|
|
public bool MultiplayerBroadcast = false;
|
|
#endif
|
|
|
|
[Tooltip("Fire A Custom Event When State Is Entered")]
|
|
[Header("Enter Custom Event")]
|
|
public bool fireEnterEvent = false;
|
|
[MasterCustomEvent]
|
|
public string enterCustomEvent = MasterAudio.NoGroupName;
|
|
|
|
[Tooltip("Fire a Custom Event when state is Exited")]
|
|
[Header("Exit Custom Event")]
|
|
public bool fireExitEvent = false;
|
|
[MasterCustomEvent]
|
|
public string exitCustomEvent = MasterAudio.NoGroupName;
|
|
|
|
[Tooltip("Fire a Custom Event timed to the animation state's normalized time. " +
|
|
"Normalized time is simply the length in time of the animation. " +
|
|
"Time is represented as a float from 0f - 1f. 0f is the beginning, .5f is the middle, 1f is the end...etc.etc. " +
|
|
"Select a Start time from 0 - 1.")]
|
|
[Header("Fire Custom EventTimed to Animation")]
|
|
public bool fireAnimTimeEvent = false; //Fire a Custom Event at a speccific time in your animation
|
|
|
|
[Tooltip("This value will be compared to the normalizedTime of the animation you are playing. NormalizedTime is represented as a float so 0 is the beginning, 1 is the end and .5f would be the middle etc.")]
|
|
[Range(0f, 1f)]
|
|
public float whenToFireEvent; //Based upon normalizedTime
|
|
[MasterCustomEvent]
|
|
public string timedCustomEvent = MasterAudio.NoGroupName;
|
|
|
|
[Tooltip("Fire a Custom Event with timed to the animation. This allows you to " +
|
|
"time your Custom Events to the actions in you animation. Select the number of Custom Events to be fired, up to 4. " +
|
|
"Then set the time you want each Custom Event to fire with each subsequent time greater than the previous time.")]
|
|
|
|
[Header("Fire Multiple Custom Events Timed to Anim")]
|
|
public bool fireMultiAnimTimeEvent = false;
|
|
|
|
[Range(0, 4)]
|
|
public int numOfMultiEventsToFire;
|
|
[Tooltip("This value will be compared to the normalizedTime of the animation you are playing. NormalizedTime is represented as a float so 0 is the beginning, 1 is the end and .5f would be the middle etc.")]
|
|
[Range(0f, 1f)]
|
|
public float whenToFireMultiEvent1; //Based upon normalizedTime
|
|
[Tooltip("This value will be compared to the normalizedTime of the animation you are playing. NormalizedTime is represented as a float so 0 is the beginning, 1 is the end and .5f would be the middle etc.")]
|
|
[Range(0f, 1f)]
|
|
public float whenToFireMultiEvent2; //Based upon normalizedTime
|
|
[Tooltip("This value will be compared to the normalizedTime of the animation you are playing. NormalizedTime is represented as a float so 0 is the beginning, 1 is the end and .5f would be the middle etc.")]
|
|
[Range(0f, 1f)]
|
|
public float whenToFireMultiEvent3; //Based upon normalizedTime
|
|
[Tooltip("This value will be compared to the normalizedTime of the animation you are playing. NormalizedTime is represented as a float so 0 is the beginning, 1 is the end and .5f would be the middle etc.")]
|
|
[Range(0f, 1f)]
|
|
public float whenToFireMultiEvent4; //Based upon normalizedTime
|
|
[MasterCustomEvent]
|
|
public string MultiTimedEvent = MasterAudio.NoGroupName;
|
|
|
|
private bool _playMultiEvent1 = true;
|
|
private bool _playMultiEvent2 = true;
|
|
private bool _playMultiEvent3 = true;
|
|
private bool _playMultiEvent4 = true;
|
|
private bool _fireTimedEvent = true;
|
|
private Transform _actorTrans;
|
|
private int _lastRepetition = -1;
|
|
|
|
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
|
|
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
|
|
_lastRepetition = 0;
|
|
|
|
_actorTrans = ActorTrans(animator);
|
|
|
|
if (!fireEnterEvent) {
|
|
return;
|
|
}
|
|
|
|
if (enterCustomEvent == MasterAudio.NoGroupName || string.IsNullOrEmpty(enterCustomEvent)) {
|
|
return;
|
|
}
|
|
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(enterCustomEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(enterCustomEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(enterCustomEvent, _actorTrans);
|
|
#endif
|
|
}
|
|
|
|
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
|
|
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
|
|
var animRepetition = (int)stateInfo.normalizedTime;
|
|
var animTime = stateInfo.normalizedTime - animRepetition;
|
|
|
|
if (!fireAnimTimeEvent) {
|
|
goto multievent;
|
|
}
|
|
|
|
#region Timed to Anim
|
|
if (!_fireTimedEvent && RetriggerWhenStateLoops) {
|
|
// change back to true if "re-trigger" checked and anim has looped.
|
|
|
|
if (_lastRepetition >= 0 && animRepetition > _lastRepetition) {
|
|
_fireTimedEvent = true;
|
|
}
|
|
}
|
|
|
|
if (_fireTimedEvent) {
|
|
if (animTime > whenToFireEvent) {
|
|
_fireTimedEvent = false;
|
|
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(timedCustomEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(timedCustomEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(timedCustomEvent, _actorTrans);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
multievent:
|
|
|
|
if (!fireMultiAnimTimeEvent) {
|
|
goto afterMulti;
|
|
}
|
|
|
|
#region Fire Multiple Events Timed To Anim
|
|
|
|
if (RetriggerWhenStateLoops) {
|
|
if (!_playMultiEvent1) {
|
|
// change back to true if "re-trigger" checked and anim has looped.
|
|
if (_lastRepetition >= 0 && animRepetition > _lastRepetition) {
|
|
_playMultiEvent1 = true;
|
|
}
|
|
}
|
|
if (!_playMultiEvent2) {
|
|
// change back to true if "re-trigger" checked and anim has looped.
|
|
if (_lastRepetition >= 0 && animRepetition > _lastRepetition) {
|
|
_playMultiEvent2 = true;
|
|
}
|
|
}
|
|
if (!_playMultiEvent3) {
|
|
// change back to true if "re-trigger" checked and anim has looped.
|
|
if (_lastRepetition >= 0 && animRepetition > _lastRepetition) {
|
|
_playMultiEvent3 = true;
|
|
}
|
|
}
|
|
if (!_playMultiEvent4) {
|
|
// change back to true if "re-trigger" checked and anim has looped.
|
|
if (_lastRepetition >= 0 && animRepetition > _lastRepetition) {
|
|
_playMultiEvent4 = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!_playMultiEvent1) {
|
|
goto decideMulti2;
|
|
}
|
|
if (animTime < whenToFireMultiEvent1 || numOfMultiEventsToFire < 1) {
|
|
goto decideMulti2;
|
|
}
|
|
|
|
_playMultiEvent1 = false;
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(MultiTimedEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
#endif
|
|
|
|
decideMulti2:
|
|
|
|
if (!_playMultiEvent2) {
|
|
goto decideMulti3;
|
|
}
|
|
|
|
if (animTime < whenToFireMultiEvent2 || numOfMultiEventsToFire < 2) {
|
|
goto decideMulti3;
|
|
}
|
|
|
|
_playMultiEvent2 = false;
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(MultiTimedEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
#endif
|
|
|
|
decideMulti3:
|
|
|
|
if (!_playMultiEvent3) {
|
|
goto decideMulti4;
|
|
}
|
|
|
|
if (animTime < whenToFireMultiEvent3 || numOfMultiEventsToFire < 3) {
|
|
goto decideMulti4;
|
|
}
|
|
|
|
_playMultiEvent3 = false;
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(MultiTimedEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
#endif
|
|
|
|
decideMulti4:
|
|
|
|
if (!_playMultiEvent4) {
|
|
goto afterMulti;
|
|
}
|
|
|
|
if (animTime < whenToFireMultiEvent4 || numOfMultiEventsToFire < 4) {
|
|
goto afterMulti;
|
|
}
|
|
|
|
_playMultiEvent4 = false;
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(MultiTimedEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(MultiTimedEvent, _actorTrans);
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
afterMulti:
|
|
|
|
_lastRepetition = animRepetition;
|
|
}
|
|
|
|
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
|
|
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
|
|
if (fireExitEvent && exitCustomEvent != MasterAudio.NoGroupName && !string.IsNullOrEmpty(exitCustomEvent)) {
|
|
#if MULTIPLAYER_ENABLED
|
|
if (CanTransmitToOtherPlayers) {
|
|
MasterAudioMultiplayerAdapter.FireCustomEvent(exitCustomEvent, _actorTrans, true);
|
|
} else {
|
|
MasterAudio.FireCustomEvent(exitCustomEvent, _actorTrans);
|
|
}
|
|
#else
|
|
MasterAudio.FireCustomEvent(exitCustomEvent, _actorTrans);
|
|
#endif
|
|
}
|
|
|
|
if (fireMultiAnimTimeEvent) {
|
|
_playMultiEvent1 = true;
|
|
_playMultiEvent2 = true;
|
|
_playMultiEvent3 = true;
|
|
_playMultiEvent4 = true;
|
|
}
|
|
|
|
if (fireAnimTimeEvent) {
|
|
_fireTimedEvent = true;
|
|
}
|
|
}
|
|
|
|
// OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
|
|
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
|
|
//
|
|
//}
|
|
|
|
// OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
|
|
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
|
|
//
|
|
//}
|
|
|
|
private Transform ActorTrans(Animator anim) {
|
|
if (_actorTrans != null) {
|
|
return _actorTrans;
|
|
}
|
|
|
|
_actorTrans = anim.transform;
|
|
|
|
return _actorTrans;
|
|
}
|
|
|
|
#if MULTIPLAYER_ENABLED
|
|
private bool CanTransmitToOtherPlayers {
|
|
get { return MultiplayerBroadcast && MasterAudioMultiplayerAdapter.CanSendRPCs; }
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
/*! \endcond */
|