I am currently making a mobile game in Unity3D. I want it so that when a ball with the tag 'Damage' is collided with, it will change the material of a damage indicator at the top of the screen. Is there an easy way to do this?
Thank you in advance.
You would typically put something like "damage indicator" in your "GameManager" and a GameManager is usually a singleton. It means you on time of collision, you can check the collider tag, if it's "Damage" then you call a function in your GameManager to change the material of your "damage indicator". Something like this:
public class ExampleClass : MonoBehaviour
{
....
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Damage")
GameManager.instance.DamageDone();
}
}
GameManager:
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public Material damageMat;
public Renderer damageIndicatorRenderer;
....
void DamageDone()
{
damageIndicatorRenderer.material = damageMat;
}
}
Related
In my game I have coins, in my coin script I have an OnDestroy() function but I get this error "NullReferenceException: Object reference not set to an instance of an object
coinscript.OnDestroy () (at Assets/Scrips/coinscript.cs:9)"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class coinscript : MonoBehaviour
{ public gamemanager GameManager;
void OnDestroy()
{
GameManager.plusScore(10);// FindObjectOfType<gamemanager>().pluseScore(10); gets the same error
}
}
fixed it thanks to help from KiynL
using System.Collections.Generic;
using UnityEngine;
public class coinscript : MonoBehaviour
{ public gamemanager GameManager;
bool destroyed = false;
void OnDestroy()
{
if (destroyed = false)
{
GameManager.plusScore(10);
destroyed = true;
}
}
}
This is because the object may be destroyed multiple times in one frame. Fix it.
void OnDestroy()
{
if (gameObject) GameManager.plusScore(10);
}
You need to go into the properties of whatever object you attached that script to, and assign Game Manager an object that has a gamemanager script attached to it.
As ted said its probably because you haven't set GameManager from inspector. you need to drag a gameObject that has gamemanager component on it.
but I recommand making plusScore function static and calling it without an object, if you make it statis you also have to make varible that stores score static as well, some thing like this:
public class gamemanager : MonoBehaviour
{
static int Score = 0;
public static void plusScore(int score)
{
Score += score;
}
}
then calling it like this:
gamemanager.plusScore(10);
When I enter a collider for a certain game object I would like to play a different sound according to whether its the first time entering the sphere collider or the 2nd or 3rd time. Can this all be written in the same script?
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
//attach in inspector or make private and get with code in the Start()
public AudioSource audioSource1;
public AudioSource audioSource2;
void Start() {
// get audioSources optional
}
int colCounter = 0;
void OnCollisionEnter(Collision collision) {
colCounter++;
if (colCounter == 1)
audioSource1.Play();
else
audioSource2.Play();
}
}
I am new and learning coding. How do I change a sprite from another game scene through a buttoned code.
using UnityEngine;
public class PlayerChoice : MonoBehaviour
{
public GameObject plo;
public Sprite boy;
public Sprite girl;
public void Boy()
{
plo.GetComponent<SpriteRenderer>().sprite = boy;
}
public void Girl()
{
plo.GetComponent<SpriteRenderer>().sprite = girl;
}
}
You actually can't do it the way you are trying.
This is a bit tricky for a beginner and you would have to read a bit to get behind it.
This is some starting point where you can dive in:
You would have to to make a gameobject that lives between scenes with
DontDestroyOnLoad(targetGameObject);
see: https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
On this gameobject you could have a script which holds all variables that are needed in the next scene.
When scenes are switched access that object and get your values;
I was getting Missing Reference Exception within my Audio Source when I change my game scene and again move back to the same scene.
Before I change the main menu scene, it is working fine but after changing and moving back to the main menu scene, it is started showing this exception.
Here is the code I have written for AudioManager:
public class AudioManager : MonoBehaviour
{
static AudioManager instance;
//
[SerializeField] AudioClip buttonClickClip;
[SerializeField] AudioSource myAudioSource;
private void Awake()
{
instance = this;
}
public static AudioManager Instance
{
get
{
return instance;
}
}
public void PlayButtonClickSound()
{
if (GameManager.Instance.IsEnableSounds)
myAudioSource.PlayOneShot(buttonClickClip);
}
}
Here is the code that I wrote for DontDestroyOnLoad purpose:
public class DontDetroyOnLoad : MonoBehaviour
{
private static bool created = false;
void Awake()
{
if (!created)
{
DontDestroyOnLoad(this.gameObject);
created = true;
}
else
Destroy(this.gameObject);
}
}
Now please give me some suggestion to solve this problem.
You are referencing the AudioManager that you are destroying in the script that is trying to play the sound.
Think of it this way. You have
AudioManager A - DontDestroyOnLoad
AudioManager B - That gets destroyed cause A exists
In your scripts you are referencing AudioManager A when you first start up. Then when you leave the Scene and return you are now referencing AudioManager B, which got destroyed because A exists. All you need to do is always reference AudioManager A, not B.
Appreciate the answer from #jfish. That clearly describes the situation.
Here let me elaborate mine, on the example of using DontDestroyOnLoad
[SerializeField] AudioSource audioSource;
void Awake()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("music");
if (objs.Length > 1)
{
Destroy(this.gameObject);
//Here, get the previous audioSource from previous game object
audioSource = objs[0].GetComponent<AudioSource>();
}
DontDestroyOnLoad(this.gameObject);
}
On first load, it gets from Editor.
Subsequently, it gets from previous game object.
I have a baseclass that inherits from Monobehaviour. How do i cast my monobehaviour to the base class when finding it in the hierarchy?
GameManager : MonoBehaviour {
public MonoBaseClass MyThing;
void Awake() {
MyThing = GameObject.Find("Child") as MonoBaseClass;
}
}
MonoBaseClass : MonoBehaviour {
public void BaseClassMethod() {}
}
GameObject.Find returns a GameObject, a MonoBehaviour is a component of a GameObject. That's why you can't cast the GameObject to the MonoBaseClass.
Instead you have to get a reference of the GameObject and then get the Component:
GameObject childGameObject = GameObject.Find("Child");
MyThing = childGameObject.GetComponent<MonoBaseClass>();
You need to use FindObjectOfType<MonoBaseClass>(), i.e.:
void Awake() {
MyThing = FindObjectOfType<MonoBaseClass>();
}
Problem with both Find and FindObjectOfType is: They are quite slow and you will get the first hit from the entire scene.
If the Component you are looking for is on a Gameobject which is a child of the current GameObject (which seems the case) than you can just use:
MyThing = GetComponentInChildren<MonoBaseClass>();
https://docs.unity3d.com/ScriptReference/Component.GetComponentInChildren.html
Of course this will anyway still only get the first hit. For more use an array and GetComponentsInChildren<T>()