How do I go about muting a specific audio source in Unity? - c#

So I'm trying to mute a specific audio source once my death menu pops up ingame. I tried with:
public void toggleEndMenu(float score)
{
GameObject jumpGameObject = GameObject.Find("Jump");
if (jumpGameObject != null)
{
AudioSource jumpAudio = jumpGameObject.GetComponent<AudioSource>();
if (jumpAudio != null)
{
jumpAudio.mute = true;
}
}
gameObject.SetActive(true);
scoreText.text = ((int)score).ToString();
isShown = true;
This did not work the audiosource does not get muted, maybe it cannot find the gameobject or something?

Related

NativeGallery work on Unity Editor but doesn't work on Android device?

I am implementing an user reporting function, trying to give user the ability to post picture to their report. Here the code:
public class ResponseImageHandler : MonoBehaviour
{
[SerializeField] GameObject[] imgHolder;
[SerializeField] Texture2D defaultTexture;
[SerializeField] TMP_Text imgIndicator;
Texture2D tempTexture;
int curIdx = 0;
void Start()
{
for (int i = 0; i < 4; i++)
{
imgHolder[i].transform.GetChild(0).gameObject.AddComponent<ButtonIndex>();
imgHolder[i].transform.GetChild(0).gameObject.GetComponent<ButtonIndex>().Init(i + 1);
imgHolder[i].GetComponent<Button>().interactable = true;
imgHolder[i].GetComponent<Button>().onClick.AddListener(ChoosePictureOnClick);
}
}
void ChoosePictureOnClick()
{
ChoosePicture(SystemInfo.maxTextureSize);
}
void ChoosePicture(int maxSize)
{
NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
{
if (path != null)
{
tempTexture = NativeGallery.LoadImageAtPath(path, maxSize, false);
if (tempTexture == null)
{
Debug.Log($"cant load image from path: {path}");
return;
}
else
{
imgHolder[curIdx].GetComponent<Button>().interactable = false;
imgHolder[curIdx].transform.GetChild(0).gameObject.SetActive(true);
imgHolder[curIdx].GetComponent<RawImage>().texture = tempTexture;
if (curIdx < 3)
{
curIdx++;
}
imgIndicator.text = $"{curIdx}/4";
}
}
});
imgHolder[curIdx].SetActive(true);
}
In Unity editor, i was able to insert all 3 slot with picture and an empty slot
Unity Editor
But in Android Studio Emulator and also on android device, i can only insert one picture and then no further slot appear to insert more picture
Android Studio Emulator
I have no idea what happen can any one give me an explanation? And how to fix the problem?
I'm using Unity 2021.3.5f1 version and NativeGallery asset to get picture from device.

Using the same script for dealing with different triggers

I have a scene with multiple triggers and a Player with collider. My idea is to have one script to deal with all interactions between triggers and Player collider. I thought that using the same script to different GameObjects would be enough but this thing doesn't work properly. While working with one trigger I need to change one GameObject attached to this trigger but the other GameObjects with this script are changing as well.
One more detail about script is that I have two types of triggers: one is for GameObjects that need some input from user, some doesn't need it. I check it by checking two fields firstChoiceText and secondChoiceText. And if they are empty, the interaction with GameObject doesn't need any choice from the player. Otherwise, I show a plane with two option and change the text of this options using firstChoiceTextfield and secondChoiceTextfield.
So the main idea of script is that when the Player enter the trigger the script activates E key of keyboard. And if we press the E button and if this interaction wasn't done yet, we go further. We check the type of trigger and if we need to make a choice, we activate so called choiceMode of PlayerScript. PlayerScript is just a script for movements of the player, and we need choiceMode just to use W and S keys to select the choice. We make our choice and return to usual movement of the player. If we don't need to make a choice we just do some action and mark the trigger as isDone.
Everything works great with one trigger but when I use several triggers and GameObjects with InteractionScript, all this triggers are mixed up. While working with one trigger I accidentally change the other script. And I don't quite understand how to separate this scripts from each other.
Can anybody give me some piece of advice?
using UnityEngine;
using UnityEngine.UI;
public class InteractionScript : MonoBehaviour
{
[SerializeField]
private GameObject buttonE;
[SerializeField]
private GameObject choiceMenu;
[SerializeField]
private PlayerScript ps;
private int choiceNum = 0;
[SerializeField]
private Transform choicePoint;
[SerializeField]
private Text firstChoiceTextfield;
[SerializeField]
private Text secondChoiceTextfield;
[SerializeField]
private string firstChoiceText;
[SerializeField]
private string secondChoiceText;
[SerializeField]
private bool enteredMe;
[SerializeField]
private bool isDone;
void OnTriggerEnter2D() {
if (!isDone) {
enteredMe = true;
buttonE.SetActive(true);
Debug.Log("++");
}
}
void OnTriggerExit2D() {
if (!isDone) {
buttonE.SetActive(false);
enteredMe = false;
}
}
void Update() {
if (!isDone) {
if (Input.GetKeyDown(KeyCode.E) && buttonE.activeSelf && enteredMe) {
if (firstChoiceText != "" && secondChoiceText != "") {
choiceMenu.SetActive(true);
buttonE.SetActive(false);
ps.choiceMode = true;
Debug.Log("with choice");
} else {
Debug.Log("without choice");
//Action
buttonE.SetActive(false);
isDone = true;
}
}
}
if (ps.choiceMode) {
firstChoiceTextfield.text = firstChoiceText;
secondChoiceTextfield.text = secondChoiceText;
if (Input.GetKeyDown(KeyCode.W)) {
choiceNum += 1;
}
if (Input.GetKeyDown(KeyCode.S)) {
choiceNum -= 1;
}
if (choiceNum > 1) {
choiceNum = 0;
} else if (choiceNum < 0) {
choiceNum = 1;
}
if (choiceNum == 0) {
choicePoint.localPosition = new Vector3(0f, 24f, 0f);
if (Input.GetKeyDown(KeyCode.Return)) {
Debug.Log("choice1");
choiceMenu.SetActive(false);
isDone = true;
enteredMe = false;
ps.choiceMode = false;
}
} else if (choiceNum == 1) {
choicePoint.localPosition = new Vector3(0f, -21.5f, 0f);
if (Input.GetKeyDown(KeyCode.Return)) {
Debug.Log("choice2");
choiceMenu.SetActive(false);
isDone = true;
enteredMe = false;
ps.choiceMode = false;
}
}
}
}
}

How to disable Prefabs in Unity 2D?

Im working on an 2d local multiplayer platformer Game. In the game are obstacles (Spikes), when the player collides with them the player will die. I want the Players of the game to decide if they would like to enable or disable the Spikes (the link leads to an image that will help understanding my problem)by pressing a Key. I already wrote a script for that and added it to my dontdestroyOnLoad GameManager. So all my spikes I built are the same Prefabs. My idea was to disable the main Prefab from the Project folder to disable all the spikes in every scene, until you press a Key to reactivate them again. The Problem is, that only the texture itself in the Project Panel disables and not the Spikes Prefabs in the Hierarchy, because the prefabs turn into regular gameObjects. How can I fix this?
My Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using System.Threading;
public class DisableSpikes : MonoBehaviour
{
[Header("Spikes")]
public KeyCode disableSpikes;
public float time;
public GameObject prefabSpikes;
public bool toggleSpikes = true;
[Header("Player Green")]
public KeyCode disableGreen;
public GameObject prefabGreen;
public bool toggleGreen = true;
[Header("Reset Score")]
public KeyCode resetScore;
// Start is called before the first frame update
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == true)
{
prefabSpikes.SetActive(false);
Debug.Log("Disable");
//Thread.Sleep(1000);
Invoke("SetFalse", time);
}
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == false)
{
prefabSpikes.SetActive(true);
Debug.Log("Anable");
//Thread.Sleep(1000);
Invoke("SetTrue", time);
}
if (Input.GetKeyDown(disableGreen) && toggleGreen == true)
{
prefabGreen.SetActive(false);
Debug.Log("Disable");
//Thread.Sleep(1000);
Invoke("SetFalse", time);
}
if (Input.GetKeyDown(disableGreen) && toggleGreen == false)
{
prefabGreen.SetActive(true);
Debug.Log("Anable");
//Thread.Sleep(1000);
Invoke("SetTrue", time);
}
if (Input.GetKeyDown(resetScore))
{
ScoreScriptBlue.scoreValueBlue = 0;
ScoreScriptRed.scoreValueRed = 0;
ScoreScriptGreen.scoreValueGreen = 0;
RoundScript.scoreValueRound = 0;
TimeScript.scoreValueTime = 0;
}
}
public void SetFalse()
{
toggleGreen = false;
toggleSpikes = false;
}
public void SetTrue()
{
toggleGreen = true;
toggleSpikes = true;
}
}
void Update() {
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == true){
// show
// renderer.enabled = true;
gameObject.GetComponent<Renderer>().enabled = true;
}
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == false) {
// hide
// renderer.enabled = false;
gameObject.GetComponent<Renderer>().enabled = false;
}
}

Selecting and deselecting gameobject to change material

I am having some issues with my code.
I am trying to create a highlighting feature so a player can click on a game object and see what they have selected.
I would like it to stay highlighted
till they select another object.
when they select another object the default material would be
applied back to the previous gameobject. and it
would continue for each object them
select and deselect.
can anyone help me. I've tried a few things but it just keeps the color the same.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SelectionManager : MonoBehaviour
{
[SerializeField] private string selectableTag = "Selectable";
[SerializeField] private Material highlightMaterial;
private Material originalMaterial;
private GameObject selected;
private GameObject oldSelected;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Renderer selectionRenderer;
//change the color to the highlight
if (Input.GetMouseButtonDown(0))
{
//if selected set to highlight color
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 300.0f))
{
selected = hit.transform.gameObject;
Debug.Log("1111 new Selection --> " + selected);
if (selected.CompareTag(selectableTag))
{
if(selected != oldSelected || oldSelected == null)
{
//save the original material
selectionRenderer = selected.GetComponent<Renderer>();
originalMaterial = selectionRenderer.material;
selectionRenderer.material = highlightMaterial;
Debug.Log("Old Selection --> " + oldSelected);
Debug.Log("new Selection --> " + selected);
}
else
{
oldSelected = selected;
Debug.Log("you have selected a new building");
oldSelected.GetComponent<Renderer>().sharedMaterial = originalMaterial;
}
//comment 2
}
}
//comment 3
}
//comment1
}
void ClearSelection()
{
if (selected == null)
{
return;
}
else
{
selected.GetComponent<Renderer>().sharedMaterial = originalMaterial;
selected = null;
}
}
}
So the problem is basically that you are not assign oldSelected correctly.
Fixing this, your code should look like:
using UnityEngine;
public class SelectionManager : MonoBehaviour
{
[SerializeField] private string selectableTag = "Selectable";
[SerializeField] private Material highlightMaterial;
private Material originalMaterial;
private GameObject selected = null;
private GameObject oldSelected = null;
private Renderer selectionRenderer;
private Renderer oldSelectionRenderer;
// Update is called once per frame
void Update()
{
//change the color to the highlight
if (Input.GetMouseButtonDown(0))
{
//if selected set to highlight color
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 300.0f))
{
selected = hit.transform.gameObject;
Debug.Log("1111 new Selection --> " + selected);
if (selected.CompareTag(selectableTag))
{
//newSelection
if(selected != oldSelected)
{
//Set original material to oldSelected if it's not the first selection
if(oldSelected != null)
{
oldSelectionRenderer = oldSelected.GetComponent<Renderer>();
oldSelectionRenderer.material = originalMaterial;
}
//Set highlighted material to selected
selectionRenderer = selected.GetComponent<Renderer>();
originalMaterial = selectionRenderer.material;
selectionRenderer.material = highlightMaterial;
//assign oldSelected GO to your current selection
oldSelected = selected;
}
}
}
}
}
}

Unable to play video clip downloaded from url using VideoPlayer in Unity

I am trying to download a video(Bunny Video for testing) from a url and then play it using a video player component.
The issue I have here is that if I pass a pre downloaded clip or url to the video player in editor mode it plays video without any issue but when I try to add the VideoPlayer component dynamically to my gameobject and assign video clip to the video player, it never plays the video. Clip option always shows null in VideoPlayer component during play mode. Adding url also doesn't work when done via script.
Here is my script which downloads the video and assign it to the videoplayer.
public class DownloadScript : MonoBehaviour
{
private WWW Url;
private VideoPlayer Player;
public VideoClip clip;
public float test;
// Use this for initialization
void Start ()
{
this.gameObject.AddComponent<VideoPlayer>();
Player = this.gameObject.GetComponent<VideoPlayer>();
_Download();
/*Player.source=VideoSource.VideoClip;
Player.clip = clip;
Player.Prepare();*/
// Player.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
}
// Update is called once per frame
void Update () {
if (!Player.isPlaying && Player.isPrepared)
{
Player.Play();
}
}
private IEnumerator WaitForDownload(string sURL)
{
Url = new WWW(sURL);
//WWW www = new WWW(sURL);
Debug.Log(Url.bytesDownloaded);
yield return Url;
if (Url.isDone)
{
Debug.Log("Player ready");
Invoke("PlayVideo",20f);
}
else
{
Debug.Log(Url.bytesDownloaded);
}
yield return Url;
}
private void _Download()
{
try
{
StartCoroutine(WaitForDownload("http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"));
// return Url.bytes;
}
catch(Exception e)
{
Debug.Log(e.ToString());
}
}
public void PlayVideo()
{
Debug.Log("url download complete");
File.WriteAllBytes(Application.dataPath + "/Resources"+"/bunny.mp4", Url.bytes);
clip =(VideoClip) Resources.Load("bunny.mp4");
Player.source=VideoSource.VideoClip;
Player.clip = clip;
test = 5.0f;
// Player.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
if (Player.isPrepared)
{
Player.Play();
}
}
}
Here is the screenshot of the inspector panel at runtime.
I added a test variable in my script to verify if anything is getting updated at runtime or not. So the value of test variable is updated in the inspector panel but the video clip value doesn't update and that's why my video doesn't get played.
Any solution for this ?
So I had the same problem. Just got it resolved.
CODE :
private void Start()
{
StartCoroutine(this.loadVideoFromThisURL(videoUrl));
}
[SerializeField]
internal UnityEngine.Video.VideoPlayer myVideoPlayer;
string videoUrl ="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
private IEnumerator loadVideoFromThisURL(string _url)
{
UnityWebRequest _videoRequest = UnityWebRequest.Get (_url);
yield return _videoRequest.SendWebRequest();
if (_videoRequest.isDone == false || _videoRequest.error != null)
{ Debug.Log ("Request = " + _videoRequest.error );}
Debug.Log ("Video Done - " + _videoRequest.isDone);
byte[] _videoBytes = _videoRequest.downloadHandler.data;
string _pathToFile = Path.Combine (Application.persistentDataPath, "movie.mp4");
File.WriteAllBytes (_pathToFile, _videoBytes);
Debug.Log (_pathToFile);
StartCoroutine(this.playThisURLInVideo (_pathToFile));
yield return null;
}
private IEnumerator playThisURLInVideo(string _url)
{
myVideoPlayer.source = UnityEngine.Video.VideoSource.Url;
myVideoPlayer.url = _url;
myVideoPlayer.Prepare ();
while (myVideoPlayer.isPrepared == false)
{ yield return null;}
Debug.Log ("Video should play");
myVideoPlayer.Play ();
}
SOLUTION :
From your code, I see that you save your bytes to the Resources folder. That is not needed. Consequently you don't have to load it using Resources.Load.
Just pass in absolute filepath. I have tested in iOS and Mac OS. It works.

Categories