itineration problem with function after resume app - c#

this probably is a noob question, but I can't figure out how resolve it.
Im opening/resuming my android app from a notification (intent data).
the app is opening fine from the intent.
the problem is if send the app to the background again after opening from the intent and later I resume again, the coroutine executes again every time I resume, because keeps getting the data from the "old" intent.
*is there some way of clear the intent data? (without close the app)
im trying something like: AndroidJavaObject saveIntent = curActivity.Call<AndroidJavaObject>("setData");
to replace the intent data so the next itineration dont get te correct values
*Im thinking to limit to 1, the times what the coroutine can be executed, but not is a "clean"solution.
can someone give me some guidance?.
this is my code so far:
void OnApplicationPause(bool appPaused)
{
if (!isOnAndroid || Application.isEditor) { return; }
if (!appPaused)
{
//Returning to Application
Debug.Log("Application Resumed");
StartCoroutine(LoadSceneFromFCM());
}
else
{
//Leaving Application
Debug.Log("Application Paused");
}
}
IEnumerator LoadSceneFromFCM()
{
AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject curActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject curIntent = curActivity.Call<AndroidJavaObject>("getIntent");
string sceneToLoad = curIntent.Call<string>("getStringExtra", "sceneToOpen");
//string extraInfo = curIntent.Call<string>("getStringExtra", "extraInfo"); use this for do some extra stuff
Scene curScene = SceneManager.GetActiveScene();
if (!string.IsNullOrEmpty(sceneToLoad) && sceneToLoad != curScene.name)
{
// If the current scene is different than the intended scene to load,
// load the intended scene. This is to avoid reloading an already acive
// scene.
Debug.Log("Loading Scene: " + sceneToLoad);
Handheld.SetActivityIndicatorStyle(AndroidActivityIndicatorStyle.Large);
Handheld.StartActivityIndicator();
yield return new WaitForSeconds(0f);
SceneManager.LoadScene(sceneToLoad);
}
}

this is working for me now:
void Awake()
{
DontDestroyOnLoad(gameObject);
}
void OnApplicationPause(bool appPaused)
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
Scene curScene = SceneManager.GetActiveScene();
string sceneToLoad = intent.Call<string>("getStringExtra", "sceneToOpen");
if (sceneToLoad != null && sceneToLoad.Trim().Length > 0 && sceneToLoad != curScene.name)
{
Debug.Log("Load the Video Scene");
SceneManager.LoadScene(sceneToLoad);
//redirectToAppropriateScreen(intent, onClickScreen);
}
intent.Call("removeExtra", "sceneToOpen"); //this remove the data from the intent, so the function cant be completed after resume again.
Debug.Log("Extra data removed");
}

Related

Tiles not following input in a branching board game path

I'm making a board game in Unity with multiple branching paths where the players can decide which one to follow. (Think the Mario Part game board) But the player input on which path to follow isn't working.
So I have a script that has the tokens follow a set path and (Linked List for the path) with a for loop to have the tokens move their allocated amount. Within the loop, I have an If statement that checks how many paths the tile has and if there are more than one if runs a separate script that pauses the game and offers a menu prompt for the players to pick one path or the other.
I've tried tossing in a few contitions for continuing the game within the loop but they either ignore the player input, are an input behind or just break the code.
`for (int i = 0; i < spacesToMove; i++)
{
if (final_Waypoint == null)
{
final_Waypoint = Starting_Waypoint;
}
else
{
if (final_Waypoint.Next_Waypoint == null || final_Waypoint.Next_Waypoint.Length == 0)
{
//we are overshooting the final waypoint, so just return some nulls in the array
//just break and we'll return the array, which is going to have nulls at the end.
Debug.Log(Current_Waypoint);
break;
}
else if (final_Waypoint.Next_Waypoint.Length > 1) // && if playerID == 0 so it only appears for players.
{
menu.Pause_for_Choice();
//if (menu.ButtonPress == true)
final_Waypoint = final_Waypoint.Next_Waypoint[menu.choice_int];
//***There's a bug here. It calls menu as per normal, and the game pauses.
//But when I click 'no', choice_int isn't updated first: this function finishes first,
//so this function gets old choice_int. THEN the button function executes.
Debug.Log("test 3 " + menu.choice_int);
}
else
{
final_Waypoint = final_Waypoint.Next_Waypoint[0];
}
}
listOfWaypoints[i] = final_Waypoint;
Debug.Log("i:" + i);
}
return listOfWaypoints;
}`
`{
public GameObject choice_Menu;
public bool isPaused = true;
public int choice_int=0;
public int choice_placeholder = 0;
public void Pause_for_Choice()
{
isPaused = true;
choice_Menu.SetActive(true);
Time.timeScale = 0;
}
public void Yes()
{
choice_placeholder = 0;
UnPause_Game();
}
public void No()
{
choice_placeholder = 1;
UnPause_Game();
}
public void UnPause_Game()
{
isPaused = false;
choice_Menu.SetActive(false);
Time.timeScale = 1;
}
}`

Take several photos with PhotoCapture Unity C#

I got a script that should be able to take more than one photo. I am using PhotoCapture and get an error making it unable to capture a second photo. I get the error "Value cannot be null" on the photoCaptureObject.StartPhotoModeAsync(cameraParameters, result => row, but I don't understand why this is.
I have commented away the photoCaptureObject = null; row so that the photoCaptureObject should not be null. The row if (photoCaptureObject == null) return; also proofs that the photoCaptureObjectis not null.
PhotoCapture photoCaptureObject = null;
Texture2D targetTexture = null;
public string path = "";
CameraParameters cameraParameters = new CameraParameters();
private void Awake()
{
var cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, captureObject =>
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
});
}
private void Update()
{
// if not initialized yet don't take input
if (photoCaptureObject == null) return;
if (Input.GetKeyDown(KeyCode.K) || Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, result =>
{
if (result.success)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Couldn't start photo mode!", this);
}
});
}
}
There is some code here in between that change the photo taken and so on, but I don't think that that code is part of the problem.
private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
VuforiaBehaviour.Instance.gameObject.SetActive(true);
photoCaptureObject.Dispose();
//photoCaptureObject = null;
Debug.Log("Photomode stopped");
}
So what else could be null? Is it the StartPhotoModeAsync somehow? How can I fix this issue?
Thanks!
Okay so I understand now thanks to Henriks comment.
Unity specifically says this about StartPhotoModeAsync:
Only one PhotoCapture instance can start the photo mode at any given
time
I have focused more on the sentence after saying that one should always use PhotoCapture.StopPhotoModeAsyncbecause having PhotoCaptureMode on takes more power so I never thought about that the instance wouldn't start again after stopping it.
Now I only have TakePhotoAsyncin the update on key press and do not stop the PhotoMode due to that the app that I am making should always be able to capture photos.

Unity play pause audio not working well

I cannot figure out the right code for playing and pausing the audio source in a single button click.
Here is my Code
ButtonAction.GetComponent().onClick.AddListener(delegate
{
if (soundTarget.isPlaying)
{
soundTarget.Pause();
}
else if(!soundTarget.isPlaying)
{
soundTarget.Play();
playSound("sounds/English");
}
});
Note: By default it is not playing because if I play it by default it will just loop around. It is somehow working but I need to click the button multiple times before it plays or pauses.
Help me.
It's quite simple :
Your Unity scene should be something like this :
For the script that I called "UnityUI" is like below :
public AudioSource MyAudioSource;
public Button PlayBtn;
public PlayButtonText;
void Start()
{
PlayBtn.onClick.AddListener(() =>
{
if (MyAudioSource.isPlaying)
{
MyAudioSource.Stop();
PlayButtonText.text = "Play me!";
}
else
{
MyAudioSource.Play();
PlayButtonText.text = "Stop me!";
}
});
}
Hope that this helped!
Happy coding!
My code is supposed to be like this. When the button is clicked it will play the sound and when clicked again it will be paused.
playSound("sounds/English");
soundTarget.Play();
if (soundTarget.isPlaying)
{
soundTarget.Stop();
}
else
{
soundTarget.Play();
}
But this code is just looping around and doesn't play the sound.
void Update()
{
StateManager sm = TrackerManager.Instance.GetStateManager();
IEnumerable<TrackableBehaviour> tbs = sm.GetActiveTrackableBehaviours();
foreach (TrackableBehaviour tb in tbs)
{
string name = tb.TrackableName;
ImageTarget it = tb.Trackable as ImageTarget;
Vector2 size = it.GetSize();
Debug.Log("Active image target:" + name + " -size: " + size.x + ", "
+ size.y);
ButtonAction.gameObject.SetActive(true);
TextDescription.gameObject.SetActive(true);
PanelDescription.gameObject.SetActive(true);
ButtonMute.gameObject.SetActive(true);
if (name == "quezon")
{
ButtonAction.GetComponent<Button>().onClick.AddListener(delegate
{
if (soundTarget.isPlaying)
{
soundTarget.Pause();
btn.image.overrideSprite = Play;
}
else
{
btn.image.overrideSprite = Pause;
playSound("sounds/English");
soundTarget.Play();
}
});
TextDescription.GetComponent<Text>().text = "Manuel L. Quezon was
born on August 19, 1878, and died on August 1, 1944. He was a
Filipino statesman, soldier, and politician who served as president
of the Commonwealth of the Philippines from 1935 to 1944.";
Narrator.gameObject.SetActive(true);
void playSound(string ss)
{
clipTarget = (AudioClip)Resources.Load(ss);
soundTarget.clip = clipTarget;
soundTarget.loop = false;
soundTarget.playOnAwake = false;
soundTarget.ignoreListenerPause = true;
}

Unity ads, Video always fails to show

I have this code and after I execute it with a button console every time that prints out that video, it fails. Maybe I just don't know how to enable ads in Unity. I have test mode enabled. This is my code. :
FIXED i just needed to replace this line
public string placementId = "rewardedVideo";
with this:
Advertisement.Show(placementId, options);
private string gameId = "1523603";
void Start(){
Advertisement.Initialize (gameId);
}
public void ShowAd (){
var options = new ShowOptions();
options.resultCallback = HandleShowResult;
Debug.Log (Advertisement.IsReady ("rewardedVideo"));
Advertisement.Show(gameId, options);
}
void HandleShowResult (ShowResult result){
if(result == ShowResult.Finished) {
Debug.Log("Video completed - Offer a reward to the player");
OnemoreTry ();
}else if(result == ShowResult.Skipped) {
Debug.LogWarning("Video was skipped - Do NOT reward the player");
}else if(result == ShowResult.Failed) {
Debug.LogError("Video failed to show");
}
}

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