I'm building a RPG game in Unity and I have some trouble with my battle system. I have a world scene which is populated by various monsters, if the player collides with the monster it loads the battle Scene. I want to pass the name and ID# of the enemy controller so it can load the correct sprites and prefab (the battle scene is generic). The problem is that my monster object (in this case GrassSlug) is in a different scene (world scene) than my battle controller (battle scene). How can I communicate these values to my battle controller? Do I need to add an extra controller which doesn't get destroyed on load? (I current have a GameManager like that and a SkillManager).
GrassSlug.cs (GameObject in world scene)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrassSlug : Monster {
private string enemyName = "Grass Slug";
private int enemyID = 001;
}
Monster.cs (GameObject in world scene)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Monster : Character {
void OnCollisionEnter2D(Collision2D other)
{
if (other.collider.tag == "Player") {
SceneManager.LoadScene("Battle");
}
}
}
BattleController.cs (GameObject in Battle scene)
using Random = System.Random;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class BattleController : MonoBehaviour {
private Stat playerHealth;
private Stat enemyHealth;
private static Random random = new Random();
private int playerDamage;
private int enemyDamage;
public Button attackButton;
public Button escapeButton;
public Transform victoryText;
public GameObject canvas;
public GameObject button;
public Canvas battleUI;
void Start () {
InitHealth();
InitUI();
}
// <summary>
// Init player and enemy health
// </summary>
private void InitHealth()
{
playerHealth.Initialize(100, 100);
enemyHealth.Initialize(100, 100);
}
// <summary>
// Set up main battle UI
// </summary>
private void InitUI()
{
Button AttackButton = attackButton.GetComponent<Button>();
AttackButton.onClick.AddListener(PlayerAttack);
Button EscapeButton = escapeButton.GetComponent<Button>();
EscapeButton.onClick.AddListener(ReturnScene);
}
// <summary>
// Function for the player attack
// Calculates player's damage and adds XP to the skills
// </summary>
private void PlayerAttack ()
{
playerDamage = random.Next(20);
enemyHealth.CurrentValue -= playerDamage;
GameController.Instance.attackXP += playerDamage;
GameController.Instance.hitpointsXP += playerDamage;
if(enemyHealth.CurrentValue <= 0) {
Victory();
} else {
EnemyAttack();
}
}
// <summary>
// Function for enemy attack
// Calculates enemy's damage and adds XP to the players' skills
// </summary>
private void EnemyAttack () {
enemyDamage = random.Next(10);
playerHealth.CurrentValue -= enemyDamage;
GameController.Instance.defenceXP += enemyDamage;
GameController.Instance.SkillDebug();
if(playerHealth.CurrentValue <= 0) {
Debug.Log("You are defeated!");
}
}
// <summary>
// Change UI when player wins the battle
// </summary>
private void Victory() {
Instantiate(victoryText, new Vector3(0, 1.75f, 0), Quaternion.identity);
GameObject newCanvas = Instantiate(canvas) as GameObject;
GameObject newButton = Instantiate(button) as GameObject;
newButton.transform.SetParent(newCanvas.transform, false);
Button NewButton = newButton.GetComponent<Button>();
NewButton.onClick.AddListener(ReturnScene);
battleUI.gameObject.SetActive(false);
}
// <summary>
// Return to the previous screen
// Note: Currently only supports going back to the "Hometown" scene
// </summary>
private void ReturnScene () {
SceneManager.LoadScene("Hometown");
}
}
You can either create a new Don't Destroy On Load object that will hold that information for you, or just keep those data in static field. Static fields are not destroyed while changing scenes.
I guess you could also create a ScriptableObject for keeping this data, but this is not the best solution in this case in my opinion.
A simple solution is to create a static method and private static fields in your BattleController.
public class BattleController : MonoBehaviour {
private static string enemyName;
private static int enemyID;
public static void SetEnemy(string name, int id)
{
enemyName = name;
enemyID = id;
}
//other code
}
Then call the method before loading the scene.
public class Monster : Character {
void OnCollisionEnter2D(Collision2D other)
{
if (other.collider.tag == "Player") {
BattleController.SetEnemy(enemyName, enemyID)
SceneManager.LoadScene("Battle");
}
}
}
In your example the monster's name and ID are set as private fields in the GrassSlug class, but for this solution you'd need to add them to the Monster class as protected fields, then set them in GrassSlug.
If you need to share more information with the Battle Controller, you might want to just pass the Monster implementation to the Battle Controller instead of just its name and ID.
Related
I am making Third person multiplayer game with unity and Photon i can't get the Instantiating of players right both players are sometimes instantiating the same avatar or sometimes there camera Mix up. I have used Cinemachine Virtual camera and Cinemachine brain on main camera
My Hierarchy
Player Prefeb:
Cinemachine Virtual Cam:
Cinemachine brain cam:
This is my script that is responsible for intantiating players
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Photon.Pun;
using UnityEngine;
public class PlayerInstantiator : MonoBehaviour
{
PhotonView PV;
bool spawnPoint1 = true;
bool spawnPoint2 = true;
public GameObject player1;
public GameObject player2;
public Transform sp1;
public Transform sp2;
private void Update()
{
Debug.Log(CheckPlayers());
if (CheckPlayers() == 1 && spawnPoint1 == true)
{
spawnPoint1 = false;
SpawnMasterPlayer();
}
else if (CheckPlayers() == 2 && spawnPoint2 == true)
{
// SpawnMasterPlayer();
SpawnPlayer2();
spawnPoint2 = false;
}
}
private void SpawnMasterPlayer()
{
if (PV.IsMine)
{
CreateController(player1.name, sp1);
}
}
private void SpawnPlayer2()
{
if (!PV.IsMine)
{
CreateController(player2.name, sp2);
}
}
private int CheckPlayers()
{
return PhotonNetwork.CurrentRoom.PlayerCount;
}
private void Awake()
{
PV = GetComponent<PhotonView>();
}
void CreateController(string name, Transform sp)
{
PhotonNetwork.Instantiate(name, sp.position, Quaternion.identity);
}
}
It takes two spawn points and players Prefeb all have photon View attached but still i cant figure it out
It should intantiate two differnt Avatars and make their camers function properly
I've been stuck at this for a while. What I want is for my outline object to be instantiated at the location of my bronze Base game object and for it to destroy when the bronze base is no longer the closest to the player.
I'm willing to completely restart my bronze script if it means I can make this easier.
Thanks in advance!
Find Closest Bronze Script
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
public class FindBronze : MonoBehaviour
{
void Update()
{
FindClosestBronze();
}
void FindClosestBronze()
{
float distanceToClosestBronze = Mathf.Infinity;
Bronze closestBronze = null;
Bronze[] allBronze = GameObject.FindObjectsOfType<Bronze>();
foreach (Bronze currentBronze in allBronze)
{
float distanceToBronze = (currentBronze.transform.position - this.transform.position).sqrMagnitude;
if (distanceToBronze < distanceToClosestBronze)
{
distanceToClosestBronze = distanceToBronze;
closestBronze = currentBronze;
}
if (distanceToBronze > distanceToClosestBronze)
{
closestBronze.GetComponent<Bronze>().notSelected();
}
closestBronze.GetComponent<Bronze>().Selected();
}
}
}
Bronze (includes outline) script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bronze : MonoBehaviour
{
public bool isSelected = false;
public Animator anim;
[SerializeField]
public GameObject selectedBox;
public GameObject bronzeBase;
private GameObject clone;
// Update is called once per frame
void Awake()
{
clone = (GameObject)Instantiate(selectedBox, bronzeBase.transform);
}
public void Selected()
{
if (!isSelected)
{
clone = (GameObject)Instantiate(selectedBox, bronzeBase.transform);
isSelected = true;
}
else
{
Destroy(clone);
isSelected = false;
}
}
public void notSelected()
{
Destroy(selectedBox);
}
}
In the Bronze in notSelected you are destroying the prefab selectBox!
You probably rather wanted to destroy the clone instance.
Anyway I would suggest a few things that I would do different
Instead of Instantiate and Destroy all the time rather only use SetActive
Instead of using FindObjectOfType in Update store them in a HashSet event driven: Each Bronze instance registers and unregisters itself
Depends on personal taste but I would use Linq to find the closest instance
This could look somewhat like
public class Bronze : MonoBehaviour
{
// Every instance of this component registers and unregisters itself here
public static readonly HashSet<Bronze> Instances = new HashSet<Bronze>();
[Header("References")]
public Animator anim;
[SerializeField] private GameObject selectedBox;
[SerializeField] private GameObject bronzeBase;
[Header("Debugging")]
[SerializeField] bool _isSelected = false;
private GameObject clone;
// Have a property for the selection
public bool IsSelected
{
// when something reads this property return _isSelected
get => _isSelected;
// This is executed everytime someone changes the value of IsSelected
set
{
if(_isSelected == value) return;
_isSelected = value;
clone.SetActive(_isSelected);
}
}
// Update is called once per frame
void Awake()
{
// Instantiate already returns the type of the given prefab
clone = Instantiate(selectedBox, bronzeBase.transform);
// Register yourself to the alive instances
Instances.Add(this);
}
private void OnDestroy ()
{
// Remove yourself from the Instances
Instances.Remove(this);
}
}
And then use it
using System.Linq;
public class FindBronze : MonoBehaviour
{
private Bronze currentSelected;
private void Update()
{
UpdateClosestBronze();
}
void UpdateClosestBronze()
{
if(Bronze.Instances.Count ==0) return;
// This takes the instances
// orders them by distance ascending using the sqrMagnitude
// of the vector between the Instance and you
// sqrMagnitude is more efficient than Vector3.Distance when you only need to compare instead of the actual distance
// then finally it takes the first item
var newClosest = Bronze.Instances.OrderBy(b => (b.transform.position - transform.position).sqrMagnitude).First();
// skip if the result is the same as last time
if(newClosest == currentSelected) return;
// otherwise first deselect the current selection if there is one
if(currentSelected)
{
currentSelected.IsSelected = false;
}
// Then set the new selection
currentSelected = newSelected;
currentSelected.IsSelected = true;
}
}
My problem is that when all the enemies are killed the scene that should be loaded is not loading. I did add the scene to the Build setting (it has an index of 3) but it is still not loading. The script I created is attached to an empty object and not directly to the sprite (is that okay?). Can someone tell me why the scene isn't loading? Thank you.
This image is for to show you the EnemySpawner empty object inspector
EnemySpawner Script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnemySpawner : MonoBehaviour {
[SerializeField] GameObject EnemyPreFab;
[SerializeField] int MaxEnemies = 30;
[SerializeField] float EnemySpawnTime = 1.00001f;
[SerializeField] GameObject FirstWaypoint;
int CurrentNumOfEnemies = 0;
public LevelManager myLevelManager;
public int maximumnumberofhits = 0;
int timesEnemyHit;
IEnumerator SpawningEnemies()
{
while(CurrentNumOfEnemies <= MaxEnemies)
{
GameObject Enemy = Instantiate(EnemyPreFab, this.transform.position, Quaternion.identity);
CurrentNumOfEnemies++;
yield return new WaitForSeconds(EnemySpawnTime);
}
}
void Start()
{
StartCoroutine(SpawningEnemies());
timesEnemyHit = 0;
if (this.gameObject.tag == "EnemyHit")
{
CurrentNumOfEnemies++;
}
}
void OnCollisionEnter2D()
{
timesEnemyHit++;
if (timesEnemyHit == maximumnumberofhits)
{
CurrentNumOfEnemies--;
Destroy(this.gameObject);
}
if (CurrentNumOfEnemies == 0)
{
myLevelManager.LoadLevel("NextLevelMenu");
Debug.Log("LevelLoaded");
}
}
}
LevelManger script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelManager : MonoBehaviour {
public void LoadLevel(string name)
{
print("Level loading requested for" + name);
SceneManager.LoadScene(name);
}
}
EnemyShooting Script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyShooting : MonoBehaviour {
[SerializeField] float EnemyLaserSpeed = 10f;
[SerializeField] float EnemyLaserFireTime;
[SerializeField] GameObject LaserBulletEnemyPreFab;
[SerializeField] int MaxNumberOfHits = 1;
int CurrentNumberOfHits = 0;
Coroutine FireCoroutine;
void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject.tag == "PlayerLaser")
{
if(CurrentNumberOfHits < MaxNumberOfHits)
{
CurrentNumberOfHits++;
Destroy(collider.gameObject);
Score.ScoreValue += 2;//The user will be rewarded 1 point
}
}
}
void DestroyEnemy()
{
if(CurrentNumberOfHits >= MaxNumberOfHits)
{
Destroy(gameObject);
}
}
private void Fire()
{
FireCoroutine = StartCoroutine(ShootContinuously());
}
void BecomeVisible()
{
Fire();
}
IEnumerator ShootContinuously()
{
while (true)
{
GameObject LaserBulletEnemy = Instantiate(LaserBulletEnemyPreFab, this.transform.position, Quaternion.identity) as GameObject;
LaserBulletEnemy.GetComponent<Rigidbody2D>().velocity = new Vector2(0, EnemyLaserSpeed);
EnemyLaserFireTime = Random.Range(0.5f, 0.9f);
yield return new WaitForSeconds(EnemyLaserFireTime);
}
}
// Use this for initialization
void Start () {
BecomeVisible();
}
// Update is called once per frame
void Update () {
DestroyEnemy();
}
}
EnemyPathing script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyPathing : MonoBehaviour {
[SerializeField] List<Transform> WayPoints;
[SerializeField] float EnemyMovingSpeed = 5f;
int WayPointIndex = 0;
void EnemyMoving()
{
if (WayPointIndex <= WayPoints.Count - 1)
{
var TargetedPosition = WayPoints[WayPointIndex].transform.position; //The position of where the enemy needs to go
TargetedPosition.z = 0f;
var MoveThisFrame = EnemyMovingSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards(this.transform.position, TargetedPosition, MoveThisFrame);
if(transform.position == TargetedPosition)
{
WayPointIndex++;
}
}
else
{
Destroy(gameObject);
}
}
// Use this for initialization
void Start () {
transform.position = WayPoints[WayPointIndex].transform.position;
}
// Update is called once per frame
void Update () {
EnemyMoving();
}
}
Problem
You're checking for collisions on the SPAWNER; when someone hits the Spawner it counts down enemies. But the Spawner doesn't have a collision box in the screenshot so it can never be hit. The Scene changing code can never be called.
So the game, based on the code, looks like this:
Spawn X enemies,
Hit the Spawner X times,
(Removed: Destroy the Spawner,)
Change scene.
I'm guessing this is conceptually incorrect and you actually want to check collisions on the spawned enemies, which will then count up the amount of destroyed enemies, and change the scene when they are all dead.
Solution
Conceptually, what you want is:
Spawn X enemies
Count up variable for every enemy
On Enemy death, count it down
When 0, change scene
So how do we code this?
Well, every enemy needs a reference to the object that holds the count. You can do this in several ways, when I personally do it I usually have just one spawner that is responsible for everyone so I make that one a Singleton, that can be references from anywhere:
EnemySpawner
public class EnemySpawner : MonoBehaviour
{
public static Spawner Instance = null;
int CurrentNumOfEnemies = 0;
// ... etc
void Start()
{
if (Instance == null)
Instance = this;
// Spawn enemies like you do already, CurrentNumOfEnemies++ for every spawned
}
public OnEnemyDeath() {
CurrentNumOfEnemies--;
if (CurrentNumOfEnemies < 1)
{
// You killed everyone, change scene:
LevelManager.LoadLevel("Your Level");
}
}
}
Enemy script (I don't know how your current code looks, but here's a minimal solution based on how I THINK your code looks):
void OnDestroy()
{
// This will run automatically when you run Destroy() on this gameObject
EnemySpawner.Instance.OnEnemyDeath(); // Tell the EnemySpawner that someone died
}
This will only work if you have exactly only ONE spawner. If you have multiple ones you will have to send a reference to the instance of its spawner to every spawned enemy. I can show you how to do ths too, if you wish.
Bonus content
LevelManager doesn't need to be on a GameObject, it can be static instead:
Remove the LevelManager script from any GameObject
Change your LevelManager code to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public static class LevelManager
{
public static void LoadLevel(string name)
{
Debug.Log("Level loading requested for" + name);
SceneManager.LoadScene(name);
}
}
Now you can use it from ANYWHERE, without needing to initialize a reference to any script or GameObject:
LevelManager.LoadLevel("My Level");
myLevelManager.LoadLevel("NextLevelMenu"); is never executed, because you destroy the object in the if-test above.
In the game I am creating a 'Game Over' scene which loads once the player loses the game. During the game, the score is counted by the player's position on the screen and increases as the player's y-axis position increases.
I used this code to display the score on the scene the game was actually played:
using UnityEngine;
using UnityEngine.UI;
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
}
}
I tried to use the same coding to display the final score of the player on the 'Game Over' screen. The problem I faced was that I was not able to identify the player on the 'Game Over' scene as the player was not an object or sprite on that scene.
Is there an easy way to reference the player sprite from the previous scene into the final ('Game Over') scene so I can use it to determine the final score?
This is the script I tried with a game object of the 'EndScene' within the playing scene:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class EndMenu: MonoBehaviour
{
public Text scoreText;
public Transform player;
public static bool GameEnds = false;
public GameObject endMenuUI;
void OnCollisionEnter2D(Collision2D exampleCol)
{
if(exampleCol.collider.tag == "Obstacle")
{
endMenuUI.SetActive(true);
Time.timeScale = 0.0001f;
GameEnds = true;
}
}
public void Retry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
SceneManager.LoadScene("Menu");
}
public void Quit()
{
Debug.Log("Quitting game...");
Application.Quit();
}
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
}
}
You can keep the player using DontDestroyOnLoad
You could add this to the player:
void Awake() {
DontDestroyOnLoad(transform.gameObject);
}
You could do other stuff like keeping just the data... but the easier way should be this one.
Keep in mind that the player will remain in you gameover screen.
In my opinion the best idea could be creating a new gameobject in your game scene called "GameOverScreen" and disable it until you need it.
I think the easiest solution would be to simply store the score as a static variable that will persist across scene loads, then manually reset it when you start over. For example:
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
public static string scoreString;
// Update is called once per frame
void Update()
{
scoreString = player.position.y.ToString("0");
scoreText.text = scoreString;
}
}
Now you will be able to access scoreString from anywhere in your code and it will be whatever it was when the PlayerScore component last ran its Update(). Then in your EndMenu class, you would simply update your Retry() and BackToMenu() methods like so:
public void Retry()
{
PlayerScore.scoreString = "0";
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
PlayerScore.scoreString = "0";
SceneManager.LoadScene("Menu");
}
And your EndMenu.Update() method becomes the following:
// Update is called once per frame
void Update()
{
scoreText.text = PlayerScore.scoreString;
}
//try to use playerprefs to save the score
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
PlayerPrefs.SetInt("CurrentScore", player.position.y);
}
}
//for another scene get the value of saved score using playerprefs.getInt
public class EndMenu: MonoBehaviour
{
public Text scoreText;
public Transform player;
public static bool GameEnds = false;
public GameObject endMenuUI;
void OnCollisionEnter2D(Collision2D exampleCol)
{
if(exampleCol.collider.tag == "Obstacle")
{
endMenuUI.SetActive(true);
Time.timeScale = 0.0001f;
GameEnds = true;
}
}
public void Retry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
SceneManager.LoadScene("Menu");
}
public void Quit()
{
Debug.Log("Quitting game...");
Application.Quit();
}
// Update is called once per frame
void Update()
{
scoreText.text = PlayerPrefs.GetInt("Score",0);
}
}
I am almost done with my Object Pooling System for my PickAxe GameObject, but I have this one problem I need help with.
What I am trying to figure out is why all of my spawning restarts whenever the first PickAxe hits the wall? How do I make to where the PickAxe just goes back into the "pooler" whenever it hits the wall?
I took two screenshots and I'll post my code below too. The first one is just before the first Pickaxe that was spawned hits the wall, and the second screenshot is right after that same PickAxe hit the wall.
Some of my code below:
This script spawns my PickAxes. I am 99% sure my problem is where I am calling my Event function in my CoRoutine. Am I right?
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Obstacle4 // Pick Axe Obstacle
{
public float SpawnWait; // Time in seconds between next wave of obstacle 4.
public float StartGameWait; // Time in seconds between when the game starts and when the fourth obstacle start spawning.
public float WaveSpawnWait; // Time in seconds between waves when the next wave of obstacle 4 will spawn.
}
public class SpawnPickAxe : MonoBehaviour
{
public GameObject pickAxePrefab;
public Obstacle4 obstacle4_;
void Start ()
{
PickAxePoolManager.instance.CreatePool (pickAxePrefab, 15); //CreatePool is a method in PickAxePoolManager
StartCoroutine (PickAxeSpawner ());
}
IEnumerator PickAxeSpawner ()
{
yield return new WaitForSeconds (obstacle4_.StartGameWait);
while (true)
{
for (int i = 0; i < 5; i++)
{
Vector3 newSpawnPosition = new Vector3 (Random.Range(-10.0f, 10.0f), 1.2f, 30.0f);
Quaternion newSpawnRotation = Quaternion.Euler (0.0f, -90.0f, 0.0f);
PickAxePoolManager.instance.ReuseObject (pickAxePrefab, newSpawnPosition, newSpawnRotation); //ReuseObject is also a method in PickAxePoolManager
//Instantiate (obstacle4.pickAxe, spawnPosition, spawnRotation);
yield return new WaitForSeconds (obstacle4_.SpawnWait);
ResetByWall.instance.onTriggerEntered += delegate(GameObject obj)
{
PickAxePoolManager.instance.ReuseObject(pickAxePrefab, newSpawnPosition, newSpawnRotation);
};
}
yield return new WaitForSeconds (obstacle4_.WaveSpawnWait);
}
}
}
Below is my "ResetByWall" script. This script is also important because it contains the public Event that allows me to detect a collision with whatever collides with my wall, and my wall is the trigger.
using System;
using UnityEngine;
using System.Collections;
public class ResetByWall : MonoBehaviour
{
//public bool collided;
//public GameObject pickAxePrefab;
//NOTE:
//Singleton Pattern from lines 12 to 25 //
// ************************************
static ResetByWall _instance; // Reference to the Reset By Wall script
public static ResetByWall instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<ResetByWall>(); //Find the instance in the Reset By Wall script in the currently active scene
}
return _instance;
}
}
public event Action <GameObject> onTriggerEntered;
void OnTriggerEnter(Collider other)
{
if (onTriggerEntered != null) {
onTriggerEntered (other.gameObject);
}
}
}
And below is my PoolManager Script. You might not even need to look at this script but I'll post it anyways just in case.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PickAxePoolManager : MonoBehaviour {
Dictionary<int,Queue<GameObject>> poolDictionary = new Dictionary<int,Queue<GameObject>>();
//NOTE:
//Singleton Pattern used from lines 12 to 25
static PickAxePoolManager _instance; // Reference to the Pool Manager script
public static PickAxePoolManager instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<PickAxePoolManager>(); //Find the instance in the Pool Manager script in the currently active scene
}
return _instance;
}
}
/// <summary>
/// Creates the pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="poolSize">Pool size.</param>
public void CreatePool(GameObject prefab, int poolSize)
{
int poolKey = prefab.GetInstanceID (); // Unique integer for every GameObject
if (!poolDictionary.ContainsKey (poolKey)) //Make sure poolKey is not already in the Dictionary,
//if it's not then we can create the pool
{
poolDictionary.Add(poolKey, new Queue<GameObject>());
for (int i = 0; i < poolSize; i++) //Instantiate the prefabs as dictated by the "poolSize" integer
{
GameObject newObject = Instantiate (prefab) as GameObject; //Instantiate as a GameObject
newObject.SetActive(false); // Don't want it to be visible in the scene yet
poolDictionary [poolKey].Enqueue(newObject); // Add it to our Pool
}
}
}
I solved the problem. I am just going to use this in my ResetByWall script:
void OnTriggerEnter (Collider obstacle)
{
if (obstacle.gameObject.tag == "Pick Axe")
{
obstacle.gameObject.SetActive (false);
}
}
Thanks! :)