How to destroy a game object marked "DontDestroyOnLoad" when a new scene loads? - unity3d

So I created a music player to play music through all my menu and story scenes without interrupting, but then in my game scene I want to delete that music. How can destroy the playing music when my game scene loads?
Here is my music script:
#pragma strict
var offsetY : float = 40;
var sizeX : float = 100;
var sizeY : float = 40;
var musicPrefab : Transform;
function Start () {
if (!GameObject.FindGameObjectWithTag("MM")) {
var mManager = Instantiate (musicPrefab, transform.position, Quaternion.identity);
mManager.name = musicPrefab.name;
DontDestroyOnLoad (mManager);
}
}

Just call destroy on it directly:
Destroy(mManager);
DontDestroyOnLoad only protects the object from being destroyed when loading a new scene.

I created a script called Destroyer.js and attached it to the camera in the scene where I didn't want music. Then in that script I added this code, and it doesn't play anymore.
function Start() {
Destroy(gameObject.Find("_MMusic"));
}

You can destroy the object by calling Destroy(objectname) directy like mentioned above by Almo. You could place it in the same function call which is responsible for the change to the scene where you don't want the music to be playing.

I had the same issue so I tried Destroy(gameObject); as mentioned in answers above but It didn't work for me.
So I tried SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive); and it worked for me. Read official docs here.

Maybe it's a little bit late but I use this script and it's works great:
GameObject player = GameObject.FindGameObjectWithTag("Player");
if(player)
Destroy(player);

To achieve this, simply put Destroy(gameObject) in the Update method.

Related

Particle System is not Playing in Unity

I made a simple spaceship that has a particlesystem. When I press "space" button, spaceship should fly and particle system should instantiate and play. But it's not playing. It seems in hierarchy as clone but not playing.
As you see, particle effect is instantiating but not playing. It should play at bottom of spaceship
Those are codes
void FlyShip()
{
if (Input.GetKey(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpForce);
if (!takeoffSound.isPlaying)
{
// _rocketJetParticle is gameobject.
_rocketJetParticle = Instantiate(rocketJetParticle, new Vector3(transform.position.x, transform.position.y - 4, transform.position.z), transform.rotation);
takeoffSound.Play();
}
}
else
{
//Destroy(_rocketJetParticle);
takeoffSound.Stop();
}
}
make sure your particle is assign to the script and use the debug mode to check the particle system is working or not
rocketJetParticle = Instantiate(Vector3);
ParticleSystem ps =rocketJetPartivle.GetComponent<ParticleSystem>();
ps.Play();
Instantiate the gameObject that contains ParticleSystem. and named that 'rocketJetParticle'
'get ParticleSystem from 'rocketJetParticle' gameObject and named that ps.
play particleSystem that called ps.
and also, I would suggest using gameObject.setActive or enabled
instead of using Instantiate&&Destroy for better performance.

Unity, Volume Slider Problem When Changing Scence

im making a game that have a empty game object for audio source (music) and the script for that music, and i also have a volume slider in diffrent object .
The Script :
float musicVolume = 1f;
private void Update()
{
mainMusic.volume = musicVolume;
}
// Slider will Trigger This
public void SetVolume(float volume)
{
musicVolume = volume;
}
i use that way because it's simple and easy since i will only use 1 music.
With that i can control my music volume correctly, but the problem is when i go to another scence and go back, the slider seems don't do anything so my music volume won't cahange.
So how to i fix it?
Sorry for my bad english. Thanks...
First Of All you can remove Volume initialize From Update Method
Your Problem
When Set Volume From Slider It's Okk set Success Like 0.5f
But After Call Update Methos So Your Volume Set 1f from musicVolume variable
Solution
remove Volume initialize From Update Method
My guess is that the object having the AudioSource is destroied as soon as a new scene is loaded.
Go with this in its script in order to avoid its deallocation when you change the scene:
void Awake () {
DontDestroyOnLoad(this);
}
As a side note, your Update could be avoided because setting the volume at each frame is not optimal.
why not simply
public void SetVolume(float volume)
{
mainMusic.volume = volume;
}
without the Update in between? Do the work only when it is needed!
To your question: it sounds like you are using DontDestroyOnLoad on the mainMusic and loosing the reference due to destroying the duplicate after loading the scene. You should get an exception about that!
However, simply search for the AudioSource in your script like
private void Start()
{
mainMusic = FindObjectOfType<AudioSource>();
}
public void SetVolume(...){ ... }
or if there are multiple AudioSources in your Scene give the main source an explicit type like e.g.
public MainAudioSource : AudioSource
{
// Does nothing but now you can explicitely search for it
}
and then in the other script do
private void Start()
{
mainMusic = FindObjectOfType<MainAudioSource>();
}

Unity: GameObject always at center regardless of position changes

I am working on a 2D game and have created a game object using C# script as below. I also set my camera to orthogonal and have adjusted my sprite based on the width of the screen. Regardless of the position I set, the object is always at the center of the screen. How can I solve this?
using UnityEngine;
using System.Collections;
public class TestingPositions : MonoBehaviour {
GameObject hero;
Sprite heroSprite;
Vector3 heroPosition;
// Use this for initialization
void Start () {
hero = new GameObject ();
Instantiate (hero, heroPosition, Quaternion.identity);
Camera camera = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<Camera> ();
heroPosition = camera.ScreenToWorldPoint(new Vector3(Screen.width/4, Screen.height/4, camera.nearClipPlane));
heroSprite = Resources.Load <Sprite> ("Sprites/heroImage");
SpriteRenderer renderer = hero.AddComponent<SpriteRenderer>(); renderer.sprite = heroSprite;
}
}
when you use Instantiate you have to use it on
an existing model.
Instantiate means "duplicate this model" or "copy this model", or "make a new one, using this model as an example".
What you are doing, is creating a brand new empty "hero" game object - and then "instantiating" it. That is meaningless and does nothing.
What you must do whenever you want to use "Instantiate" is this:
public GameObject modelPerson;
Note that the name must be "modelSomething".
first put that in your code. LOOK at the Inspector. MAKE your actual model hero (or whatever it is)
Sit it somewhere off camera where it is not seen.
Now, drag that thing to the "modelPerson" slot in the Inspector.
If you are not familiar with the basics of using Inspector-dragging in Unity, review basic Unity tutorials https://unity3d.com/learn/tutorials/topics/scripting
Next in your code, perhaps in Start, try this
GameObject newHero = Instantiate( modelPerson );
newHero.transform.position = .. whatever you want
newHero.transform.rotation = .. whatever you want
newHero.name = "Dynamically created";
newHero.transform.parent = .. whatever you want
once you understand these basics, there is very much more to learn about Instantiate. You can ask that in separate questions. Good luck.
Your need to save the reference to your gameObject that is created with Instantiate, because Instantiate makes a copy not modifies the original.
To modify a gameobjects position after instantiation, you need to use gameobject.transform.position = newPosition; To modify it before instantiation, you would need to do the "heroPosition" line before using heroPosition in Instantiate.
So like this:
using UnityEngine;
using System.Collections;
public class TestingPositions : MonoBehaviour
{
GameObject hero;
SpriteRenderer heroSprite;
// Use this for initialization
void Start()
{
Camera camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
//Save the reference to the instantiated object into a variable
//Since you are creating an object from scratch, you don't even need Instantiate, which means copy - not create.
hero = new GameObject();
//Set its position
hero.transform.position = camera.ScreenToWorldPoint(new Vector3(Screen.width / 4, Screen.height / 4, camera.nearClipPlane));
//Set its rotation
hero.transform.rotation = Quaternion.identity;
//Add sprite renderer, save the reference
heroSprite = hero.AddComponent<SpriteRenderer>();
//Assign the sprite
heroSprite.sprite = Resources.Load<Sprite>("Sprites/heroImage");
}
}

Set transform from another GameObject's script

I'm trying to make a script to set an object when is being instantiated. The problem is, I don't clearly know how to do it. I have this function..
function spawnPlayer()
{
var CameraScript = GameObject.Find(PlayerPrefab.name).GetComponent("Camera Control");
Network.Instantiate(PlayerPrefab, spawnObject.position, Quaternion.identity, 0);
}
Where PlayerPrefab is going to be the Prefab that's going to be instantiated. When this happens, I need to set the instantiated gameObject on another GameObject which is camera and has a script called "Camera Control" and inside there's a transform Target which I'm trying to set. How to do this?
The code you posted can't be right. You are using the PlayerPrefab's name to to find the Camera Control script attached to the camera? By that logic then the moment you instantiate PlayerPrefab, on the second line, you will have a second camera.
I think what you want to do is this: Instantiate the player prefab and make the camera point to the player.
So I am assuming the CameraControl script is created. You need the following before we start to code.
Attach CameraControl script to the camera in the scene.
Make sure the Player script is attached to the Player Prefab.
Have a third script that will instantiate the PlayerPrefab. I will call it Instantiator. Attach it to an empty GameObject in the scene, think of it as the world GameObject. We will call it World.
Make sure the Instantiator script is attached to the World GameObject and that it is pointing to the PlayerPrefab.
Code: Instantiator
The Instantiator script will spawn and create things we will use in the scene.
#pragma strict
var PlayerPrefab : GameObject;
function Start ()
{
// You can add position and rotation to the function call if you like.
var p = Instantiate(PlayerPrefab) as GameObject;
// Find the camera script and point to Player's transform.
Camera.main.GetComponent("CameraControl").SendMessage("setTarget", p.transform);
}
Notice I used the fact that the MainCamera in the scene is marked by Unity for you so it is easy to find.
Code: CameraControl
The CameraControl will have the logic to follow the Player as you see fit. Notice that target will point to what the camera will focus on. Of course following the Player around you will have to write.
var target : Transform;
function setTarget(t : Transform)
{
target = t;
}
I just taught myself a bit of JavaScript. I had never used it before.
I found my solution.
What I was meaning on my question was to set my camera's script the transform of the instantiated object.
I did not have to make many empty objects with scripts value of each object; it took me hours to find it because I did not know how unity handles the scripts objects calls.
This is how I made it:
var PlayerPrefab : GameObject;
var spawnObject : Transform;
private var MainCamera : GameObject;
function spawnPlayer()
{
var player = Instantiate(PlayerPrefab, spawnObject.position, Quaternion.identity);
MainCamera = GameObject.Find("MainCamera");
player.name = "Ball";
if(MainCamera)
{
MainCamera.GetComponent.<CameraControl>().target = player.transform;
Debug.Log("Succeed.");
}
}
Like this, my camera will have the transform properties of the new instantiated object automatically.

AudioSource error

I am following directions out of a book to put together a simple FPS. However, I am not getting the same results as the book says I should.
The last thing I have been trying to do is add a sound to my "gun", so that this sound clip "pop.wav" plays when you fire.
Here is the working code before I took the steps to add the sound.
var projectile : Rigidbody;
var speed = 50;
function Update () {
if(Input.GetButtonDown("Fire1"))
{
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position +
Vector3(0,-1,0), transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection(Vector3(0,0,speed));
Physics.IgnoreCollision(instantiatedProjectile.collider, transform.root.collider);
}
}
So I did what the book said, and imported Pop.wav. Then it said to add two simple lines of code to the script.
var projectile : Rigidbody;
var speed = 50;
var pop : AudioClip;
function Update () {
if(Input.GetButtonDown("Fire1"))
{
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position +
Vector3(0,-1,0), transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection(Vector3(0,0,speed));
Physics.IgnoreCollision(instantiatedProjectile.collider, transform.root.collider);
audio.Play(pop);
}
}
Assets/FireProjectile.js(12,27): BCE0023: No appropriate version of 'UnityEngine.AudioSource.Play' for the argument list '(UnityEngine.AudioClip)' was found.
I would really appreciate some help on this.
I don't see you assigning the file to be played to the audio clip... something like
pop.clip = ...
A brief search on unity 3d mentions assigning the clip, and checking that it's ready to play.
Actually, you have overlooked something outside the script. You do in fact need to add an audio listener and an audio source in the scene. Then, you'll be able to hear the sound.
The reason for this is that unity allows for 3D sound, i.e. sound which has a location in 3D space, and will increase in volume if you go near it. The Audio Source is obviously where the sound is comming from, and Audio Listener is where your ears are, so to speak. Usually the audio listener is on your character. But you can rig it so that it is on any object, but then that object would have to get near the audio source, and not the character, which doesn't make any sense at all.
However, remember to only have ONE audio LISTENER at a time. Infinite audio SOURCES are allowed. :)
You need to assign your variable. It would be something like
pop.clip = (anything here)
You must use audio.PlayOneShot(pop) instead of audio.Play().
But if you want to use audio.Play(); you should know that it doesn't take AudioClip as argument.
Use following code and make sure you assign pop to Audio Clip property of Audio Source component by dragging pop sound from Project to inspector. audio.Play() uses default assigned Audio Clip in AudioSource.
var projectile : Rigidbody;
var speed = 50;
function Update () {
if(Input.GetButtonDown("Fire1"))
{
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position +
Vector3(0,-1,0), transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection(Vector3(0,0,speed));
Physics.IgnoreCollision(instantiatedProjectile.collider, transform.root.collider);
audio.Play();
}
}
#script RequireComponent(AudioSource)
Based on the Unity documentation (I've never used Unity so I can't be sure this is correct) I find that you probably want to do something like this.
var projectile : Rigidbody;
var speed = 50;
var pop : AudioClip;
...
if(Input.GetButtonDown("Fire1"))
{
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position +
Vector3(0,-1,0), transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection(Vector3(0,0,speed));
Physics.IgnoreCollision(instantiatedProjectile.collider, transform.root.collider);
audio.PlayOneShot(pop);
}
This is actually all you have to do. Assign a variable, and then tell it to play in the update function, whenever Fire1 is pressed, which is LMB by default.
PlayOneShot means the sound won't loop or anything, which I assume you want for gunshots or similar. Within the parentheses you simply name the sound you want to play.