Hey @revolution5,
I've made an example scene for you with a round system according to your code.
https://www.dropbox.com/s/x5i1zcddq0gebeo/RoundSystemExample.unitypackage?dl=0
***(Don't forget to check out the code for you specifically below the following concept code)***
The basic concept is this:
> You have a game cycle, within that> game cycle, you loop through multiple> rounds. You can wait for each phase of> the round by starting coroutines> inside coroutines, as shown below.
using UnityEngine;
using System.Collections;
public class RoundSystemSimple : MonoBehaviour {
[Range( 1, 5 )] // Makes the number of rounds a slider from 1 to 5.
public int m_numberOfRounds = 3; // Indicate number of rounds, 3 by default.
[Header( "Duration Settings" )]
public float m_startWait = 3f;
public float m_roundDurationInSeconds = 5f; // 5 seconds, try 180 for 3 minutes (set in inspector).
public float m_endWait = 2f;
// Holder Variables.
private int m_currentRound = 1;
private float m_currentRoundTimeRemaining;
private WaitForSeconds m_waitShortly = new WaitForSeconds( 0.01f );
void Start()
{
StartCoroutine( RoundSystem() );
}
private IEnumerator RoundSystem()
{
// Lasts X rounds.
while( m_currentRound <= m_numberOfRounds )
{
yield return StartCoroutine( StartRound() );
yield return StartCoroutine( RoundBusy() );
yield return StartCoroutine( EndRound() );
m_currentRound++;
}
}
private IEnumerator StartRound()
{
// Do Round Start Stuff.
m_currentRoundTimeRemaining = m_roundDurationInSeconds;
yield return m_waitShortly;
}
private IEnumerator RoundBusy()
{
while( m_currentRoundTimeRemaining > 0f )
{
// Do Round Busy Stuff. (Using clamp to prevent dirty values like -0.0123 upon round ending)
m_currentRoundTimeRemaining = Mathf.Clamp( m_currentRoundTimeRemaining - Time.deltaTime, 0, m_roundDurationInSeconds );
yield return m_waitShortly;
}
}
private IEnumerator EndRound()
{
// Do Round End Stuff.
yield return new WaitForSeconds( m_endWait );
}
}
The full code adjusted to your needs is this:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class RoundSystemExample : MonoBehaviour
{
[Range(1,5)] // Makes the number of rounds a slider from 1 to 5.
public int m_numberOfRounds = 3; // Indicate number of rounds, 3 by default.
[Header("Duration Settings")]
public float m_startWait = 3f;
public float m_roundDurationInSeconds = 5f; // 5 seconds, try 180 for 3 minutes (set in inspector).
public float m_endWait = 2f;
[Header("Has Started")]
public GameObject m_starterPrefab;
public Transform m_startingLocation;
public GameObject hasStarted; // Public so it can be set if wished for.
[Header("Ball Settings")]
public float m_initialBallSpeed = 5f;
public float m_ballRespawnWait = 3f; // Currently Unused.
[Header("Timer Display")]
public Text m_timerText;
[Header("Force Stop")]
public bool m_stop;
// Lists of different targetAreas, balls and spawn locations.
[Header("Lists")]
public List m_targetAreas = new List();
public List m_balls = new List();
public List m_spawnLocations = new List();
// Active Objects.
private GameObject inPlayBall;
private GameObject inTarget;
// Holder Variables.
private int m_currentRound = 1;
private float m_currentRoundTimeRemaining;
private WaitForSeconds m_waitShortly = new WaitForSeconds( 0.01f );
private Vector3 m_relativePos;
private int m_ranNum;
void Start()
{
if (hasStarted == null)
{
hasStarted = Instantiate( m_starterPrefab, m_startingLocation.position, m_startingLocation.rotation ) as GameObject;
}
StartCoroutine( RoundSystem() );
}
private IEnumerator RoundSystem()
{
Debug.Log( "Awaiting has started to become null" );
while ( hasStarted != null )
{
yield return m_waitShortly;
}
Debug.Log( "HasStarted became null, Starting RoundSystem." );
// Lasts X rounds.
while (m_currentRound <= m_numberOfRounds && !m_stop)
{
// Just a friendly debug, could be used for UI call. (Add else for normal rounds)
if( m_currentRound == m_numberOfRounds )
{
Debug.Log( "Final Round!" );
}
yield return StartCoroutine( StartRound() );
yield return StartCoroutine( RoundBusy() );
yield return StartCoroutine( EndRound() );
m_currentRound++;
}
}
private IEnumerator StartRound()
{
// Do Start Round Stuff.
float startWaitCurrent = m_startWait;
while (startWaitCurrent > 0)
{
startWaitCurrent -= Time.deltaTime;
m_timerText.text = "Round " + m_currentRound + " Starting in " + Mathf.RoundToInt( startWaitCurrent ).ToString();
yield return m_waitShortly;
}
// If you don't want text display stuff, just use:
// yield return new WaitForSeconds( m_startWait ); // Round start delay.
if( !m_stop )
{
m_currentRoundTimeRemaining = m_roundDurationInSeconds;
if( inPlayBall == null )
{
// Your adjusted code.
inPlayBall = Instantiate( _getRandomFromList( m_balls ), _getRandomFromList( m_spawnLocations ).position, Quaternion.identity ) as GameObject;
m_relativePos = _getRandomFromList( m_targetAreas ).transform.position - inPlayBall.transform.position;
inPlayBall.GetComponent().velocity = m_relativePos;
}
}
}
private IEnumerator RoundBusy()
{
while (m_currentRoundTimeRemaining > 0f && !m_stop)
{
// Do Round Busy Stuff. (Using clamp to prevent dirty values like -0.0123 upon round ending)
m_currentRoundTimeRemaining = Mathf.Clamp( m_currentRoundTimeRemaining - Time.deltaTime, 0, m_roundDurationInSeconds);
_updateText();
yield return m_waitShortly;
}
}
private IEnumerator EndRound()
{
// Do Round End Stuff.
m_timerText.text = (m_currentRound >= m_numberOfRounds) ? "Game Over" : "Round Over";
Destroy( inPlayBall );
yield return new WaitForSeconds( m_endWait );
}
// Using your code, changed from .ToString("f0") to .ToString( "00" ); force two digits for seconds at all times.
private void _updateText()
{
string minutes = ( ( int ) m_currentRoundTimeRemaining / 60 ).ToString();
string seconds = ( m_currentRoundTimeRemaining % 60 ).ToString( "00" );
m_timerText.text = minutes + ":" + seconds;
}
// Applied generic method, gets random item from list.
private T _getRandomFromList(List list)
{
if (list == null)
{
Debug.Log( "List is null, make sure list = new List<>(); was called somewhere" );
return default( T );
}
else if (list.Count == 0)
{
Debug.Log( "List is empty, fill it first." );
return default( T );
}
// Return a random item from the list.
return list[ Random.Range( 0, list.Count ) ];
}
}
I hope this helps you out! It took me a while, but it was fun to make, so thank you for your question! :)
If it did help you out, please accept this answer, it'd be much appreciated!
Best of luck! If you need anything else, let me know!
↧