how to reproduce a sound effect while loading a scene - visual-studio

how to reproduce a sound effect while loading a scene?
I would like to play a sound effect when moving to the next scene, but it does not play. I already tried with method DontDestroyOnLoad but it doesn't work and I get this error: NullReferenceException: Object reference not set to an instance of an object
LevelLoader.LoadNextLevel ()
this is my script to manage sounds:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManagerScript : MonoBehaviour
{
public static AudioClip clikSound, shootSound;
static AudioSource audioScr;
// Start is called before the first frame update
void Start()
{
clikSound = Resources.Load<AudioClip> ("clik");
shootSound = Resources.Load<AudioClip>("shoot");
audioScr = GetComponent<AudioSource> ();
}
// Update is called once per frame
void Update()
{
}
public static void PlaySound(string clip)
{
switch (clip)
{
case "clik":
audioScr.PlayOneShot(clikSound);
break;
case "shoot":
audioScr.PlayOneShot(shootSound);
break;
}
}
}
and this is the script for switching between scenes:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
public Animator transition;
public float transitionTime = 1f;
static AudioSource audioScr;
public void LoadNextLevel()
{
DontDestroyOnLoad(audioScr.gameObject);
SoundManagerScript.PlaySound("shoot");
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1));
}
IEnumerator LoadLevel(int LevelIndex)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(LevelIndex);
}
}

Becasuse you're required gameobjects are destroyed. AudioSource by itself not enough. Maybe your AudioListener destroyed?
To arrange those things. I recommend you to have multiple scenes. in example, Persistent scene, MenuScene, Level1 etc, and you can put your audios in Persistent scene.
You can have more than one scene via SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive);. That's where multiple scenes gets it's power.
It may be hard but i recommend you to use Addressables for handling scenes and assets like audios.

Related

How to turn off scene transition animations

How to turn off scene transition animations?
I would like to disable the animation ONLY for the RestartGame command. so that the animation works for other commands.
Is there any script for such a thing?
this is my animation script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
public Animator transition;
public float transitionTime = 1f;
public void LoadNextLevel()
{
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1));
}
public AudioClip impact;
IEnumerator LoadLevel(int LevelIndex)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(LevelIndex);
yield return new WaitForSeconds(0.3f);
AudioSource.PlayClipAtPoint(impact, transform.position);
}
}
and this is my RestartGame command which is in another script:
public void RestartGame()
{
SceneManager.LoadScene(PlayerPrefs.GetInt("SavedScene"));
}
In your actualy code, the RestartGame method don't use de animation, but if you have an animation on your scene when this starts, you can save a PlayerPref variable inside the RestartGame method before load the scene, and then check the variable before the animation.
For example:
public void RestartGame()
{
PlayerPrefs.SetInt("isRestarting",1);
SceneManager.LoadScene(PlayerPrefs.GetInt("SavedScene"));
}
then in the start of the new scene
void Start ()
{
if(PlayerPrefs.GetInt("isRestarting",0)!=1)
{
//Do the animation
}
}
You can add another option to IEnumerator that controls the animation.
IEnumerator LoadLevel(int LevelInde, bool hasAnimation = true)
{
if (hasAnimation)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
}
SceneManager.LoadScene(LevelIndex);
yield return new WaitForSeconds(0.3f);
AudioSource.PlayClipAtPoint(impact, transform.position);
}
Now set it to true when restart and false to other cases. On LoadNextLevel:
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1, false));

How to move a cube 3 second in one direction, and next 3 seconds in oppposite direction, alternatively

I am new to unity, and trying something like below, but I can either move only in one direction, or not moving at all.
My cube is a trigger, and is not using gravity. I have checked the Kitematic box. I am trying to make the cube move to and fro, so that player have difficuly collecting it.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
public class movedanger : MonoBehaviour
{
private int mytime = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
MyMover(mytime);
}
void MyMover(int mytime)
{
if (mytime <= 3)
{
transform.Translate(Vector3.forward * Time.deltaTime);
mytime++;
}
else
{
transform.Translate(-Vector3.forward * Time.deltaTime);
mytime = 1;
}
}
}
What you are looking for is to and fro movement of an object. You can achieve this with Mathf.PingPong() function instead of using translate. I have tested it with a cube, you can set the minimum and maximum distance it should move to and the speed at which it travels. Since you want the cube to move 3 seconds in one direction at a time. You can calculate the speed as distance/time so the max distance it should travel to from the current distance and the time (3 seconds) it takes. Hope this helps.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCube : MonoBehaviour {
public float min = 2f;
public float max = 8f;
public float SpeedOfMovement = 2f;
// Start is called before the first frame update
void Start () {
}
// Update is called once per frame
void Update () {
transform.position = new Vector3 (Mathf.PingPong (Time.time * SpeedOfMovement, max - min) + min, transform.position.y, transform.position.z);
}
}
With InvokeRepeating you will call the same MoveCube method every 3 seconds.
using UnityEngine;
public class MoveDanger: MonoBehaviour
{
public bool isForward = false;
private void Start()
{
InvokeRepeating("MoveCube", 0f, 3f);
}
private void MoveCube()
{
if (isForward)
{
transform.Translate(Vector3.back);
isForward = false;
}
else
{
transform.Translate(Vector3.forward);
isForward = true;
}
}
}
Honestly the best and easiest way to do something like this, once you get used to it, is just to
Use Unity's incredibly simple animator system:
(Essentially just click "new animation" and then drag the object around as you want it animated.)
There are 100s of tutorials online explaining how to use it.
It's one of those things where once you use it and see how easy it is, you will do a "facepalm" and never bother again with other ways.
It's really "the Unity way" to achieve the goal here, dead easy and flexible.

Destroying a prefab from mouse click raycast

I want to destroy or remove a spawning prefab from my scene when the mouse clicks on the gameobject. I'm trying to use the code below from the Unity docs, however I'm presented with the following error:
object reference not set to the instance of an object.
This script is attached to my main camera. onclick crashes the game. Can anyone see where this is going wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickDestroy : MonoBehaviour
{
public GameObject destroyCube;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit(); //*
if (Physics.Raycast(ray, out hit)) //**
{
print("true" + hit.point);
}
}
}
}
Solution 1
Make sure your Camera is really tagged as MainCamera
if not click there and select MainCamera from the list
Solution 2
Get and check the main camera at game start
priavte Camera _camera;
privtae void Awake()
{
_camera = Camera.main;
if(!_camera)
{
Debug.LogError("No Camera tagged MainCamera in Scene!");
enabled = false;
}
}
Solution 3
Or instead of using Camera.main at all instead get the Camera component directly
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickDestroy : MonoBehaviour
{
public GameObject destroyCube;
privtae Camera _camera;
private void Awake()
{
_camera = GetComponent<Camera>();
}
// Update is called once per frame
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
print("true" + hit.point);
}
}
}
}

How would I change the colour of an object using 'OnMouseEnter'?

The script used to be:
function OnMouseEnter()
{
renderer.material.color = Color.grey;
}
But using that is now obsolete after an update and I have no idea what the current syntax is or how one would go about finding it out. I've searched everywhere and couldn't find an answer.
Since Unity 4.6 there is a new way of handling input events. One have to use interfaces from UnityEngine.EventSystems namespace. Look at this example:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; // dont forget this
public class SomeController : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
private bool hovered = false;
// from IPointerEnterHandler
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
// from IPointerExitHandler
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
// from IPointerClickHandler
public void OnPointerClick(PointerEventData eventData)
{
// send some event
}
}
Still, you have to add collider component to your object.

unity object reset button and slider

I want to make that on keyboard r button press reset object into position: x112 y8 z153. Object name is Sphere i can rename it.
And i want a gui slider that can change forceadder 50f in game from 0 to 500.
I am a beginner. Just finished begginer tutorials. What code do i need to get? i tried to make that reset button my self but dosent do anything to me it says in debug that its pressed but it dosent reset it. Soo i removed that code.
My code right now:
using UnityEngine;
using System.Collections;
public class ShootMeBall : MonoBehaviour
{
public float forceadder = 500f;
void OnMouseDown()
{
rigidbody.AddForce (transform.forward * forceadder);
rigidbody.useGravity = true;
}
void Awake()
{
Debug.Log ("I am awake.");
Screen.lockCursor = true;
gameObject.renderer.material.color = Color.yellow;
}
}
Here's the solution(You will need to drag the object you're moving into the scripts GameObject variable in the inspector, and the slider into the slider slot):
using UnityEngine;
using UnityEngine.UI;
using System;
public class Example : MonoBehavior
{
public GameObject go;
public Slider slider;
private float force;
void Update()
{
if(Input.GetKeyDown(KeyCode.R))
{
go.transform.position = new Vector3(112f, 8f, 153f);
}
force = (float)slider.value;
}
}
Don't forget to set the min/max values of the slider, and the value "Use whole numbers" to true if it matters.

Resources