//In Coin.cs
private void OnTriggerEnter(Collider other) {
PlayerMovement player = other.gameObject.GetComponent<PlayerMovement>();
if(player != null)
{
GameManager.Instance.OnScoreIncrease?.Invoke();
SoundManager.Instance?.PlaySFX(SoundType.CoinPickup);
Instantiate(coinPickEffect,transform.position,Quaternion.identity);
}
base.Destroy();
}
//In GameManager.cs
//In Initialize method
OnScoreIncrease.AddListener(IncreaseScore);
OnScoreIncrease.AddListener(UpdateScoreText);
//Separate methods
private void IncreaseScore()
{
_score++;
}
private void UpdateScoreText()
{
_scoreText.text = _score.ToString();
}
void Update()
{
Floor firstFloor = _floors[0];
Transform firstFloorEndPoint = firstFloor.EndPoint;
float offset = player.transform.position.z - firstFloorEndPoint.position.z;
if(offset >= spawnDistance)
{
Debug.Log("Generating path");
for(int i = 1; i <= floorsGenerationCount; i++)
{
Floor lastFloor = _floors[_floors.Count - 1];
Transform lastFloorEndPoint = lastFloor.EndPoint;
Floor generatedFloor = PoolManager.Instance.ReuseObject(floor.gameObject,lastFloorEndPoint.position,Quaternion.identity).PoolObject as Floor;
_floors.Add(generatedFloor);
Transform generatedFloorEndPoint = generatedFloor.EndPoint;
if(generateObstacles)
{
GenerateObstacles(generatedFloor,generatedFloorEndPoint);
}
if(generateCoins)
{
GenerateCoins(generatedFloor,generatedFloorEndPoint);
}
}
SetToOrigin();
_floors.Remove(firstFloor);
StartCoroutine(DestroyFloor(firstFloor,floorDestroyTime));
}
}
void SetToOrigin()
{
playerCamera.enabled = false;
player.transform.position -= Vector3.forward * backwardDistance;
playerCamera.enabled = true;
foreach(Floor floor in _floors)
{
floor.transform.position -= Vector3.forward * backwardDistance;
List<PoolObject> things = floor.ThingsOnFloor;
foreach(PoolObject thing in things)
{
if(thing != null)
{
thing.transform.position -= Vector3.forward * backwardDistance;
}
}
}
}
private void GenerateObstacles(Floor floor,Transform floorEndPoint)
{
int randomObstacleCount = Random.Range(1,maxObstaclesPerFloor + 1);
for(int i = 1; i <= randomObstacleCount; i++)
{
int randomSpawnPtIndex = Random.Range(0,spawnPointRefs.Length);
float positionX = spawnPointRefs[randomSpawnPtIndex].transform.position.x;
float positionZ = floorEndPoint.position.z - Random.Range(0f,obstacleSpawnLength);
float positionY = spawnPointRefs[randomSpawnPtIndex].transform.position.y;
Vector3 spawnPosition = new Vector3(positionX,positionY,positionZ);
Obstacle obstacle = PoolManager.Instance.ReuseObject(obstaclePrefab.gameObject,spawnPosition,Quaternion.identity).PoolObject as Obstacle;
floor.AddThing(obstacle);
}
}
private void GenerateCoins(Floor floor,Transform floorEndPoint)
{
int randomCoinsCount = Random.Range(1,maxCoinsToGenerate + 1);
for(int i = 1; i <= randomCoinsCount; i++)
{
int randomSpawnPtIndex = Random.Range(0,spawnPointRefs.Length);
float positionX = spawnPointRefs[randomSpawnPtIndex].transform.position.x;
float positionZ = floorEndPoint.position.z - Random.Range(0f,obstacleSpawnLength);
float positionY = spawnPointRefs[randomSpawnPtIndex].transform.position.y;
Vector3 spawnPosition = new Vector3(positionX,positionY,positionZ);
Coin coin = PoolManager.Instance.ReuseObject(coinPrefab.gameObject,spawnPosition,Quaternion.identity).PoolObject as Coin;
floor.AddThing(coin);
}
}
private IEnumerator DestroyFloor(Floor floor,float destroyTime)
{
yield return new WaitForSeconds(destroyTime);
floor.Destroy();
}//PoolManager.cs
public class PoolManager : GenericSingleton<PoolManager>
{
private Dictionary<int,Queue<ObjectInstance>> _poolDictionary;
protected override void Awake() {
base.Awake();
_poolDictionary = new Dictionary<int, Queue<ObjectInstance>>();
}
private void Start() {
SceneManager.sceneLoaded += OnSceneLoaded;
}
public void CreatePool(GameObject prefab,int poolSize)
{
int id = prefab.GetInstanceID();
if(_poolDictionary.ContainsKey(id) == false)
{
_poolDictionary.Add(id,new Queue<ObjectInstance>());
GameObject poolObjectsContainer = new GameObject(prefab.name + " pool");
poolObjectsContainer.transform.parent = transform;
for(int i = 0; i < poolSize; i++)
{
ObjectInstance objectInPool = new ObjectInstance(Instantiate(prefab) as GameObject,id);
objectInPool.SetParent(poolObjectsContainer.transform);
_poolDictionary[id].Enqueue(objectInPool);
}
}
}
/*
public void ReuseObject(GameObject prefab,Vector3 position,Quaternion rotation)
{
int id = prefab.GetInstanceID();
if(!_poolDictionary.ContainsKey(id))
{
Debug.LogError(prefab.name + " Pool not found!!");
return;
}
ObjectInstance objectInPool = _poolDictionary[id].Dequeue();
objectInPool.Reuse(position,rotation);
_poolDictionary[id].Enqueue(objectInPool);
}
*/
public ObjectInstance ReuseObject(GameObject prefab,Vector3 position,Quaternion rotation)
{
int id = prefab.GetInstanceID();
if(!_poolDictionary.ContainsKey(id))
{
Debug.LogError(prefab.name + " pool not found!!");
return null;
}
if(_poolDictionary[id].Count == 0)
{
return null;
}
ObjectInstance objectInPool = _poolDictionary[id].Dequeue();
objectInPool.Reuse(position,rotation);
//_poolDictionary[id].Enqueue(objectInPool);
return objectInPool;
}
public void ReturnObjectToPool(ObjectInstance instance)
{
if(!_poolDictionary.ContainsKey(instance.MainPrefabID))
{
Debug.LogError(instance.GameObject.name + " Pool not found!!");
return;
}
_poolDictionary[instance.MainPrefabID].Enqueue(instance);
}
public void ClearAllPools()
{
foreach(var pair in _poolDictionary)
{
Queue<ObjectInstance> poolObjects = pair.Value;
while(poolObjects.Count > 0)
{
poolObjects.Dequeue();
}
}
_poolDictionary.Clear();
GameObject[] allChildren = new GameObject[transform.childCount];
int i = 0;
foreach(Transform child in transform)
{
allChildren[i] = child.gameObject;
i++;
}
foreach(GameObject child in allChildren)
{
Destroy(child);
}
}
private void OnSceneLoaded(Scene scene,LoadSceneMode mode)
{
ClearAllPools();
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
}//ObjectInstance.cs
public class ObjectInstance
{
GameObject gameObject;
Transform transform;
bool hasPoolObjectComponent;
PoolObject poolObject;
int mainPrefabID;
public PoolObject PoolObject { get => poolObject; }
public GameObject GameObject { get => gameObject; }
public int MainPrefabID { get => mainPrefabID; }
public ObjectInstance(GameObject gameObject,int mainPrefabID)
{
this.gameObject = gameObject;
this.transform = gameObject.transform;
this.gameObject.SetActive(false);
this.mainPrefabID = mainPrefabID;
PoolObject poolObjectReference = gameObject.GetComponent<PoolObject>();
if(poolObjectReference != null)
{
this.hasPoolObjectComponent = true;
this.poolObject = poolObjectReference;
this.poolObject.ObjectInstanceComp = this;
}
}
public void Reuse(Vector3 position,Quaternion rotation)
{
if(this.hasPoolObjectComponent)
{
this.poolObject.Reuse();
}
this.gameObject.SetActive(true);
this.gameObject.transform.position = position;
this.gameObject.transform.rotation = rotation;
}
public void SetParent(Transform parent)
{
this.gameObject.transform.parent = parent;
}
}