When navigating from menu to a Scene that contains 8, 1-minutes MP4 videos, that are played using new VideoPlayer script on RawImage component. I am using Unity 5.6.0b11 beta version.
In the scene that I am trying to navigate has prefabs that loads videos in list thumbnails, previously I was loading Images instead of Videos and it was working fine, now when trying to load video it freezes for than 38 seconds on Axon 7 (4GB RAM) and 32 seconds on One Plus 3 (6 GB RAM) but does not lags at all when playing on Unity Player itself.
Script I used for VideoPlayer is from this StackOverflow Question.
button.onClick.AddListener(new UnityEngine.Events.UnityAction(() =>
{
SceneManager.LoadSceneAsync("SceneSponsors");
StartCoroutine(CloseMenu());
}));
Is there a way, I can work around with the Slow Loading Scenes or pre-load them in Background when mainScene is loaded on the App start and navigate in need.
I saw somewhere Resources.Load() also makes it slow on Android Devices, but I've tested by removing all Resources.Load() which I was using to load image sprites but the problem was still there.
Edit:
Here's my CloseMenu() functions it is only used to swipe and move the menu panel. P.S the App freezes only on loading that particular Scene, and works smoothly for other.
IEnumerator CloseMenu()
{
if (IsOpen)
{
Vector3 pos = MainMenuWindow.transform.position;
iTween.ColorUpdate(CloseArea, new Color(0, 0, 0, 0f), .6f);
iTween.MoveTo(MainMenuWindow.gameObject, new Vector3(Screen.width, pos.y, pos.z), .6f);
IsOpen = false;
yield return new WaitForSeconds(.3f);
CloseArea.transform.position = new Vector3(-240 * ScaleFact, CloseArea.transform.position.y, CloseArea.transform.position.z);
}
}
Edit 2
I am loading VideoPlayer on RawImage using Script. Here's what RawImage looks like in Play mode along with VideoPlayer, and in inactive mode.
For my case of problem. I had to make some changes on the VideoPlayer API Script I was using from this StackOverflow Question
In the script I was using from that link. The Co-routine was started inside the Start() function, that made the videos in 8 different prefab, to load at once even they were in pause mode.
So I added a new function PlayVideoOnClick() and attached it to the Click Event of the RawImage, so now the video will be loaded only if the RawImage is clicked.
Changed from
public void Start()
{
Application.runInBackground = true;
StartCoroutine(playVideo());
}
To
public void PlayVideoOnclick()
{
Application.runInBackground = true;
StartCoroutine(playVideo());
}
P.S: You can also see my YouTube Video Tutorial and Blog on Playing Videos smoothly in Unity.
It is a well known bug that loading big scenes using LoadSceneAsync may block the gpu completely several seconds (completely unnoticeable in the editor), i´ve also been following this for quite some time now,
From the forums:
https://forum.unity3d.com/threads/starting-async-load-causes-massive-lag-spike.288755/
Official unity Issue tracker:
https://issuetracker.unity3d.com/issues/loading-a-scene-async-creates-huge-performance-spikes-for-the-gpu
Related
I'm making a mobile game and have some troubles with Android.
On IOS game works perfect, 60fps, very fast scene loading 1-2 sec.
On Android First scene is loading like 5-6 min(Menu Scene), game scenes seems like infinite loading.
I testet On Xiaomi phones, Pixel and Galaxy. Everywhere is the same problem.
I left one scene in the game, it loads instantly, but as I add more scenes the game takes longer and longer to load with each scene.
Its seems like game is loading all the scenes at once.
Could someone please help me I'm stuck with this.
This is the code on first scene :
string path = Application.persistentDataPath + "/Data23.fun";
if (File.Exists(path))
{
if (PSM.CharacterCreated)
{
SceneManager.LoadScene(2);
}
else
{
SceneManager.LoadScene(1);
}
}
else
{
Debug.Log("Save File not exist in Path : " + path);
SceneManager.LoadScene(1);
}
Solved, the problem was wrong "Base Gradle Template" settings.
In my Xamarin forms Android app, I play videos in view 1 and 16 in a matrix of 16 views using Android SurfaceView integrating with third-party video SDK, see screenshot below. Then I switch to 4 views. On switching, I stopped both videos first and then resume playing. It still plays video in view 1 which is correct. But it also shows a still video image left behind (from previous view 16). Th surface view of this image should have been removed. What could be the cause of the image?
I can clear a video or image and detach the camera using the following code. We do have such a command button Clear All.
public int ClearVideo(int cameraIndex)
{
if (App.CameraToViewHolderDictionary.ContainsKey(cameraIndex))
{
var surfaceHolder = (ISurfaceHolder)App.CameraToViewHolderDictionary[cameraIndex];
if (surfaceHolder != null/* && surfaceHolder.Surface.IsValid*/)
{
surfaceHolder.SetFormat(Format.Transparent);
surfaceHolder.SetFormat(Format.Opaque);
}
}
_videoViewModel.DetachCamera(cameraIndex);
return 0;
}
However this code shouldn't be required when changing the size of matrix views. Please suggest a way to get rid of the image left behind. Thank you.
I understand that this may not be an issue of Xamarin forms. Please note that the app works on some Android versions such as Pixel 3 or emulators such as bluestacks.
When launching the game, after the unity splash screen, my first scene is a small 15-seconds .mp4 cinematic.
I have scripted said cinematic to load the next scene (Main Menu UI) after it has ended and it works flawlessly on desktop. When I build&run to test it on my Android device (Huawei P20), it crashes after the Unity splash screen.
I've tried using multiple .mp4 as well as using converters to change their codec to no avail. I've also tried resizing and/or changing the resolution, but that wouldn't fix it either.
My only limited solution is using Handheld.PlayFullScreenMovie, but this is not something I want since I don't want players to be able to pause/skip the cinematic.
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.SceneManagement;
public class IntroToMainMenuUI : MonoBehaviour
{
public VideoPlayer VideoPlayer;
void Start()
{
VideoPlayer.loopPointReached += LoadScene;
}
voice LoadScene(VideoPlayer vp)
{
SceneManager.LoadScene("Main Menu UI");
}
}
Needless to say, the Android device always crashes, while the W10 desktop runs it perfectly.
For anyone in the future in a similar predicament, I resolved it. The fault was that I had the video clip attached to the main camera directly. Apparently desktop will play it fine as is, but on Android it will always crash. I, instead, went to the Video Player component and in "Render Mode" I chose "Render Texture". I then created a raw image and attached the Video Clip in the "Texture" section. Like-wise, I then attached the raw image into the Video Player's "Target Image" section. It played fine afterwards.
When I load scenes the first time after app installation on my android phone, it takes time I.e. few seconds. Thereafter all the scenes load pretty fast. I am assuming the faster load times is because the scenes are loaded from cache.
So how can I preload all the scenes in cache or at least the 'heavy' scenes so that they get loaded fast even the first time?
Thanks.
Short answer is you can't, the first time your app runs it will create its own cache and that takes time, But you can create a loading screen and load your scenes asynchronously, there are a lot of tutorials about that
https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Example : MonoBehaviour
{
void Update()
{
//Press the space key to start coroutine
if (Input.GetKeyDown(KeyCode.Space))
{
//Use a coroutine to load the Scene in the background
StartCoroutine(LoadYourAsyncScene());
}
}
IEnumerator LoadYourAsyncScene()
{
// The Application loads the Scene in the background at the same time as the current Scene.
//This is particularly good for creating loading screens. You could also load the Scene by build //number.
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Scene2");
//Wait until the last operation fully loads to return anything
while (!asyncLoad.isDone)
{
yield return null;
}
}
}
http://blog.teamtreehouse.com/make-loading-screen-unity
https://www.youtube.com/watch?v=YMj2qPq9CP8
https://en.wikipedia.org/wiki/Dalvik_%28software%29
I instantiate the following gameObject, which contains an Animator with the mode "always animate" on, the animation goes for 340ms, after that time I destroy the gameObject.
The gameObject Inspector properties:
I instantiate it using the following code:
instancia = (Instantiate(cardAnimation, new Vector3(0, 0, 0), Quaternion.identity) as GameObject).GetComponent<Image>();
instancia.rectTransform.SetParent(transform);
StartCoroutine(KillOnAnimationEnd());
Here is the Coroutine:
private IEnumerator KillOnAnimationEnd()
{
yield return new WaitForSeconds(0.34f);
DestroyImmediate(instancia);
}
Here is how the animation looks like when simulating in Unity (PC-Windows):
But on android after I open the chest it waits 340ms with nothing happening and then show the information above, does this have something to do with the plataform or is some unity or perhaps code related issue?
NOTE: I also have another animation in another scene that is just a already instantiated gameObject in the Hierarchy with always animated on and it works on Android.
--EDIT--
So I have ran the newest version of the app in a emulator which is almost about 1080x480 and the animation showed just as the PC, also running on a 720p smartphone did the job, the only problem I'm still having is with my QuadHD resolution from Galaxy S6, everything else shows but the animation, I have even tried making the animation run without any script so it runs in a loop, but it doesn't show up in galaxy screen.
Given the news about the issue I think this might change a little bit the perspective of answers and perhaps help someone else solve the same problem in the future.
Okay, figured out the problem, its something to do with "rotation" in animations using Unity3D in 2D mode, gonna be reporting it form Unity so it is fixed.
The solution: Animate your UI only using scale/position, if used rotation it will not show on high resolution display.
I am pretty sure your WaitForSeconds(0.34f) is not working properly because there is no thing such as yield keyword in Java. I recommend you to use a invoke method instead to call your method that destroys your GameObject.