I am creating a rogue-like dungeon crawler and I have recently implemented my GameManager as a singleton that takes advantage of the C# Event/Action system. I have run into a minor issue that I can live with but would love to use the situation as a learning opportunity for myself! One of the Events (PlayerMoveEvent) is originally triggered by the Player moving as this is how traps/enemies/etc. are notified that they should also be completing their turns but for the very first move of the game, the MoveEvent says it does not exist.
This is obviously due to the order that scripts are being called/gameObjects are being created but as far as I can tell I have it set up where this should not be an issue. As a side note, my GameManager script execution is set to the very first thing that is created in the game (-500ms).
The order of script execution is currently like this (some code not relevant to the issue has been removed fo easier readability):
GAME MANAGER (1st)
private void Awake()
{
//SINGLETON ASSIGNMENT
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
_dg = GetComponent<DungeonGenerator>();
}
void Start()
{
//GENERATE FIRST LEVEL
curLevel = 1;
_dg.ChooseNextRoomLayout();
}
DUNGEON GENERATOR (2nd)
public void ChooseNextRoomLayout() //Chooses which room layout according to current level
{
_roomInfo = _curRoom.GetComponent<RoomInformation>(); //Sets room info to the current room
_curTiles = _roomInfo.roomTiles; //Sets the tile list to the current room tiles
//SET THE CUR DUNGEON INFO FOR PLAYER
_playerController.curDungeonFirstPlayTile = _roomInfo.firstPlayTile;
_playerController.curDungeonLastPlayTile = _roomInfo.lastPlayTile;
_playerController.curDungeonStartTile = _roomInfo.startTile;
_playerController.curDungeonEndTile = _roomInfo.endTile;
_playerController.moveDirHorizontal = _roomInfo.startMoveDirHorizontal;
_playerController.StartLevel();
GenerateDungeon();
}
PLAYER CONTROLLER (3rd)
public void StartLevel()
{
transform.position = curDungeonStartTile.transform.position;
playerTargetTile = curDungeonFirstPlayTile.transform.position;
currentPos = transform.position;
StartCoroutine(MoveToPosition(removed as it is not important));
}
public IEnumerator MoveToPosition(Vector3 targetTile, float timeToMove, int tilesToTarget)
{
float time = 0f; //Reset timer
GameManager.Instance.PlayerMove();
timeToMove *= tilesToTarget;
while (time < 1)
{
time += Time.deltaTime / timeToMove; //How much time has passed relatively
transform.position = Vector3.Lerp(currentPos, targetTile, time); //Change to smoothDamp
yield return null;
}
}
GAME MANAGER (4th)
public void PlayerMove()
{
if (PlayerMoveEvent != null)
{
PlayerMoveEvent();
}
else
{
Debug.Log("PlayerMoveEvent is null");
}
}
For the very first Player Movement, I get the “PlayerMoveEvent is null” debug message. It is not a huge issue by any means but in my mind, the execution order should work out so that the PlayerMoveEvent is not null. Would love to learn why it is so!
Any info or thoughts are greatly appreciated, thanks!