change scene upon reaching specific score - c#

I'm very new to unity and coding so I have some doubt here. I'm current creating a multiple choice quiz game. can someone help w the coding for my question. My question here is I need to change scene upon reaching certain point. for example, when my score hits 30 I want winner page to appear and when my score hits 0 I want you lose page to appear. how?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class AnswerButtons : MonoBehaviour {
public GameObject answerAbackBlue; // blue is waiting
public GameObject answerAbackGreen; // green is correct
public GameObject answerAbackRed; // red is wrong answer
public GameObject answerBbackBlue; // blue is waiting
public GameObject answerBbackGreen; // green is correct
public GameObject answerBbackRed; // red is wrong answer
public GameObject answerCbackBlue; // blue is waiting
public GameObject answerCbackGreen; // green is correct
public GameObject answerCbackRed; // red is wrong answer
public GameObject answerDbackBlue; // blue is waiting
public GameObject answerDbackGreen; // green is correct
public GameObject answerDbackRed; // red is wrong answer
public GameObject answerA;
public GameObject answerB;
public GameObject answerC;
public GameObject answerD;
public AudioSource CorrectFX;
public AudioSource WrongFX;
public GameObject currentScore;
public int scoreValue;
void Update() {
currentScore.GetComponent<Text>().text = "SCORE: " + scoreValue;
if (scoreValue > 300)
SceneManager.LoadScene("WinnerPage");
if (scoreValue < 50)
SceneManager.LoadScene("LoserPage");
}
public void AnswerA() {
if (QuestionGenarate.actualAnswer == "A") {
answerAbackGreen.SetActive(true);
answerAbackBlue.SetActive(false);
CorrectFX.Play();
scoreValue += 10;
} else {
answerAbackRed.SetActive(true);
answerAbackBlue.SetActive(false);
WrongFX.Play();
scoreValue -= 5;
}
answerA.GetComponent<Button>().enabled = false;
answerB.GetComponent<Button>().enabled = false;
answerC.GetComponent<Button>().enabled = false;
answerD.GetComponent<Button>().enabled = false;
StartCoroutine(NextQuestion());
}
public void AnswerB() {
if (QuestionGenarate.actualAnswer == "B") {
answerBbackGreen.SetActive(true);
answerBbackBlue.SetActive(false);
CorrectFX.Play();
scoreValue += 10;
} else {
answerBbackRed.SetActive(true);
answerBbackBlue.SetActive(false);
WrongFX.Play();
scoreValue -= 5;
}
answerA.GetComponent<Button>().enabled = false;
answerB.GetComponent<Button>().enabled = false;
answerC.GetComponent<Button>().enabled = false;
answerD.GetComponent<Button>().enabled = false;
StartCoroutine(NextQuestion());
}
public void AnswerC() {
if (QuestionGenarate.actualAnswer == "C") {
answerCbackGreen.SetActive(true);
answerCbackBlue.SetActive(false);
CorrectFX.Play();
scoreValue += 10;
} else {
answerCbackRed.SetActive(true);
answerCbackBlue.SetActive(false);
WrongFX.Play();
scoreValue -= 5;
}
answerA.GetComponent<Button>().enabled = false;
answerB.GetComponent<Button>().enabled = false;
answerC.GetComponent<Button>().enabled = false;
answerD.GetComponent<Button>().enabled = false;
StartCoroutine(NextQuestion());
}
public void AnswerD() {
if (QuestionGenarate.actualAnswer == "D") {
answerDbackGreen.SetActive(true);
answerDbackBlue.SetActive(false);
CorrectFX.Play();
scoreValue += 10;
} else {
answerDbackRed.SetActive(true);
answerDbackBlue.SetActive(false);
WrongFX.Play();
scoreValue -= 5;
}
answerA.GetComponent<Button>().enabled = false;
answerB.GetComponent<Button>().enabled = false;
answerC.GetComponent<Button>().enabled = false;
answerD.GetComponent<Button>().enabled = false;
StartCoroutine(NextQuestion());
}
IEnumerator NextQuestion() {
yield return new WaitForSeconds(2);
answerAbackGreen.SetActive(false);
answerBbackGreen.SetActive(false);
answerCbackGreen.SetActive(false);
answerDbackGreen.SetActive(false);
answerAbackRed.SetActive(false);
answerBbackRed.SetActive(false);
answerCbackRed.SetActive(false);
answerDbackRed.SetActive(false);
answerAbackBlue.SetActive(false);
answerBbackBlue.SetActive(false);
answerCbackBlue.SetActive(false);
answerDbackBlue.SetActive(false);
answerA.GetComponent<Button>().enabled = true;
answerB.GetComponent<Button>().enabled = true;
answerC.GetComponent<Button>().enabled = true;
answerD.GetComponent<Button>().enabled = true;
QuestionGenarate.displayingQuestion = false;
}
}

It is hard to answer because you didn't show us the exact code where you count scores. But I will try to help you as much as I can.
Enter your code where you count scores (where you have that variable that stores scores). Now, above the code, among other "using" statements add
using UnityEngine.SceneManagement;
So you just added a scene manager into your script to have control over scenes. Now inside your Update() function add
if (score<0)
{
SceneManager.LoadScene("LoserPage"); //player lost
}
if (score>29)
{
SceneManager.LoadScene("WinnerPage"); //player won
}
In the code above score is a variable that stores your scores. Change that to whatever you have that does it. LoserPage and WinnderPage are the names of the scenes that you have created. Change their names to whatever you have to make it work. Don't forget to add your scenes in Build settings in the correct order.

Related

Unity C# how should I call the function and values from different script files?

I am new to Unity and c#. I am trying to create a dice game that rolls two dices and the total values of the two dice faces is added to the player's score. I am intending the game to continue until the player rolls two 1's or the total score reached or exceeds 50, and at the end display win or lose message and the score. I somehow managed to implement most of it. However, I can't manage to update score after rolling the dice. I tried on my own to do so, but now it's keep adding the dice rolls without break and prints win message right away.
This is the Dice code
public class Dice : MonoBehaviour
{
Rigidbody rb;
bool hasLanded;
bool thrown;
Vector3 initPosition; //Initial Position
public int diceValue;
public DiceSide[] diceSides;
void Start()
{
rb = GetComponent<Rigidbody>();
initPosition = transform.position;
rb.useGravity = false;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
RollDice();
}
if(rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
//rb.isKinematic = true;
SideValueCheck();
}
else if(rb.IsSleeping() && hasLanded && diceValue == 0)
{
RollAgain();
}
}
void RollDice()
{
if(!thrown && !hasLanded)
{
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
else if(thrown && hasLanded)
{
Reset();
}
}
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
rb.useGravity = false;
//rb.isKinematic = false;
}
void RollAgain()
{
Reset();
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
void SideValueCheck()
{
diceValue = 0;
foreach (DiceSide side in diceSides)
{
if (side.OnGround())
{
diceValue = side.sideValue;
Debug.Log(diceValue + " has been rolled!");
}
}
}
}
and this is the sides code(just in case. not really relevant to the problem I am having but I am still attaching just in case)
public class DiceSide : MonoBehaviour
{
bool onGround;
public int sideValue;
void OnTriggerStay(Collider col)
{
if(col.tag == "Ground")
{
onGround = true;
}
}
void OnTriggerExit(Collider col)
{
if(col.tag == "Ground")
{
onGround = false;
}
}
public bool OnGround()
{
return onGround;
}
}
and here's the code I am having the hardest time with...
public class Check : MonoBehaviour
{
public GameObject DiceGameObject1;
public GameObject DiceGameObject2;
private Dice dice;
private Dice dice2;
public int dicevalue1;
public int dicevalue2;
private int score;
private int totalScore;
public TMP_Text Score;
public TMP_Text TotalScore;
public TMP_Text Win;
public TMP_Text Lose;
public TMP_Text Player;
void Start()
{
totalScore = 0;
score = 0;
Win.text = "";
Lose.text = "";
}
void Awake()
{
dice = DiceGameObject1.GetComponent<Dice>();
dice2 = DiceGameObject2.GetComponent<Dice>();
}
void Update()
{
UpdateScore();
}
void SetScoreText()
{
if (dicevalue1 == 1 && dicevalue2 == 1)
{
Lose.text = "You Lose:(";
}
else if (totalScore >= 50)
{
Win.text = "You win!";
}
else
{
TotalScore.text = totalScore.ToString();
}
}
public void UpdateScore()
{
dicevalue1 = dice.diceValue;
dicevalue2 = dice2.diceValue;
score = dicevalue1 + dicevalue2;
Debug.Log(dicevalue1 + dicevalue2);
// how do I import diceValue variables from Dice class and use the values here?
totalScore += score;
SetScoreText();
}
}
So I first had problem using the diceValue variable(value) from Dice script at Check script, but I somehow managed to. I am quite not understanding how, but I tried GetComponent from Dice file to make it somehow work. I was wondering if I should do that with UpdateScore method as well, but I am stuck...
Eventually I am trying to make this a turn-based two-player game, where player take turns. So far I barely managed it to work as one player game...
Please help!!
You are calling UpdateScore() in Update(). Update() is called every frame, so when your SideValueCheck() has evaluated a dice number, the score will rise very quickly to 50. What you need is a condition to query when the dice numbers have been evaluated such that you update the score only once. You could add in your Check class a new flag bool scoreUpdated = false; and change UpdateScore() to
public void UpdateScore()
{
dicevalue1 = dice.diceValue;
dicevalue2 = dice2.diceValue;
// only update if not done already and the dice have meaningful side values
if (!scoreUpdated && dicevalue1 != 0 && dicevalue2 != 0) {
score = dicevalue1 + dicevalue2;
Debug.Log(dicevalue1 + dicevalue2);
// how do I import diceValue variables from Dice class and use the values here?
// (Edit: you did that already)
totalScore += score;
scoreUpdated = true; // track the score update
SetScoreText();
}
}
Now, if you do a new dice roll, you need to first reset the dice value of the rolling dice. Reset() would be edited to:
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
diceValue = 0; // the dice is rolling again, so no valid side value
rb.useGravity = false;
//rb.isKinematic = false;
}
and of course you need to reset the score tracking which you could do maybe in Update() of Dice class, because you located the input code there:
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
RollDice();
check.scoreUpdated = false;
}
How to get check? I dont know where you attached it, but you need to get a reference to that game object and then get the script component on it with Check check = go.GetComponent<Check>(); just like you did with the dice variables.

Why the when playing animation state it's executing the play twice in a row instead once?

The script is attached to empty gameobject
At this line i'm using the mouse left button to fire a bullet one time.
If i'm using a break point it will shot one bullet once. but if i'm not using a break point it will shot two bullets in a row one after the other.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class Shooting : MonoBehaviour
{
public CinemachineVirtualCamera cmf;
[Header("Main")]
public Rigidbody bulletPrefab;
public float launchForce = 700f;
public bool automaticFire = false;
public float bulletDestructionTime;
public bool go = false;
[Space(5)]
[Header("Slow Down")]
public float maxDrag;
public float bulletSpeed;
public bool bulletsSlowDown = false;
public bool overAllSlowdown = false;
[Range(0, 1f)]
public float slowdownAll = 1f;
public List<Transform> firePoints = new List<Transform>();
public Animator anim;
private void Start()
{
if (anim != null)
{
anim.SetBool("Shooting", true);
}
}
public void Update()
{
if (overAllSlowdown == true)
{
Time.timeScale = slowdownAll;
}
if (firePoints.Count > 0))
{
for (int i = 0; i < firePoints.Count; i++)
{
if (Input.GetMouseButton(0))
{
anim.SetTrigger("Shoot");
}
if (Input.GetMouseButton(1))
{
cmf.enabled = false;
}
if (go)
{
LaunchProjectile(firePoints[i]);
go = false;
}
}
}
}
private void LaunchProjectile(Transform firePoint)
{
Rigidbody projectileInstance = Instantiate(
bulletPrefab,
firePoint.position,
firePoint.rotation);
projectileInstance.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
cmf.enabled = true;
cmf.Follow = projectileInstance.transform;
cmf.LookAt = projectileInstance.transform;
projectileInstance.AddForce(new Vector3(0, 0, 1) * launchForce);
if (bulletsSlowDown == true)
{
if (projectileInstance != null)
{
StartCoroutine(AddDrag(maxDrag, bulletSpeed, projectileInstance));
}
}
}
IEnumerator AddDrag(float maxDrag, float bulletSpeed, Rigidbody rb)
{
if (rb != null)
{
float current_drag = 0;
while (current_drag < maxDrag)
{
current_drag += Time.deltaTime * bulletSpeed;
rb.drag = current_drag;
yield return null;
}
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.drag = 0;
}
}
}
This script is attached to my player with animator and i'm using this method to reference event i added to animation in the animator controller. when the event happens the variable bool flag go is set to true.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThrowObject : MonoBehaviour
{
public Shooting shooting;
public void ThrowEvent()
{
shooting.go = true;
}
}
This is a screenshot of the animator controller.
I added a new state name Throwing with two transitions from and to the Grounded state.
The Grounded state is playing idle animation.
In the transition from the Grounded to the Throwing i added a condition name Shoot type trigger.
In the transition from the Throwing state to the Grounded there is no any conditions.
Afaik animator triggers are stackable!
So since you call this in a for loop it might happen that it adds multiple triggers at once but each transition only consumes one at a time!
What I ended up using in combination with triggers in an animator is this script
public class AnimatorTriggerResetter : StateMachineBehaviour
{
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
foreach(var p in animator.parameters)
{
if (p.type == AnimatorControllerParameterType.Trigger)
{
animator.ResetTrigger(p.name);
}
}
}
}
attach this to no specific state at all but directly to the Basic layer of your AnimatorController itself => It is called for each and every state that is entered => resets all existing triggers.
In your specific case though, why not rather pull the general calls out of the loop and rather make it
if (firePoints.Count > 0 && go)
{
if (Input.GetMouseButton(0))
{
anim.SetTrigger("Shoot");
}
if (Input.GetMouseButton(1))
{
cmf.enabled = false;
}
for (int i = 0; i < firePoints.Count; i++)
{
LaunchProjectile(firePoints[i]);
}
go = false;
}

How can I disable the audio for a specific scene?

I'm using this line :
AudioListener.pause = true;
The problem is that I have two scenes loaded, I'm loading another scene with the
LoadSceneMode.Additive
Then the audio pausing is effecting both scenes.
This is my full code for pausing/resuming the game. Index 0 is the Main Menu scene and index 1 is the Game scene. I have two scenes the Main Menu and the Game.
When I hit the escape key to the main menu I want to pause the audio in the Game scene and then when hitting the escape ley again back to the game I want to resume the audio in the game scene.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class BackToMainMenu : MonoBehaviour
{
public GameObject[] objsToDisable;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (Time.timeScale == 0)
{
DisableEnableUiTexts(true);
AudioListener.pause = false;
SceneManager.UnloadSceneAsync(0);
Cursor.visible = false;
Time.timeScale = 1;
}
else
{
Time.timeScale = 0;
MenuController.LoadSceneForSavedGame = false;
AudioListener.pause = true;
SceneManager.LoadScene(0, LoadSceneMode.Additive);
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
Cursor.visible = true;
}
}
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
DisableEnableUiTexts(false);
}
private void DisableEnableUiTexts(bool enabled)
{
foreach (GameObject go in objsToDisable)
{
if (go.name == "Cameras")
{
foreach(Transform child in go.transform)
{
if(child.name == "Main Camera")
{
if (enabled == false)
{
child.GetComponent<Camera>().enabled = false;
}
else
{
child.GetComponent<Camera>().enabled = true;
}
}
}
}
else
{
go.SetActive(enabled);
}
}
}
}
As mentioned one possibility is to use AudioSource.mute but of course you'd have to use it on all sources of according scene.
When you already know the index you can do e.g.
var scene = SceneManager.GetSceneAtBuildIndex(1);
if(scene.isValid)
{
// Iterate through the scene Hierarchy and get all sources (also inactive/disabled ones)
var audioSources = new List<AudioSource>();
foreach (var root in scene.GetRootGameObjects())
{
audioSources.AddRange(root.GetComponentsInChildren<AudioSource>(true));
}
foreach(var source in audioSources)
{
source.mute = !enabled;
//Or
source.pause = !enabled;
}
}
Alternatively you could use the AudioMixer which I'd say is more convenient for this.
Here would simply but all the sources into a certain AudioMixerGroup and make the volume an exposed parameter.
Then you can simply silent that entire group by using SetFloat.
Btw be very careful with naming your method parameters like already existing fields/properties! Yes, they will be shadowed anyway but it only leads to confusion for you and other readers. There already is Behavior.enabled which MonoBehavior and thus your class derives from.
Can you try using audio_source_name.mute = true &/or audio_source_name.Stop()?
Example:
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (Time.timeScale == 0)
{
DisableEnableUiTexts(true);
// AudioListener.pause = true;
audio_source_name.mute = false; // <--------
SceneManager.UnloadSceneAsync(0);
Cursor.visible = false;
Time.timeScale = 1;
}
else
{
Time.timeScale = 0;
MenuController.LoadSceneForSavedGame = false;
// AudioListener.pause = true;
audio_source_name.mute = false; // <--------
SceneManager.LoadScene(0, LoadSceneMode.Additive);
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
Cursor.visible = true;
}
}
}
You could also do it this way (Source: Unity - Scripting API: AudioSource.mute):
// Mutes-Unmutes the sound from this object each time the user presses space.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
AudioSource audioSource;
void Start()
{
audioSource = GetComponent<AudioSource>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
audioSource.mute = !audioSource.mute;
}
}

Instantiate inside nested for loops does not do what it is intended to

I have been working on a minecraft clone game in Unity 2017.3 and C# and i started all right but when i worked on the super flat world generation system there began a problem. Inside the World mono behaviour, in the Generate void, there are three nested for loops which should generate a new dirt block on every possible position between 0 and 5
But it only makes a line of dirt block stretching along the Z axis.
Here is the code for PlaceableItem(attached to dirtPrefab) and World(attached to World)
Placeable Item class
using UnityEngine;
using System.Collections;
public class PlaceableItem : MonoBehaviour
{
public string nameInInventory = "Unnamed Block";
public int maxStack = 64;
public bool destructible = true;
public bool explodesOnX = false;
public bool abidesGravity = false;
public bool isContainer = false;
public bool canBeSleptOn = false;
public bool dropsSelf = false;
private Rigidbody rb;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (abidesGravity) {
rb.useGravity = true;
} else {
rb.useGravity = false;
}
}
private void OnDestroy()
{
if (dropsSelf) {
//Drop this gameObject
}
}
public void Explode() {
if (!explodesOnX)
return;
}
public void OnMouseDown()
{
if (isContainer && !canBeSleptOn) {
//Open the container inventory
} else if (canBeSleptOn && !isContainer) {
//Make the character sleep on the item
}
}
private void OnMouseOver()
{
if (Input.GetMouseButtonDown(1) && destructible) {
Destroy(gameObject);
}
}
}
World class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class World : MonoBehaviour {
public GameObject dirtPrefab;
public bool generateAutomatically = true;
// Use this for initialization
void Start () {
if (generateAutomatically) {
Generate();
}
}
// Update is called once per frame
void Update () {
}
void Generate() {
for (int x = 0; x <= 5; x++) {
for (int y = 0; y <= 5; y++) {
for (int z = 0; z <= 5; z++) {
Instantiate(dirtPrefab, new Vector3(x, y, z), Quaternion.identity);
}
}
}
}
void RemoveAllBlocks() {
foreach (PlaceableItem placeableItem in GetComponentsInChildren<PlaceableItem>()) {
Destroy(placeableItem.gameObject);
}
}
}
Thanks in advance, fellow developers!
Hope this is not a stupid question!
[SOLVED] I realised i had a recttransform somehow attached to my dirt prefab. Removing it and adding a transform instead helped.

What is missing reference exception in c#?

I am making a game in unity 3d and I have missing reference exception.The error
don't appear in my script editor so I don't know what is this error related to.
Here is the Gamemanager script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gamemanager : MonoBehaviour
{
public List<Character> Characters = new List<Character>();
public List <Item> AllItems = new List<Item> ();
bool ShowCharWheel;
public int SelectedCharacter;
int LastCharacter;
public static Gamemanager Instance;
public bool CanShowSwitch = true;
public Character CurrentCharacter;
void Awake()
{
foreach (Character c in Characters)
{
c.Instance = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
c.Instance.GetComponent<PlayerController> ().LocalCharacter = c;
}
ChangeCharacterStart(Characters[PlayerPrefs.GetInt("SelectedChar")]);
}
// Use this for initialization
void Start()
{
}
void ChangeCharacterStart(Character c)
{
LastCharacter = SelectedCharacter;
SelectedCharacter = Characters.IndexOf(c);
CurrentCharacter = c;
Characters [LastCharacter].Instance.GetComponent<PlayerController> ().CanPlay = false;
Characters[SelectedCharacter].Instance.GetComponent<PlayerController>().CanPlay = true;
Camera.main.GetComponent<SmoothFollow>().target = Characters[SelectedCharacter].Instance.transform;
PlayerPrefs.SetInt("SelectedChar", SelectedCharacter);
}
// Update is called once per frame
void Update()
{
if (CanShowSwitch) {
if (Input.GetKey (KeyCode.C)) {
ShowCharWheel = true;
} else if (Input.GetKey (KeyCode.V)) {
ShowCharWheel = false;
}
}
}
void ChangeCharacter(Character c)
{
c.Instance.GetComponent<AI> ().DoneHome = false;
if (Vector3.Distance (Characters [SelectedCharacter].Instance.transform.position, c.Instance.transform.position) > 10) {
sequencemanager.Instance.StartCoroutine ("DoCharSwitch", c);
CanShowSwitch = false;
LastCharacter = SelectedCharacter;
SelectedCharacter = Characters.IndexOf (c);
CurrentCharacter = c;
Characters [LastCharacter].Instance.GetComponent<PlayerController> ().CanPlay = false;
Characters [SelectedCharacter].Instance.GetComponent<PlayerController> ().CanPlay = true;
PlayerPrefs.SetInt ("SelectedChar", SelectedCharacter);
} else {
LastCharacter = SelectedCharacter;
SelectedCharacter = Characters.IndexOf(c);
CurrentCharacter = c;
Characters [LastCharacter].Instance.GetComponent<PlayerController> ().CanPlay = false;
Characters [SelectedCharacter].Instance.GetComponent<PlayerController> ().CanPlay = true;
PlayerPrefs.SetInt ("SelectedChar", SelectedCharacter);
Camera.main.GetComponent<SmoothFollow> ().target = Characters [SelectedCharacter].Instance.transform;
}
}
void OnGUI()
{
if (ShowCharWheel)
{
GUILayout.BeginArea(new Rect(Screen.width - 64, Screen.height - 256, 64, 208), GUIContent.none, "box");
foreach (Character c in Characters)
{
if (GUILayout.Button(c.Icon, GUILayout.Width(64), GUILayout.Height(64)))
{
ChangeCharacterStart(c);
}
}
GUILayout.EndArea();
}
}
}
[System.Serializable]
public class Character
{
public string Name;
public Texture2D Icon;
public GameObject PlayerPrefab;
public GameObject Instance;
public Transform HomeSpawn;
}
[System.Serializable]
public class Item
{
public string Name;
public Texture2D Icon;
public ItemInstance InstancePrefab;
}
The error is on line
c.Instance = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
This is my editor image with error.The main problem is when I start the game it destroy the gamemanager script.
And another important thing.I migrated this project.I had to reinstall windows.Before that the error didn't appeared.And now it do.And I am sure I took the whole pro
I just a junior developer without much of experience but your code looks messy. May be there is more null refs errors so most probably you did not assign/ save to prefab something or an object that you want to use is destroyed. Check [how to debug with monobehaviour] (https://unity3d.com/learn/tutorials/topics/scripting/monodevelops-debugger). So put some break point, and go through them one by one. When break point activated you can hover over variable and check if it has some value. I strongly suggest you make any assignment on separate line like this:
c.Instance = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
should be like this:
GameObject newGameObject = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
c.Instance = newGameObject;
In that case you can check if you really have newGameObject and so on.

Categories