I have been working on my game for quite a while. one of its key features is cross-platform local multiplayer for example 2 players on 1 keyboard and some people on the controller.
here is the 4th Iteration
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public GameObject playerPrefab;
public GameObject[] Players;
public List<string> playerOrderString = new List<string>() { };
public bool resetPlayerSelect;
public Image UIImage;
public float fadeTime = 1.0f;
public GameObject MainCamera;
public bool isGameRunning = false;
#region Spawnner
public GameObject spawnnerGameObject;
public GameObject[] objectsToSpawn;
public GameObject[] ObjectsToSpawnOnFloor;
public float[] SpawnRateOfObjectsPerFloor;
#endregion
void Start()
{
MainCamera = GameObject.FindWithTag("MainCamera");
isGameRunning = false;
Time.timeScale = 0.0f;
}
void Update()
{
if (isGameRunning == false)
{
InputCheck();
AssignPlayerInput();
if (playerOrderString.Count != 0)
if (Input.GetButtonDown("Select" + playerOrderString[0]))
{
SceneManager.LoadScene(0, LoadSceneMode.Single);
}
}
else if (isGameRunning == true)
{
if (Input.GetButtonDown("Start" + playerOrderString[0]))
{
PauseOrResumeGame();
}
}
}
public bool RestartGame = false;
void PauseOrResumeGame()
{
if (isGameRunning == true)//this pauses the game
{
Time.timeScale = 0.0f;
isGameRunning = false;
}
else if (isGameRunning == false)
{
Time.timeScale = 1.0f;//this resumes the game
isGameRunning = true;
}
else
Debug.Log(Time.timeScale);
}
void InputCheck()
{
if (playerOrderString.Count == 0)
return;
if (resetPlayerSelect || Input.GetButtonDown("resetInput"))
ResetInput();
else if (Input.GetButtonDown("Start" + playerOrderString[0]) && GameObject.FindWithTag("MazeGenerator") == null)
StartGame();
else if (Input.GetButtonDown("Start" + playerOrderString[0]))
PauseOrResumeGame();
}
public GameObject floorSet;
void StartGame()
{
isGameRunning = true;
Time.timeScale = 1.0f;
Instantiate(floorSet, new Vector3(0, -0.45f, 0), Quaternion.identity);
playerOrderString.RemoveAll(item => item == null);
PlayersHasBeenSelected();
StartCoroutine(FadeOutStartScreen(fadeTime, 0.0f));
Players = new GameObject[playerOrderString.Count];
InstantiatePlayers();
}
void InstantiatePlayers()
{
transform.position -= new Vector3((Players.Length - 1) * 2, 0, 0);
for (int i = 0; i < Players.Length; i++)
{
Players[i] = Instantiate(playerPrefab, transform.position, Quaternion.identity) as GameObject;
Instantiate(spawnnerGameObject, transform.position, Quaternion.identity);
transform.position += new Vector3(4, 0, 0);
Players[i].GetComponent<PlayerMovement>().playerInput = playerOrderString[i];
Players[i].GetComponent<PlayerMovement>().playerText = PlayersText[i];
Players[i].GetComponent<PlayerMovement>().PlayerNumber = i + 1;
StartCoroutine(WaitUntilScreenFades(fadeTime, i));
}
for (int i = 0; i < objectsToSpawn.Length; i++)
{
Instantiate(objectsToSpawn[i]);
}
MainCamera.GetComponent<CameraController>().enabled = true;
}
IEnumerator WaitUntilScreenFades(float fadeTime, int i)
{
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / fadeTime)
{
yield return null;
}
Players[i].GetComponent<PlayerMovement>().enabled = true;
}
IEnumerator FadeOutStartScreen(float fadeTime, float fadeToValue)
{
float alpha = UIImage.color.a;
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / fadeTime)
{
Color newColor = new Color(1, 1, 1, Mathf.Lerp(alpha, fadeToValue, t));
UIImage.color = newColor;
yield return null;
}
}
void ResetInput()
{
playerOrderString = new List<string>() { };
resetPlayerSelect = false;
{
for (int i = 0; i < 4; i++)
PlayersText[i].text = "Player Not Selected";
}
StartCoroutine(FadeOutStartScreen(fadeTime, 1.0f));
}
void AssignPlayerInput()
{
for (int unAssignedPlayer = playerOrderString.Count; unAssignedPlayer <= playerOrderString.Count; unAssignedPlayer++)
{
if (playerOrderString.Count >= 0)
{
CheckInputFor("K", 2);
CheckInputFor("C", 4);
}
}
}
void CheckInputFor(string repFor, int times)
{
for (int input = 0; input < times; input++)
{
string playerOrderValue = repFor + (input + 1);
string playerThisTime = "Fire1" + playerOrderValue;
if ((Input.GetButtonDown(playerThisTime)))
{
if (CheckForDuplicateInput(playerOrderValue))
{
playerOrderString.Add(playerOrderValue);
PlayersHasBeenSelected();
}
else
return;
}
}
}
bool CheckForDuplicateInput(string playerOrderValue)
{
for (int i = 0; i < playerOrderString.Count; i++)
{
if (playerOrderString[i] == playerOrderValue)
{
return false;//isDupplicate
}
}
return true;//not dubliclate
}
public Text[] PlayersText;
void PlayersHasBeenSelected()
{
for (int i = 0; i < playerOrderString.Count; i++)
{
PlayersText[i].text = "Player " + (i + 1) + " is " + playerOrderString[i];
}
}
}
As of now in my 4ths Iteration, the code works fine but I would like to optimize it further since it still seems a bit inefficient to me
I will explain a bit more about how my code works
In unity input manager I have set up controls for 6 types of controllers which follow the pattern of thisInputK1, thisInputK2, thisInputC1... and so on where K denotes keyboard input and C denotes Controller Input.
The numbers after that denote the different sets of keys the input requests, for example, VecticalK1 is the same as VecticalK2 but K1 uses WASD while K2 uses arrow keys same is for the controller but they use separate controllers.
after a player 1 is assigned if player one presses their start button the input manager feeds controls to game manager and the game begins