- Home /
Event for Unity Editor "Pause" and "Play/Stop" events?
I am using my own custom external C# DLL for music, music loading, etc. Because I'm using an external DLL, I need to be able to inform my external threads when to start/stop. I can do this fine from within my game if it's running start to finish with no interruption, but when I'm actually editing and debugging my game, I need to be able to know when the "Pause" or "Play/Stop" buttons have been hit inside the Unity IDE. This will allow me to clean up my external threads so I don't have a bunch of mystery threads running when the program isn't actually running inside the IDE.
Is there any event to handle to do this?
Answer by iwaldrop · Apr 30, 2013 at 05:32 PM
I like to create a delegate method and assign it to handle play-mode changes, like so:
EditorApplication.playmodeStateChanged = HandleOnPlayModeChanged;
void HandleOnPlayModeChanged()
{
// This method is run whenever the playmode state is changed.
if (EditorApplication.isPaused)
{
// do stuff when the editor is paused.
}
}
Flags that you can check:
isPlaying
isPlayingOrWillChangePlaymode
isPaused
isCompiling
isUpdating
This is exactly what I was looking for! Thank you :D
For reference, here's what I had to wind up doing to detect "stopped" state (since there is not a "isStopped" property):
void HandleOnPlay$$anonymous$$odeChanged()
{
// This method is run whenever the playmode state is changed.
if (EditorApplication.isPaused)
{
if (!wasPaused)
{
Pause();
wasPaused = true;
}
else //.isStopped equivalent
{
Stop ();
initLoadComplete = false;
}
}
else if (initLoadComplete && (EditorApplication.isPlaying || EditorApplication.isPlayingOrWillChangePlaymode))
{
if (wasPaused)
{
wasPaused = false;
Play ();
}
else //.isStopped equivalent
{
Stop ();
initLoadComplete = false;
}
}
}
Edit: Forgot a condition for Paused -> Stop. Above code should work properly now.
Answer by stephenlautier · Feb 21, 2014 at 02:04 AM
Unity API for playmodeChanged state is a bit arghh..
I created the following to make it easier, usage would be something like this:
[InitializeOnLoad]
public class SingleEntryPoint
{
static SingleEntryPoint()
{
Debug.Log("SingleEntryPoint. Up and running");
EditorPlayMode.PlayModeChanged += OnPlayModeChanged;
}
private static void OnPlayModeChanged(PlayModeState currentMode, PlayModeState changedMode)
{
// DO your stuff here...
}
}
Playmode API source below.
public enum PlayModeState
{
Stopped,
Playing,
Paused
}
[InitializeOnLoad]
public class EditorPlayMode
{
private static PlayModeState _currentState = PlayModeState.Stopped;
static EditorPlayMode()
{
EditorApplication.playmodeStateChanged = OnUnityPlayModeChanged;
}
public static event Action<PlayModeState, PlayModeState> PlayModeChanged;
public static void Play()
{
EditorApplication.isPlaying = true;
}
public static void Pause()
{
EditorApplication.isPaused = true;
}
public static void Stop()
{
EditorApplication.isPlaying = false;
}
private static void OnPlayModeChanged(PlayModeState currentState, PlayModeState changedState)
{
if (PlayModeChanged != null)
PlayModeChanged(currentState, changedState);
}
private static void OnUnityPlayModeChanged()
{
var changedState = PlayModeState.Stopped;
switch (_currentState)
{
case PlayModeState.Stopped:
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
changedState = PlayModeState.Playing;
}
break;
case PlayModeState.Playing:
if (EditorApplication.isPaused)
{
changedState = PlayModeState.Paused;
}
else
{
changedState = PlayModeState.Stopped;
}
break;
case PlayModeState.Paused:
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
changedState = PlayModeState.Playing;
}
else
{
changedState = PlayModeState.Stopped;
}
break;
default:
throw new ArgumentOutOfRangeException();
}
// Fire PlayModeChanged event.
OnPlayModeChanged(_currentState, changedState);
// Set current state.
_currentState = changedState;
}
}
hope it helps, and feel free to use. :)
Thanks for sharing. I tested. However events are fired twice when exiting from play mode with changeState = stopped. I made a few modifications to your code, and now it works fine.
using UnityEditor;
using System;
public enum Play$$anonymous$$odeState
{
Stopped,
Playing,
Paused
}
[InitializeOnLoad]
public class EditorPlay$$anonymous$$ode
{
private static Play$$anonymous$$odeState _currentState = Play$$anonymous$$odeState.Stopped;
static EditorPlay$$anonymous$$ode()
{
EditorApplication.playmodeStateChanged = OnUnityPlay$$anonymous$$odeChanged;
if (EditorApplication.isPaused)
_currentState = Play$$anonymous$$odeState.Paused;
}
public static event Action<Play$$anonymous$$odeState, Play$$anonymous$$odeState> Play$$anonymous$$odeChanged;
public static void Play()
{
EditorApplication.isPlaying = true;
}
public static void Pause()
{
EditorApplication.isPaused = true;
}
public static void Stop()
{
EditorApplication.isPlaying = false;
}
private static void OnPlay$$anonymous$$odeChanged(Play$$anonymous$$odeState currentState, Play$$anonymous$$odeState changedState)
{
if (Play$$anonymous$$odeChanged != null)
Play$$anonymous$$odeChanged(currentState, changedState);
}
private static void OnUnityPlay$$anonymous$$odeChanged()
{
var changedState = Play$$anonymous$$odeState.Stopped;
switch (_currentState)
{
case Play$$anonymous$$odeState.Stopped:
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
changedState = Play$$anonymous$$odeState.Playing;
}
else if (EditorApplication.isPaused)
{
changedState = Play$$anonymous$$odeState.Paused;
}
break;
case Play$$anonymous$$odeState.Playing:
if (EditorApplication.isPaused)
{
changedState = Play$$anonymous$$odeState.Paused;
}
else if (EditorApplication.isPlaying)
{
changedState = Play$$anonymous$$odeState.Playing;
}
else
{
changedState = Play$$anonymous$$odeState.Stopped;
}
break;
case Play$$anonymous$$odeState.Paused:
if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPaused)
{
changedState = Play$$anonymous$$odeState.Playing;
}
else if (EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPaused)
{
changedState = Play$$anonymous$$odeState.Paused;
}
break;
default:
throw new ArgumentOutOfRangeException();
}
// Fire Play$$anonymous$$odeChanged event.
if (_currentState!=changedState)
OnPlay$$anonymous$$odeChanged(_currentState, changedState);
// Set current state.
_currentState = changedState;
}
}
Simplified further, add support for AboutToStop event, so it's easier to hook up before the unity editor quit runtime. https://gist.github.com/paraself/0d75962a2c509759a6c9
Answer by the_9an · Jun 23, 2021 at 01:57 PM
With Pause Event, You must use EditorApplication.pauseStateChanged
Answer by Proliecan · Jun 23, 2021 at 09:19 AM
This should work just fine:
private void OnApplicationPause(bool pause)
{
}
Your answer
Follow this Question
Related Questions
Unity UI/Events - how to do something for as long as UI button is pressed 2 Answers
Unsubscribe events in OnDisable causes NullReferenceException 2 Answers
Correct way to send an event to a specific enemy 0 Answers
How do I pause/stop an audio clip that I choose, on a certain condition? 2 Answers
Coroutines pauses when not focused on the game page. 1 Answer