Forum rules - please read before posting.

Music stutters/glitches during scene changes on Nintendo Switch

edited February 2023 in Technical Q&A

When walking between scenes on the Switch I'm getting a lot of music stuttering. This happens eeven if its the same music that keeps on playing across both scenes.
The music is played using the music storage soundtrack. Any ideas?

Thanks!

Comments

  • Can't think of anything on the AC side of things - ultimately it's still a regular AudioSource placed in the DontDestroyOnLoad scene, which is Unity's standard practice for cross-scene music playback.

    Try tinkering with the AudioClip's properties, as well as running a Deep Profile to see if anything's slowing things down.

  • I made a new discovery that makes me think this might be an AC issue after all:
    The music only starts stuttering on scene loads AFTER a player speech has been played. Before that, scene transitions are 100% smooth.

    A little info which might help you recreate:

    • The issue happens both when speech is played using "Naming convention" (resources) and when played using Addressables
    • I'm loading scenes using Addressables
    • This is for Switch, but I bet the same thing is true for phones
  • The music only starts stuttering on scene loads AFTER a player speech has been played.

    As in, speech played in the previous scene? Has it finished playback by the time the stuttering occurs?

    I suspect the issue will be affected (at the very least, compounded) by the size of the project / assets involved. How many speech / music tracks are you using?

    What are the Preload Audio Data and Load Type values for your music clips, and is there any difference if you enable the former and set the latter to Streaming?

  • edited February 2023

    OK, so I tried A LOT of stuff to get to the bottom of this problem :)

    Some learnings for context
    1. Android (and probably every other low end device) suffers from exactly the same problem
    2. The number/size of the assets doesn't affect the problem
    3. The problem remains after trying every possible permutation of Preload Audio Data/Load Type/Streaming
    4. The problem remains no matter if the speech has ended or not when switching scene
    5. The problem gets "reset" if you give another app focus on the phone/device and then come back to the game - scene loads are then back to being totally silent (until after a speech has been played)

    This helps a lot
    The biggest part of the problem turns out to be ACs calls to Resources.UnloadUnusedAssets() on AssetLoader.UnloadAssets().

    These calls are probably a good idea when using Resources for stuff like save game references or scenes, but that method is also known to cause audio stuttering on low end devices.

    Also, I'm using Addressables for both these scenarios, so perhaps it would be a good idea to skip that call if that is the case. Or play it safe and add a checkbox in the Settings manager for it (or just have property that can be set programmatically to skip these calls).

    This helps some
    Stuttering can be further minimized by setting Project Settings->Audio->DSP Buffer Size to "Best performance"

    Almost gone..
    Together, those fixes takes care of (ish) 90% of the stuttering, but there's still enough left to sometimes break the flow when moving from scene to scene.

    Any ideas?
    Point 5 on my list makes me think that perhaps the speech audio isn't disposed/unloaded after it has been played? Or is something audio related done once the app regains focus?

  • edited February 2023

    Thank you for your efforts. I'll look into the use of UnloadUnusedAssets further.

    What happens when audio is played, and focus is regained, however, is handled by Unity. Have you been through AC's "Performance and optimisation" chapter?

  • You're welcome - happy to provide some love to my AC brethren 👍

    I have been through that chapter, yes. Here's the reason why I think the last audio crackle has to do with how AC handles speech specifically:

    Playing other sounds (like walk animation sounds and UI sounds) does not cause the next scene transition to crackle - only speech sounds do that. And if a speech is shown that doesn't hava any audio - not a crackle...

    If you have any theories as to some code you want me to try or uncomment to see if it gets rid of it, don't hesitate to ping me. But you should be able to reproduce this using any Android phone (even high end ones) given the info on this thread.

  • I've looked into the use of UnloadUnusedAssets, and I believe it can be bypassed automatically (no need for a separate option) so long as Save asset references with Addressables? is checked.

    Playing other sounds (like walk animation sounds and UI sounds) does not cause the next scene transition to crackle - only speech sounds do that. And if a speech is shown that doesn't hava any audio - not a crackle...

    Does this occur when speech is played "By Direct Reference"?

  • edited February 2023

    I've looked into the use of UnloadUnusedAssets, and I believe it can be bypassed automatically (no need for a separate option) so long as Save asset references with Addressables? is checked.

    I'm pretty sure you're wrong there. I just did a debug session with breakpoints on all ACs call to UnloadUnusedAssets - they were all hit. As I indicated though, it's only the call made on AssetLoader.UnloadAssets() that is causing the problems while changing scenes. That one is hit 3 times the first scene switch and then 4 times from then on. Here are the stacktraces for a scene switch that causes 4 calls:

    #1
    
    >   Void AC.AssetLoader:UnloadAssets ()+0x0 at Assets\AdventureCreator\Scripts\Static\AssetLoader.cs:[243:3-243:4]  C#
        Void AC.SaveSystem:InitAfterLoad ()+0x11e at Assets\AdventureCreator\Scripts\Save system\SaveSystem.cs:[696:4-696:32]   C#
        Void AC.MultiSceneChecker:RunStartProcess ()+0x65 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[123:5-123:45]    C#
        Void AC.MultiSceneChecker:Start ()+0x10 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[55:5-55:24]    C#
    
    
    #2
    
    >   Void AC.AssetLoader:UnloadAssets ()+0x0 at Assets\AdventureCreator\Scripts\Static\AssetLoader.cs:[243:3-243:4]  C#
        Void AC.LevelStorage:LoadPlayerData (Player, PlayerData)+0xb8 at Assets\AdventureCreator\Scripts\Save system\LevelStorage.cs:[251:4-251:32] C#
        Void AC.Player:LoadData (PlayerData)+0x610 at Assets\AdventureCreator\Scripts\Character\Player.cs:[1064:5-1064:64]  C#
        Void AC.PlayerPrefab:SpawnInScene (Boolean)+0x45 at Assets\AdventureCreator\Scripts\Character\PlayerPrefab.cs:[130:6-130:42]    C#
        Void AC.KickStarter:PreparePlayer ()+0xc8 at Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:[1181:31-1181:64]   C#
        Void AC.KickStarter:Initialise ()+0x56 at Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:[1146:4-1146:21]   C#
        Void AC.MultiSceneChecker:Awake ()+0x54 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[45:4-45:47]    C#
    
    #3
    
    >   Void AC.AssetLoader:UnloadAssets ()+0x0 at Assets\AdventureCreator\Scripts\Static\AssetLoader.cs:[243:3-243:4]  C#
        Void AC.LevelStorage:ReturnCurrentLevelData ()+0x1c at Assets\AdventureCreator\Scripts\Save system\LevelStorage.cs:[168:4-168:32]   C#
        Void AC.SaveSystem:InitAfterLoad ()+0x10b at Assets\AdventureCreator\Scripts\Save system\SaveSystem.cs:[691:6-691:57]   C#
        Void AC.MultiSceneChecker:RunStartProcess ()+0x65 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[123:5-123:45]    C#
        Void AC.MultiSceneChecker:Start ()+0x10 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[55:5-55:24]    C#
    
    #4
    >   Void AC.AssetLoader:UnloadAssets ()+0x0 at Assets\AdventureCreator\Scripts\Static\AssetLoader.cs:[243:3-243:4]  C#
        Void AC.SaveSystem:InitAfterLoad ()+0x11e at Assets\AdventureCreator\Scripts\Save system\SaveSystem.cs:[696:4-696:32]   C#
        Void AC.MultiSceneChecker:RunStartProcess ()+0x65 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[123:5-123:45]    C#
        Void AC.MultiSceneChecker:Start ()+0x10 at Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:[55:5-55:24]    C#
    

    Does this occur when speech is played "By Direct Reference"?

    Yep, still there I'm afraid.

  • I just did a debug session with breakpoints on all ACs call to UnloadUnusedAssets - they were all hit.

    I wasn't talking about the current release - but a potential update.

    Yep, still there I'm afraid.

    What were the results of a Deep Profile at the time the stuttering occurs?

  • I wasn't talking about the current release - but a potential update.

    Ah, sorry :)

    What were the results of a Deep Profile at the time the stuttering occurs?

    In a word - overwhelming... Since a whole new scene is loaded, it's very hard to pinpoint what might be causing the audio glitch...

  • A heads up: I'm not sure that you ONLY want to skip those UnloadUnusedAssets calls when not using Addressables. I kept nothing dynamically created in my previous game but I would still like to get rid of the stuttering.

    I also heard back from a user who doesn't use Addressables yet comment out those calls when it's time to do ports.

    To be honest, I'm not 100% sure that putting NPCs in addressables ALWAYS is beneficial to the perf in all situations, so if it was up to me, I would at least also allow for a programmatic way to opt out of the calls 👍

  • I would at least also allow for a programmatic way to opt out of the calls

    Point made, I'll look into it.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.