I do this as well… minus the destroy. I mean a dummy/empty component out there doesn’t really cost at all that much. So I don’t really waste my time destroying it anyhow.
A place I use this is something like this:
using UnityEngine;
using System.Collections;
using System.Linq;
using com.spacepuppy;
using com.spacepuppy.Collections;
using com.spacepuppy.Utils;
using com.mansion.Entities.Weapons;
using com.mansion.Messages;
namespace com.mansion.DebugScripts
{
#if (UNITY_EDITOR || DEVELOPMENT_BUILD)
public class DebugStartup : SPComponent, IGameStateChangedGlobalHandler
#else
public class DebugStartup : SPComponent
#endif
{
#if UNITY_EDITOR
[SerializeField]
private EpisodeSettings _episodeSettings;
[SerializeField]
[Tooltip("Set with scene name to load if death occurs before any checkpoint occurs. Otherwise no reload occurs.")]
private string _debugCheckpointReloadScene;
protected override void Awake()
{
base.Awake();
if (!Game.Initialized)
{
Debug.Log("DEBUG INITIALIZING GAME");
//Cursor.visible = false;
Game.Init((g) =>
{
if (_episodeSettings != null) g.SetEpisodeSettings(_episodeSettings);
});
_dispatchStartMessage = true;
if (_episodeSettings != null && _episodeSettings.ScenarioType != null)
Game.StartScenario(_episodeSettings.ScenarioType).StartGame(new SaveGameToken()
{
Data = null,
Checkpoint = new CheckpointState(string.IsNullOrEmpty(_debugCheckpointReloadScene) ? Constants.DEBUG_STARTUP_CHECKPOINT_SCENE : _debugCheckpointReloadScene)
});
}
}
#endif
#if (UNITY_EDITOR || DEVELOPMENT_BUILD)
private bool _dispatchStartMessage;
private bool _showDebugMenu;
private Texture2D _background;
protected override void Start()
{
base.Start();
_background = new Texture2D(1, 1);
_background.SetPixels(new Color[] { Color.gray });
Messaging.RegisterGlobal<IGameStateChangedGlobalHandler>(this);
if(_dispatchStartMessage)
{
Messaging.FindAndBroadcast<IDebugStartMessageHandler>((o) => o.OnDebugStart());
}
}
protected override void OnDestroy()
{
base.OnDestroy();
Messaging.UnregisterGlobal<IGameStateChangedGlobalHandler>(this);
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.BackQuote))
{
const string TOKEN_DEEBUGPAUSE = "*DebugMenuPause*";
_showDebugMenu = !_showDebugMenu;
if (_showDebugMenu)
Game.Scenario.GameStateStack.Push(GameState.Paused, TOKEN_DEEBUGPAUSE);
else
Game.Scenario.GameStateStack.Pop(TOKEN_DEEBUGPAUSE);
}
}
private void OnGUI()
{
if (!_showDebugMenu) return;
var style = new GUIStyle(GUI.skin.box);
style.normal.background = _background;
GUI.Box(new Rect(10f, 10f, 500f, 300f), "DEBUG MENU", style);
GUILayout.BeginArea(new Rect(15f, 60f, 490f, 245f));
//validate player exists
var playerEntity = IEntity.Pool.Find<IEntity>((e) => e.Type == IEntity.EntityType.Player);
if (playerEntity == null)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label("No player was located.");
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
goto Finish;
}
//infinite ammo
var ammo = playerEntity.FindComponent<AmmoPouch>();
if(ammo != null)
{
foreach(var e in System.Enum.GetValues(typeof(AmmoType)).Cast<AmmoType>())
{
GUILayout.BeginHorizontal();
var oldcnt = ammo.GetAmmoCount(e);
var cnt = DiscreteFloatField(e.ToString() + " Ammo Count: ", oldcnt);
if(oldcnt != cnt)
ammo.SetAmmoCount(e, cnt);
bool oldInfAmmo = float.IsPositiveInfinity(cnt);
bool infAmmo = GUILayout.Toggle(oldInfAmmo, " Infinite Ammo");
if (oldInfAmmo != infAmmo)
{
ammo.SetAmmoCount(e, infAmmo ? float.PositiveInfinity : 10f);
}
GUILayout.EndHorizontal();
}
}
//Health - God Mode
if(playerEntity.HealthMeter != null)
{
playerEntity.HealthMeter.MaxHealth = FloatField("Max Health", playerEntity.HealthMeter.MaxHealth);
playerEntity.HealthMeter.Health = FloatField("Health", playerEntity.HealthMeter.Health);
bool oldGodMode = float.IsPositiveInfinity(playerEntity.HealthMeter.Health);
bool godMode = GUILayout.Toggle(oldGodMode, " God Mode");
if(godMode != oldGodMode)
{
if(godMode)
{
playerEntity.HealthMeter.MaxHealth = float.PositiveInfinity;
playerEntity.HealthMeter.Health = float.PositiveInfinity;
}
else
{
playerEntity.HealthMeter.MaxHealth = 100f;
playerEntity.HealthMeter.Health = 100f;
}
}
}
//1-btn grapple release
/*
var grapple = playerEntity.FindComponent<com.mansion.Entities.Actors.Player.PlayerGrappledState>();
if(grapple != null)
{
GUILayout.BeginHorizontal();
GUILayout.Label("Release Odds: " + grapple.GrappleReleaseOdds.ToString("P"));
grapple.GrappleReleaseOdds = Mathf.Clamp01(GUILayout.HorizontalSlider(grapple.GrappleReleaseOdds, 0f, 1f));
GUILayout.EndHorizontal();
}
*/
var actionMotor = playerEntity.FindComponent<com.mansion.Entities.Actors.Player.PlayerActionMotor>();
if(actionMotor != null && actionMotor.DefaultMovementSettings != null)
{
GUILayout.BeginHorizontal();
GUILayout.Label("Release Odds: " + actionMotor.DefaultMovementSettings.GrappleReleaseOdds.ToString("P"));
actionMotor.DefaultMovementSettings.GrappleReleaseOdds = Mathf.Clamp01(GUILayout.HorizontalSlider(actionMotor.DefaultMovementSettings.GrappleReleaseOdds, 0f, 1f));
GUILayout.EndHorizontal();
}
Finish:
GUILayout.EndArea();
}
private static float DiscreteFloatField(string label, float value)
{
GUILayout.BeginHorizontal();
GUILayout.Label(label);
string val = GUILayout.TextField(value.ToString());
//val = System.Text.RegularExpressions.Regex.Replace(val, @"^[0-9]", "");
if (!float.TryParse(val, out value))
value = 0;
GUILayout.EndHorizontal();
return value;
}
private static float FloatField(string label, float value)
{
GUILayout.BeginHorizontal();
GUILayout.Label(label);
string val = GUILayout.TextField(value.ToString());
//val = System.Text.RegularExpressions.Regex.Replace(val, @"^[0-9\.\+\-]", "");
if (!float.TryParse(val, out value))
value = 0;
GUILayout.EndHorizontal();
return value;
}
void IGameStateChangedGlobalHandler.OnGameStateChanged(GameState last, GameState current)
{
if ((current & GameState.Paused) == 0)
{
_showDebugMenu = false;
}
}
#endif
}
}
Basically in our current project we want to be able to start our game from any scene in the editor.
But if you do this… the game isn’t necessarily initialized yet. Certain actions that usually occur at the start of the game in our boot scene haven’t necessarily occurred yet if you just press play in the editor.
I also use this as a place to have an optional debug HUD display in the game if I press the tilde key.
But in game when I finally deploy… all that’s left is an empty ‘DebugStartup’ script that does nothing.