- Home /
Need to a Instantiate a prefab in canvas which is in another scene
I am making an achievement system.I have to 2 scene in my game.The first scene is my Main Menu and the other scene is my game scene. I have designed and coded the achievement system in the main menu scene and added a EarnCanvas to my game scene. EarnCanvas will display the achievement that the player has unlocked.
Code i have is only allowing me to link the achievements to a EarnCanvas on the Main Menu scene.i need help to modifier the code or link the two scene so that i can instantiate the unlocked achievement prefab in the EarnCanvas in the game Scene. At the moment no prefab is instantiated or displayed in the EarnCanvas when the player has unlocked an achievement.
Main Menu scene achievement Manager script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
public class AchievementManager : MonoBehaviour {
public GameObject achievementPraf;
public Sprite[] sprites;
private AchievementButton activeButton;
public ScrollRect scrollRect;
public GameObject achievementMenu;
public GameObject visualAchievement;
public Dictionary<string, Achievement> achievements = new Dictionary<string, Achievement>();
public Sprite UnlockedSprite;
private static AchievementManager instance;
public static AchievementManager Instance
{
get {
if(instance == null)
{
instance = GameObject.FindObjectOfType<AchievementManager>();
}
return AchievementManager.instance;
}
}
// Use this for initialization
void Start ()
{
//remove before deploy
//PlayerPrefs.DeleteAll();
activeButton = GameObject.Find("Streakbtn").GetComponent<AchievementButton>();
CreateAchievement("Streak", "Press W", "Press W to unlock this achievement", 5, 0);
CreateAchievement("Streak", "Press R", "Press R to unlock this achievement", 5, 0);
CreateAchievement("Streak", "Press All Keys", "Press All Keys to unlock", 5, 0, new string[] { "Press W", "Press R" });
foreach (GameObject achievementList in GameObject.FindGameObjectsWithTag("achievementList"))
{
achievementList.SetActive(false);
}
activeButton.click();
achievementMenu.SetActive(false);
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.S))
{
achievementMenu.SetActive(!achievementMenu.activeSelf);
}
if(Input.GetKeyDown(KeyCode.W))
{
EarnAchievemnent("Press W");
}
if (Input.GetKeyDown(KeyCode.R))
{
EarnAchievemnent("Press R");
}
}
public void EarnAchievemnent(string title)
{
if(achievements[title].EarnAchievement())
{
GameObject achievement = (GameObject) Instantiate(visualAchievement);
StartCoroutine(HideAchievement(achievement));
//this is where is its giving the parent the gameobject name to find
SetAchievementInfo("EarnCanvas", achievement, title);
}
}
public IEnumerator HideAchievement(GameObject achievement)
{
yield return new WaitForSeconds(3);
Destroy(achievement);
}
public void CreateAchievement(string parent,string title,string description,int points,int spriteIndex,string[] dependencies = null)
{
GameObject achievement = (GameObject)Instantiate(achievementPraf);
Achievement newAchievement = new Achievement(name, description, points, spriteIndex,achievement);
achievements.Add(title, newAchievement);
SetAchievementInfo(parent, achievement,title);
if(dependencies != null)
{
foreach(string achievementTitle in dependencies)
{
Achievement dependency = achievements[achievementTitle];
dependency.Child = title;
newAchievement.AddDependency(dependency);
//Dependency = Press Space <-- Child = Press W
//NewAchievement = Press W --> Press Space
}
}
}
public void SetAchievementInfo(string parent, GameObject achievement, string title)
{
//this where its trying to find a gameobject-(EarnCanvas) to instantiate the unlocked achievement prefab in the Main Menu Scene
achievement.transform.SetParent(GameObject.Find(parent).transform);
achievement.transform.localScale = new Vector3(1, 1, 1);
achievement.transform.localPosition = new Vector3(0, 0, 0);
achievement.transform.GetChild(0).GetComponent<Text>().text = title;
achievement.transform.GetChild(1).GetComponent<Text>().text = achievements[title].Description;
achievement.transform.GetChild(2).GetComponent<Text>().text = achievements[title].Points.ToString();
achievement.transform.GetChild(3).GetComponent<Image>().sprite = sprites[achievements[title].SprintIndex];
}
public void ChangeCategory(GameObject button)
{
AchievementButton achievementButton = button.GetComponent<AchievementButton>();
scrollRect.content = achievementButton.achievementList.GetComponent<RectTransform>();
achievementButton.click();
activeButton.click();
activeButton = achievementButton;
}
}
I am making an achievement system.I have to 2 scene in my game.The first scene is my Main Menu and the other scene is my game scene. I have designed and coded the achievement system in the main menu scene and added a EarnCanvas to my game scene. EarnCanvas will display the achievement that the player has unlocked.
Code i have is only allowing me to link the achievements to a EarnCanvas on the Main Menu scene.i need help to modifier the code or link the two scene so that i can instantiate the unlocked achievement prefab in the EarnCanvas in the game Scene. At the moment no prefab is instantiated or displayed in the EarnCanvas when the player has unlocked an achievement.
Main Menu scene
achievement Manager script:
using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic;
public class AchievementManager : MonoBehaviour {
public GameObject achievementPraf;
public Sprite[] sprites;
private AchievementButton activeButton;
public ScrollRect scrollRect;
public GameObject achievementMenu;
public GameObject visualAchievement;
public Dictionary<string, Achievement> achievements = new Dictionary<string, Achievement>();
public Sprite UnlockedSprite;
private static AchievementManager instance;
public static AchievementManager Instance
{
get {
if(instance == null)
{
instance = GameObject.FindObjectOfType<AchievementManager>();
}
return AchievementManager.instance;
}
}
// Use this for initialization
void Start ()
{
//remove before deploy
//PlayerPrefs.DeleteAll();
activeButton = GameObject.Find("Streakbtn").GetComponent<AchievementButton>();
CreateAchievement("Streak", "Press W", "Press W to unlock this achievement", 5, 0);
CreateAchievement("Streak", "Press R", "Press R to unlock this achievement", 5, 0);
CreateAchievement("Streak", "Press All Keys", "Press All Keys to unlock", 5, 0, new string[] { "Press W", "Press R" });
foreach (GameObject achievementList in GameObject.FindGameObjectsWithTag("achievementList"))
{
achievementList.SetActive(false);
}
activeButton.click();
achievementMenu.SetActive(false);
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.S))
{
achievementMenu.SetActive(!achievementMenu.activeSelf);
}
if(Input.GetKeyDown(KeyCode.W))
{
EarnAchievemnent("Press W");
}
if (Input.GetKeyDown(KeyCode.R))
{
EarnAchievemnent("Press R");
}
}
public void EarnAchievemnent(string title)
{
if(achievements[title].EarnAchievement())
{
GameObject achievement = (GameObject) Instantiate(visualAchievement);
StartCoroutine(HideAchievement(achievement));
//this is where is its giving the parent the gameobject name to find SetAchievementInfo("EarnCanvas", achievement, title);
}
}
public IEnumerator HideAchievement(GameObject achievement)
{
yield return new WaitForSeconds(3);
Destroy(achievement);
}
public void CreateAchievement(string parent,string title,string description,int points,int spriteIndex,string[] dependencies = null)
{
GameObject achievement = (GameObject)Instantiate(achievementPraf);
Achievement newAchievement = new Achievement(name, description, points, spriteIndex,achievement);
achievements.Add(title, newAchievement);
SetAchievementInfo(parent, achievement,title);
if(dependencies != null)
{
foreach(string achievementTitle in dependencies)
{
Achievement dependency = achievements[achievementTitle];
dependency.Child = title;
newAchievement.AddDependency(dependency);
//Dependency = Press Space <-- Child = Press W
//NewAchievement = Press W --> Press Space
}
}
}
public void SetAchievementInfo(string parent, GameObject achievement, string title)
{
//this where its trying to find a gameobject-(EarnCanvas) to instantiate the unlocked achievement prefab in the Main Menu Scene
achievement.transform.SetParent(GameObject.Find(parent).transform);
achievement.transform.localScale = new Vector3(1, 1, 1);
achievement.transform.localPosition = new Vector3(0, 0, 0);
achievement.transform.GetChild(0).GetComponent<Text>().text = title;
achievement.transform.GetChild(1).GetComponent<Text>().text = achievements[title].Description;
achievement.transform.GetChild(2).GetComponent<Text>().text = achievements[title].Points.ToString();
achievement.transform.GetChild(3).GetComponent<Image>().sprite = sprites[achievements[title].SprintIndex];
}
public void ChangeCategory(GameObject button)
{
AchievementButton achievementButton = button.GetComponent<AchievementButton>();
scrollRect.content = achievementButton.achievementList.GetComponent<RectTransform>();
achievementButton.click();
activeButton.click();
activeButton = achievementButton;
}
}
Main Menu Scene Achievement Script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
public class Achievement
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string description;
public string Description
{
get { return description; }
set { description = value; }
}
private bool unlocked;
public bool Unlocked
{
get { return unlocked; }
set { unlocked = value; }
}
private int points;
public int Points
{
get { return points; }
set { points = value; }
}
private int sprintIndex;
public int SprintIndex
{
get { return sprintIndex; }
set { sprintIndex = value; }
}
private GameObject achievementRef;
private List<Achievement> dependencies = new List<Achievement>();
private string child;
public string Child
{
get { return child; }
set { child = value; }
}
public Achievement(string name,string description, int points, int sprintIndex, GameObject achievementRef)
{
this.name = name;
this.description = description;
this.unlocked = false;
this.points = points;
this.sprintIndex = sprintIndex;
this.achievementRef = achievementRef;
LoadAchievement();
}
public void AddDependency(Achievement dependency)
{
dependencies.Add(dependency);
}
public bool EarnAchievement()
{
if(!unlocked && !dependencies.Exists(x=> x.unlocked == false))
{
achievementRef.GetComponent<Image>().sprite = AchievementManager.Instance.UnlockedSprite;
SaveAchievement(true);
if(child != null)
{
AchievementManager.Instance.EarnAchievemnent(child);
}
return true;
}
return false;
}
public void SaveAchievement(bool value)
{
unlocked = value;
PlayerPrefs.SetInt(name,value? 1 : 0);
PlayerPrefs.Save();
}
public void LoadAchievement()
{
unlocked = PlayerPrefs.GetInt(name) == 1 ? true : false;
if (unlocked)
{
achievementRef.GetComponent<Image>().sprite = AchievementManager.Instance.UnlockedSprite;
}
}
}
Answer by DiegoSLTS · Aug 04, 2015 at 08:47 PM
You can't modify things in other scenes. Other scenes are not loaded, they don't exists.
What you have to do is keep a record of unlocked achievements in a file or somewhere else. When getting an achievement, update that file. When you display the achivements page, read that file and setup the page to reflect the info on the file.
If you want to pass some values from one scene to another check the DontDestroyOnLoad method, which lets you save values in an object that will remain after loading new scenes.
hi DiegoSLTS. Can u please give me an example how to keep a record of unlocked achievements in a file and how to display the achievements page, read that file and setup the page to reflect the info on the file.
at the moment i am clueless on how to do that.i have been trying to solve this problem for a week now.Whatever i tried doing is not working out.
Your help will be really appreciated
An "example" of all that is a little too much for an example. You can find a lot of info about writing to and reading from text files.
Then, after you unlock an achievement you update that file with the new unlocked achievement. You might want to assign an ID to each achievement so it's easier to work with them.
In your achievements page you can read that file to get a list of IDs of unlocked achievements. You can then get the info of each achievement using the IDs.
The screen that displays the achievements is like any other screen, just display only the info from the unlocked achievements.
I can't give you a working example, even pieces of code would be a lot of work. If you can't start with any of this maybe you should do some tutorials and try smaller things before making an achievements system, otherwise you'll likely get frustrated.
If you want a special scene for the moment you unlock an achievement store the ID of the achievement somewhere (a file, in PlayerPrefs or a game object that doesn't get destroyed when loading new scenes), load the scene, read the ID of the unlocked achievement, get the info for that achievement ID, setup the UI elements with that info (like Achievement name, description, maybe an image, etc, etc).