Created
December 21, 2018 07:31
-
-
Save unitycoder/e491376dc5203dd579213b871f144a09 to your computer and use it in GitHub Desktop.
small script that allows you to start the PlayMode from a specific point in the scene simply by right-clicking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://old.reddit.com/r/Unity3D/comments/a82vcm/stop_wasting_time_while_testing_and_play_from/ | |
using UnityEngine; | |
using UnityEditor; | |
[CreateAssetMenu(fileName = "PlayFromHereData")] | |
public class PlayFromHereInitData : ScriptableObject | |
{ | |
public GameObject[] m_arOriginPrefabs; | |
public GameObject[] m_arPositionPrefabs; | |
public LayerMask m_layerMask = ~0; | |
public void SpawnMissingObjects(Vector3 _v3Position) | |
{ | |
for (int i = 0; i < m_arOriginPrefabs.Length; i++) | |
{ | |
if(m_arOriginPrefabs[i] != null) | |
{ | |
if (GameObject.Find(m_arOriginPrefabs[i].name) == null) | |
{ | |
Instantiate(m_arOriginPrefabs[i]); | |
} | |
} | |
} | |
for (int i = 0; i < m_arPositionPrefabs.Length; i++) | |
{ | |
if (m_arPositionPrefabs[i] != null) | |
{ | |
GameObject goInScene = GameObject.Find(m_arPositionPrefabs[i].name); | |
if (goInScene == null) | |
{ | |
Instantiate(m_arPositionPrefabs[i], _v3Position, Quaternion.identity); | |
} | |
else | |
{ | |
goInScene.transform.position = _v3Position; | |
} | |
} | |
} | |
} | |
} | |
[InitializeOnLoad] | |
public class PlayFromHere | |
{ | |
private const string c_strPlayFromHereObjectPath = "Assets/ScriptableObjects/Editor/PlayFromHereData.asset"; | |
private static double s_startClickTime; | |
private static GameObject s_goHackObject; | |
private static Vector3 s_v3Position; | |
private static PlayFromHereInitData s_initDataObject; | |
private const string c_strHackName = "Play From Here Hack Object"; | |
static PlayFromHere() | |
{ | |
SceneView.onSceneGUIDelegate -= OnSceneGUI; | |
SceneView.onSceneGUIDelegate += OnSceneGUI; | |
s_goHackObject = GameObject.Find(c_strHackName); | |
if (s_goHackObject != null) | |
{ | |
EditorApplication.playModeStateChanged -= OnPlayModeChanged; | |
EditorApplication.playModeStateChanged += OnPlayModeChanged; | |
} | |
} | |
private static void OnPlayModeChanged(PlayModeStateChange _eStateChange) | |
{ | |
switch (_eStateChange) | |
{ | |
case PlayModeStateChange.EnteredEditMode: | |
//If we are coming back from PlayMode which was started via PlayFromHere, we delete the helper game object | |
if (s_goHackObject != null) | |
{ | |
GameObject.DestroyImmediate(s_goHackObject); | |
} | |
break; | |
case PlayModeStateChange.ExitingEditMode: | |
break; | |
case PlayModeStateChange.EnteredPlayMode: | |
//If we entered PlayMode and a Helper Object exists, we should use its position to initialize the PlayFromHere-Objects | |
if (s_goHackObject != null) | |
{ | |
RefreshPlayFromHereDataObject(); | |
if (s_initDataObject != null) | |
{ | |
s_initDataObject.SpawnMissingObjects(s_goHackObject.transform.position); | |
} | |
} | |
break; | |
case PlayModeStateChange.ExitingPlayMode: | |
break; | |
default: | |
break; | |
} | |
} | |
private static void RefreshPlayFromHereDataObject() | |
{ | |
if (s_initDataObject == null) | |
{ | |
s_initDataObject = AssetDatabase.LoadAssetAtPath<PlayFromHereInitData>(c_strPlayFromHereObjectPath); | |
} | |
} | |
private static void OnSceneGUI(SceneView sceneView) | |
{ | |
//Check for right mouse button | |
if (Event.current.isMouse && Event.current.button == 1 && !EditorApplication.isPlaying) | |
{ | |
if (Event.current.type == EventType.MouseDown) | |
{ | |
//Save time of mouse down Event to later check for click duration | |
s_startClickTime = EditorApplication.timeSinceStartup; | |
} | |
else if (Event.current.type == EventType.MouseUp) | |
{ | |
//Check time since mouse down and open menu for short click | |
if (EditorApplication.timeSinceStartup - s_startClickTime < .25f) | |
{ | |
Camera camera = sceneView.camera; | |
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); | |
RaycastHit rayhit; | |
//Default layermask is "Everything" | |
LayerMask layerMask = ~0; | |
//Try to get layermask from DataObject | |
RefreshPlayFromHereDataObject(); | |
if (s_initDataObject != null) | |
{ | |
layerMask = s_initDataObject.m_layerMask; | |
} | |
//Get world position for click | |
if (Physics.Raycast(ray, out rayhit, float.MaxValue, layerMask, QueryTriggerInteraction.Ignore)) | |
{ | |
s_v3Position = rayhit.point + Vector3.up * .1f; | |
//Show confirmation window | |
GenericMenu menu = new GenericMenu(); | |
menu.AddItem(new GUIContent("Play From Here"), false, OnConfirmPlayFromHere); | |
menu.ShowAsContext(); | |
Event.current.Use(); | |
} | |
} | |
} | |
} | |
} | |
private static void OnConfirmPlayFromHere() | |
{ | |
//Start PlayMode | |
EditorApplication.isPlaying = true; | |
//Unity reinitializes all scripts when starting PlayMode so we can't save any variables regularly | |
//Create a GameObject with "DontSave"-Flag to "save" Position for start of PlayMode | |
GameObject goPlayFromHere = new GameObject(c_strHackName); | |
goPlayFromHere.transform.position = s_v3Position; | |
goPlayFromHere.hideFlags = HideFlags.DontSave; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment