블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2702)
Unity3D (793)
Script (88)
Extensions (14)
Effect (3)
NGUI (76)
UGUI (8)
Physics (2)
Shader (36)
Math (1)
Design Pattern (2)
Xml (1)
Tips (196)
Link (22)
World (1)
AssetBundle (25)
Mecanim (2)
Plugins (66)
Trouble Shooting (63)
Encrypt (7)
LightMap (4)
Shadow (4)
Editor (8)
Crash Report (3)
Utility (9)
UnityVS (2)
Facebook SDK (2)
iTween (3)
Font (10)
Ad (11)
Photon (2)
IAP (1)
Google (8)
Android (44)
iOS (39)
Programming (471)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (224)
협업 (57)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (50)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
12-08 12:53

달력

« » 2023.12
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

공지사항

최근에 올라온 글

반응형

[2023-11-17 기준 사용 버전] Unity 2022.3.13f1

----

 

2022.3 LTS 버전이 나오고 2022.3.5까지 나온걸 보고 업데이트를 하고 사용했었는데,

2023-11-17 기준 최신 버전인 2023-11-17까지 빌드하고 테스트 해본 결과 아래와 같은 크리티컬한 크래쉬 이슈가 여전히 있었다.

안그래도 Unity 2021보다 Unity 2022가 무거워서 마음에 안들었는데 너무 크리티컬한 버그를 아직도 안고치고 있으니 갑갑함.

덕분에 스토어 올려진 앱이 크래시 증가로 경고까지 뜨고 있다.

 

  [크래쉬 이슈]

- 엔진 자체 메모리 누수로 인한 메모리 부족으로 느려지거나 크래쉬 남

- 파티클 관련 무한 재귀 관련 버그가 있는 건지 이펙트(파티클)가 터지면 간헐적으로 앱이 멈춤(이건 예상)

 

2022.3의 .3은 LTS라고 불리는 버전인데 2022.3 모든 버전에서 메모리 누수가 여전히 나고 있고,

몇일 전에 올라온 2022.3.13f1도 위 2개의 크래쉬 이슈가 이전보다는 줄었지만 여전히 나고 있다.

(유니티는 LTS의 정의를 잘못 생각하고 있는건 아닌지 의심스럽다.)

 

더이상 2022 버전 버그 수정을 기대하면서 쓰는건 뻘짓이라 판단하고 2022 버전을 완전히 버리기로 생각함.

현재 2023 버전은 LTS가 나오려면 멀었기 때문에 2021.3으로 엔진 메이저 버전을 다운그레이드 하고 앱 업데이트를 완료 했다.

 

테스트 상에서는 2022에 있던 크래쉬 이슈가 2021에선 나오지 않는걸 확인했다.

2021.3 버전을 쓰다가 2023.3으로 바로 넘어가야 될 것 같다.

 

P.s. 오늘 유니티 뉴스 보니 버전 레벨링을 개편한다면서 2023을 Unity 6으로 바꾸고 앞으로 버전으로 다시 돌아간다고 함.

       매년 업데이트 하기 힘들었나벼..그래서 출시하면 안되는 버전인 Unity 2022가 나오게 된건 아닌지 의심스럽다

 

[결론]

Unity 2022는 쓰레기니 쓰지맙시다.

Unity 2021 쓰세요~

 

[2022.3 Memory Leak 참조 링크]

https://forum.unity.com/threads/strange-memory-leak-on-2022-3-x.1460224/

 

Question - Strange Memory leak on 2022.3.x

Hi all, So this is an odd one. My game when run on 2021.3, memory sits around 1.3GB on launch. However, ive had reports since making changes over the...

forum.unity.com

https://forum.unity.com/threads/rthandles-api-introduced-catastrophic-memory-leak-bug-in-2022-3-8.1486035/

 

Bug - RTHandles API introduced catastrophic memory leak bug in 2022.3.8

Hi all, It seems there was a very large memory leak bug introduced in 2022.3.8 (on my PC it went as far as filling 32GB RAM and reserving a 32GB page...

forum.unity.com

 

반응형
Posted by blueasa
, |
반응형

[링크] https://learnandcreate.tistory.com/642

 

유니티에서 패키지를 기본값으로 재설정하기(reset pacakges to defaults)

유니티에서 패키지를 기본값으로 재설정하기(reset pacakges to defaults) 패키지를 기본값으로 재설정하면 프로젝트에서 사용자가 설치한 모든 패키지들을 제거하고 기본값으로 초기화합니다. 이 작

learnandcreate.tistory.com

 

반응형
Posted by blueasa
, |
반응형

With recent Unity versions (2020, 2021 and 2022) Flutter Android builds will take a lot longer, because it also has to compile the IL2CPP code from Unity.

From the Readme:

  • Android builds takes forever to complete Unity 2022.1.*, remove these lines from unityLibrary/build.gradle filecommandLineArgs.add("--enable-debugger")
    commandLineArgs.add("--profiler-report")
    commandLineArgs.add("--profiler-output-file=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_conv.traceevents")

Here is some testing to check how to speed things up.

Unity settings

IL2CPP Code Generation

  • Build Settings -> IL2CPP Code Generation: select Faster (smaller) builds instead of Faster runtime.
  • Or C# EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;

C++ compiler configuration

  • In Player settings -> Other settings -> configuration, select Debug.
  • Or C# PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);

Disable script debugging

Don't bother setting this in the Unity settings, it will be overridden by the build script.
Assets/FlutterUnityIntegration/Editor/build.cs
In the function DoBuildAndroid() remove the line enabling script debugging.
playerOptions.options = BuildOptions.AllowDebugging;
This is the same as removing commandLineArgs.add("--enable-debugger") from the build.gradle file after an export.

Measuring results

When you run a Flutter build, there are multiple IL2CPP stages that report their duration, with 2 sections taking far longer than all others.
We can compare these build durations when using different settings in Unity.

Log of the slow armv7 and arm64 sections

Starting: Z:\fuw20221.1.0+7\2021\example\android\unityLibrary\src\main\Il2CppOutputProject\IL2CPP\build\deploy\bee_backend\win-x64\bee_backend.exe --profile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/backend_profiler1.traceevents" --stdin-canary --dagfile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/bee.dag" --continue-on-failure --dagfilejson="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/bee.dag.json" FinalProgram
WorkingDir: Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate
ExitCode: 0 Duration: 2m:04s
Build succeeded with 553 successful nodes and 0 failed ones

Starting: Z:\fuw20221.1.0+7\2021\example\android\unityLibrary\src\main\Il2CppOutputProject\IL2CPP\build\deploy\bee_backend\win-x64\bee_backend.exe --profile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/backend_profiler1.traceevents" --stdin-canary --dagfile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/bee.dag" --continue-on-failure 
--dagfilejson="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/bee.dag.json" FinalProgram
WorkingDir: Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate
ExitCode: 0 Duration: 2m:03s
Build succeeded with 553 successful nodes and 0 failed ones
 

Results

The exact durations here aren't important, as this will be different of every computer and project setup.
This is after flutter clean and a fresh Unity export. Any subsequent runs will be faster because of caching.

Flutter build apk, with an export from Unity 2021.3.5f1 in android/unityLibrary on Windows 10.

Settingarmv7 durationarm64 duration

example project 2m:04s 2m:03s
1 - Code generation (faster builds) 1m:41s 1m:38s
2 - Compiler configuration (debug) 45s 43s
3 - No script debugging 30s 30s
1 + 2 35s 34s
1 + 2 + 3 23s 25s

Conclusion

My advice is to add this to the build script in DoBuildAndroid() for any test or debug builds, remove it for final release builds.

//Assets/FlutterUnityIntegration/Editor/build.cs
bool isReleaseBuild = false;

#if UNITY_2022_1_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, isReleaseBuild ? Il2CppCompilerConfiguration.Release : Il2CppCompilerConfiguration.Debug);
    PlayerSettings.SetIl2CppCodeGeneration(UnityEditor.Build.NamedBuildTarget.Android, UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize);
#elif UNITY_2021_2_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, isReleaseBuild ? Il2CppCompilerConfiguration.Release : Il2CppCompilerConfiguration.Debug);
    EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;
#endif
 

If it doesn't affect your workflow, disable script debugging.

// playerOptions.options = BuildOptions.AllowDebugging;

And if you are developing on an arm64 device anyway, temporarily remove the armv7 build target from the Unity player settings.

 

 

[출처] https://github.com/juicycleff/flutter-unity-view-widget/issues/643

 

[Android] Tips to reduce android build times. · Issue #643 · juicycleff/flutter-unity-view-widget

With recent Unity versions (2020, 2021 and 2022) Flutter Android builds will take a lot longer, because it also has to compile the IL2CPP code from Unity. From the Readme: Android builds takes fore...

github.com

 

반응형
Posted by blueasa
, |
반응형

Unity 2021.3.23f1 이후

Unity 2022 이후

 

----

Unity 2021.3.23f1 부터 유니티 에디터가 (Unity 2021.3.23f1 버전부터) *.androidlib를 폴더가 아닌 파일로 보게 변경된 후,

(관련 이슈 : https://issuetracker.unity3d.com/issues/macos-meta-files-are-created-inside-a-bundle-when-its-imported-into-the-project)

*.androidlib나 *.dll 등의 파일을 Import 하거나 git 등에서 pull 받고 유니티를 재실행하면 제목과 같이 Rever Factory Settings 설정 팝업등이 뜨면서 무한 루프에 빠진다.

 

이를 해결하기 위해서는 Library 폴더를 삭제 후 유니티를 켜서 Library를 새로 생성하게 하면 되는데

전체를 다시 생성하려면 시간이 너무 오래걸린다.

 

확인해보니 아래 파일 2개만 삭제하면 된다고 한다.

에디터 종료 후, 아래 파일 2개를 삭제하고 에디터를 다시 실행해보자.

 

[Library에서 삭제할 파일]

- ./Library/SourceAssetDB

- ./Library/SourceAssetDB-lock

 

 

 

 

반응형
Posted by blueasa
, |
반응형

성능이 한정된 기기에서 실행되는 애플리케이션의 충돌을 방지하려면 메모리 최적화가 반드시 필요합니다. 여러 기기를 대상으로 출시하려는 경우, 각 플랫폼에서 최고의 성능을 끌어내기 위해 메모리 사용량을 조정해야 할 수도 있습니다.

 
메모리에 영향을 끼치는 요소는 매우 다양하지만, 그 중에서도 에셋을 중심으로 메모리를 효율적으로 관리할 수 있도록 지원하는 Unity 툴과 최적화할 수 있는 방안에 대해 소개합니다.

 
제공: 오지현 에반젤리스트, 2023년 2월

빌트인 프로파일러 모듈로, 애플리케이션이 메모리를 사용하는 위치에 대한 기본 정보를 제공합니다.
 
메모리 프로파일러 모듈은 애플리케이션에 할당된 전체 메모리를 나타내는 카운터를 시각화합니다. 메모리 모듈을 사용하여 로드된 오브젝트의 수와 카테고리 별로 해당 오브젝트가 차지하는 메모리 양과 같은 정보를 볼 수 있습니다.

2. Memory Profiler 1.0 (필수)
 

Unity 애플리케이션 및 Unity 에디터의 메모리 사용량을 검사하는 데 사용할 수 있는 도구로, 어떤 에셋이 메모리를 사용하고 있는지 애플리케이션의 메모리 할당에 대한 정보를 자세하게 확인할 수 있습니다. 특히 Unity 에디터에 메모리 프로파일러 창을 추가하여 메모리 스냅샷을 캡처, 검사 및 비교할 수 있습니다.

Unity 패키지 관리자를 통해 다운로드하고 메모리를 최적화할 수 있습니다.

▶ Memory Profiler 1.0.0 관련 블로그 아티클 보기


3. Unity Addressables
 

Unity Addressables는 복잡한 라이브 콘텐츠를 전달해야 하는 대규모 제작팀의 요구사항을 보다 효과적으로 지원하기 위한 Unity 에디터 및 런타임 에셋 관리 시스템입니다.
 
Unity Addressables을 활용해 불필요한 에셋의 로드를 방지하는 약한 참조를 도입하여 런타임 메모리를 개선할 수 있습니다.

 

 어드레서블 에셋 시스템으로 메모리 최적화하기 블로그 아티클 보기


4. Audio / Sound 설정
[Force to Mono]
오디오의 스테레오 정보를 없애고 Mono로 만드는 만큼 용량이 줄어듭니다. 특히 모바일에서는 스테레오로 설정할 일이 드물어 추천 드립니다.
 
[읽기 방식(Load type)]
사운드가 어떤 성격인지에 따라 로드 타입과 포맷을 설정하는 것을 추천 드립니다.




[권장 압축 형식(Compression Format)]
● Unity는 하드웨어 가속이 아닌 소프트웨어로 오디오 디코딩을 처리하고 있어 안드로이드/iOS 구분 없이 사용할 수 있는 Vorbis 타입을 권장합니다.
● 매우 짧은 클립의 경우 ADPCM 포맷을 권장 드립니다.
 
※ 오디오는 음소거(Mute) 상태여도 메모리에는 존재하고 있어 선택 옵션이 아니라면, 지우는 것을 권장합니다.

5. Mesh

Mesh 데이터 관리를 통해 메모리를 최적화할 수 있습니다.



Read / Write Enabled 옵션은 CPU와 GPU메모리 양측에 존재하여 옵션을 OFF하는 것이 좋습니다.




6. 셰이더 배리언트
하나의 셰이더라도 여러 조건에 따라 수많은 바이너리로 파생되어 빌드 시간, 패키지 사이즈는 물론 메모리까지 영향을 줄 수 있습니다.
 
셰이더 배리언트의 개념부터 이슈 발생 원인, 최적화하는 방법으로 메모리를 최적화해 보세요.



7. TextMesh Pro
시각적 품질을 크게 개선할 뿐만 아니라 텍스트 스타일 지정 및 텍스처링 부문에서 사용자에게 뛰어난 유연성을 선사하는 TextMesh Pro
 
특히 한글은 초성+중성+종성 조합 방식으로 11,000자가 넘는 글자를 텍스트 아틀라스와 텍스처로 제작한다면 메모리가 커질 수 밖에 없습니다. 메모리 최적화를 위해 사용 시 여러 테스트를 통해 제작하는 것을 권장합니다.


8. 메모리에 영향을 주는 텍스처

대부분의 게임에서는 텍스처로 인한 메모리 이슈가 발생합니다.
 
[Baked Lighting]
Lightmap, Light Probe, Reflection Probe와 같은 조명 설정으로도 메모리 문제가 발생할 수 있습니다. 메모리에 영향을 주는 요소로 적절하게 사용하는 것이 좋습니다.
 
● Lightmap은 배경, 건물과 같은 스태틱 오브젝트에 라이트 결과를 미리 적용하여 저장하기 때문에 텍스처 메모리 이슈가 발생할 수 있습니다.
● Reflection Probe는 6면의 큐브로 만들어진 텍스처로, 텍스처 6개가 생성됩니다. 그에 따라 메모리 이슈 발생 가능성이 큽니다.
 
가능한 시각 효과 대비 사이즈를 작게 제작하고, 적절한 압축 형식을 사용하는 것을 권장합니다.

[텍스처 압축]
 

텍스처 에셋의 화질이 높을수록 픽셀당 비트가 더 높으며, 그에 따라 빌드 크기, 로드 시간, 런타임 메모리 사용량이 늘어납니다.

기기에서 지원하지 않는 포맷 사용 시 압축이 풀리기 때문에 기기별 지원하는 텍스처 포맷을 사용하는 것이 좋습니다. 모바일에서는 ASTC 형식을 사용하는 것을 권장합니다. (타겟 디바이스에 따라 상이)



[Mipmap]

Mipmap(밉맵)은 3D 그래픽스에서 텍스처를 적용하는 과정에서 렌더링 속도를 가속화하기 위해 축소한 비트맵 이미지의 집합으로, 카메라로부터의 거리에 따라 달라질 수 있습니다.


Mipmap 사용 시 원래 텍스처보다 33.3333%의 메모리가 증가합니다. 2D 맵에서는 원근법이 필요하지 않기 때문에 Off를 하는 것이 좋습니다.

[Scene Loading]
Scene 전환 시 기존 Scene A 의 데이터가 남아있는 상황에서 추가적으로 Scene B의 데이터를 로드할 경우 순간적으로 메모리에 과부하가 발생할 수 있습니다.



9. 메모리 최적화에 도움이 되는 Unity 가이드

 

[출처]

https://unitysquare.co.kr/growwith/unityblog/webinarView?id=348&utm_source=facebook-page&utm_medium=social&utm_campaign=korea_unitytipsblog-memory

 

Unity Square

성능이 한정된 기기에서 실행되는 애플리케이션의 충돌을 방지하려면 메모리 최적화가 반드시

unitysquare.co.kr

 

 

반응형
Posted by blueasa
, |
반응형

Audio Import 시, 원하는 최적화 관련 설정 자동 셋팅하도록 소스 정리 함.

(AudioCompressionFormat은 심플하게 Vobis / Quality 40으로 통일함.)

 

using System.IO;
using UnityEditor;
using UnityEngine;

public class AssetPostprocessor_Audio : AssetPostprocessor
{
    /*
     * 오디오클립 파일 경로
     * Resources - Sound ┬ BGM - MainBGM
     *                   ├ InGame - SFX
     *                   └ SoundEffect ┬ OutGame
     *                                 ├ UI
     *                                 └ Voice
     * Resources_AssetBundles ┬ sound ┬ sound_effect
     *                        │       ├ sound_main_bgm
     *                        │       ├ sound_sub_bgm
     *                        │       └ sound_voice
     *                        ├ sound_scenario
     *                        └ sound_scenario_StreamingAssets
     */
    void OnPreprocessAudio()
    {
        bool bDefaultSettingChanged = false;
        AudioImporter audioImporter = assetImporter as AudioImporter;
        AudioImporterSampleSettings defaultSampleSettings = audioImporter.defaultSampleSettings;
        AudioImporterSampleSettings iosSampleSettings = audioImporter.GetOverrideSampleSettings("iOS");
        bool biOSSettingChanged = false;

        UnityEditor.SerializedObject serializedObject = new UnityEditor.SerializedObject(audioImporter);
        UnityEditor.SerializedProperty normalize = serializedObject.FindProperty("m_Normalize");

        string strPath = audioImporter.assetPath;
        Debug.LogFormat("[audioImporter.assetPath] {0}", strPath);

        // Folder Name
        if (strPath.StartsWith("Assets/Resources/Sound/BGM"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = true;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.Streaming;
            audioImporter.preloadAudioData = false;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            //iosSampleSettings.loadType = AudioClipLoadType.Streaming;
            //iosSampleSettings.compressionFormat = AudioCompressionFormat.MP3;
            //iosSettingChanged = true;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources/Sound/InGame/SFX"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources/Sound/SoundEffect/OutGame"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources/Sound/SoundEffect/UI"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources/Sound/SoundEffect/Voice"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.CompressedInMemory;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound/sound_effect"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound/sound_main_bgm"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = true;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.Streaming;
            audioImporter.preloadAudioData = false;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound/sound_sub_bgm"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = true;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.Streaming;
            audioImporter.preloadAudioData = false;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound/sound_voice"))
        {
            audioImporter.forceToMono = true;
            normalize.boolValue = false;
            audioImporter.loadInBackground = false;
            //audioImporter.ambisonic = false;

            defaultSampleSettings.loadType = AudioClipLoadType.CompressedInMemory;
            audioImporter.preloadAudioData = true;
            defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
            defaultSampleSettings.quality = 0.4f;   // 40
            defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

            bDefaultSettingChanged = true;
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound_scenario"))
        {
            // File Name
            if (strPath.Contains("/bg_"))  // BGM
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = true;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.Streaming;
                audioImporter.preloadAudioData = false;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
            else if(strPath.Contains("/se_"))  // SFX
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = false;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
                audioImporter.preloadAudioData = true;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
            else    // Etc(SFX?)
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = false;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
                audioImporter.preloadAudioData = true;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
        }
        else if (strPath.StartsWith("Assets/Resources_AssetBundles/sound_scenario_StreamingAssets"))
        {
            // File Name
            if (strPath.Contains("/bg_"))  // BGM(
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = true;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.Streaming;
                audioImporter.preloadAudioData = false;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
            else if (strPath.Contains("/se_"))  // SFX
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = false;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
                audioImporter.preloadAudioData = true;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
            else    // Etc(SFX?)
            {
                audioImporter.forceToMono = true;
                normalize.boolValue = false;
                audioImporter.loadInBackground = false;
                //audioImporter.ambisonic = false;

                defaultSampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
                audioImporter.preloadAudioData = true;
                defaultSampleSettings.compressionFormat = AudioCompressionFormat.Vorbis;
                defaultSampleSettings.quality = 0.4f;   // 40
                defaultSampleSettings.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;

                bDefaultSettingChanged = true;
            }
        }

        try
        {
            // 수정됐으면 Save
            if (true == bDefaultSettingChanged)
            {
                audioImporter.defaultSampleSettings = defaultSampleSettings;
                serializedObject.ApplyModifiedProperties();
                if (true == biOSSettingChanged)
                {
                    audioImporter.SetOverrideSampleSettings("iOS", iosSampleSettings);
                }
                audioImporter.SaveAndReimport();

                EditorUtility.SetDirty(audioImporter);

                Debug.LogFormat("[{0}] has been imported to [{1}]\n[Force To Mono] {2}\n[Normalize] {3}\n[Load In Background] {4}\n[Load Type] {5}\n[Compression Format] Default: {6}, iOS: {7}\n[Quality] {8}\n[Sample Rate Setting] {9}",
                                Path.GetFileName(strPath),
                                Path.GetDirectoryName(strPath),
                                audioImporter.forceToMono.ToString(),
                                normalize.boolValue,
                                audioImporter.loadInBackground,
                                defaultSampleSettings.loadType.ToString(),
                                defaultSampleSettings.compressionFormat.ToString(),
                                iosSampleSettings.compressionFormat.ToString(),
                                (defaultSampleSettings.quality * 100f),
                                defaultSampleSettings.sampleRateSetting.ToString()
                                );
            }

            // OnPreprocessAudio() 에서는 Refresh 안함
            //AssetDatabase.Refresh();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e);
        }
    }

    // 파일이 이동한 경우 다시 임포트.
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        try
        {
            foreach (string movedAsset in movedAssets)
            {
                if (movedAsset.StartsWith("Assets/Resources/Sound")
                    || movedAsset.StartsWith("Assets/Resources_AssetBundles/sound")
                    || movedAsset.StartsWith("Assets/Resources_AssetBundles/sound_scenario")
                    || movedAsset.StartsWith("Assets/Resources_AssetBundles/sound_scenario_StreamingAssets")
                    )
                {
                    AssetDatabase.ImportAsset(movedAsset);
                }
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError(e);
        }
    }
}

 

[참조]

https://overworks.github.io/unity/2018/09/22/unity-audio-clip-import-guide.html

https://jwidaegi.blogspot.com/2019/07/unity-sound.html?sc=1680659862098#c4452839809969885205

https://www.jianshu.com/p/b389936ff1ad

https://blog.csdn.net/hururu20120502/article/details/121425411

https://drehzr.tistory.com/1016

 

 

반응형
Posted by blueasa
, |
반응형

Today we’ll be talking about the Preload Audio Data option in Unity’s Audio Import Settings and why understanding this small but critical checkbox is important for your game.

So many options… How does Unity choose which audio is loaded to a scene?

Editor’s Note: Compression Formats, Load Type and the Preload Audio Data/Load in Background settings go hand in hand. We recommend reading our blog posts on all three in the following order for a complete overview:

Blog 1: Compression Formats

Blog 2: Load Types

Blog 3: Preload Audio (this post)

Blog 4: Load in Background (coming soon)

This blog post has been made as a supplement to our video tutorial on this same topic.

 
 

Introduction

After figuring out how Unity compresses your audio with the different compression formats, and primes your audio for playing with the different Load Type settings, the next question to answer is: What does the Preload Audio Data option do?

The Unity Documentation provides important information on this subject, but it doesn’t explain exactly when and how audio files are selected to be loaded in an active scene.

 

Preload Audio Data

Here’s Unity’s definition of Preload Audio Data from their manual:

If enabled, the audio clip will be pre-loaded when the scene is loaded. This is on by default to reflect standard Unity behavior where all AudioClips have finished loading when the scene starts playing.

This information is pretty clear already. If you choose this option, you want the audio priming process with the respective Load Types to take place before the scene is activated and becomes playable.

This will result in mission-critical audio files being ready to be played at all times at the expense of making the scene load time a little bit longer.

So far, so good. But there is one question left unanswered:

How does Unity decide which Audio is going to be loaded in which Scene?

 

References

Let’s imagine this situation: you’re developing a large game that has 15 hours of playtime and around 30 scenes. You have something like 1000 SFX and 2000 dialogue files. You would not want every single audio asset marked with Preload Audio Data to be loaded in every scene, would you?

Unfortunately, the documentation doesn’t address this in detail, making the process of deciding whether or not to Preload your audio assets very difficult and full of uncertainty.

Luckily, Unity is a sophisticated engine. After many tests, we concluded that Unity will scan everything in our scene and load all audio files flagged with Preload Audio Data that are referenced in the scene in any way.

Let’s take a step back here because now we have another question to answer:

What is a reference?

Let’s open up Unity and find out.

 

Testing Testing

We’ve imported 10 sound effects, 10 dialogue, and 2 music files into a Unity project. They’re all marked with Preload Audio Data to simulate a larger game. There are also two different scenes to simulate loading and unloading audio in a normal scene transition.

Let’s start with the first scene. We have a GameObject here with an AudioSource that has an AudioClip.

We hope this looks familiar.

This is already a so-called reference and this audio file will be loaded when the scene is loaded. I turned off Play on Awake for this to make sure that the audio is not played. Let’s build this and confirm with the profiler.

Our AudioClip is loaded and ready for action.

Perfect. Even though the AudioClip is not played at all, it is loaded because it has been referenced.

Note that this music file, which has “Streaming” selected as its Load Type, is only 311 bytes in the memory, unlike the 200-ish kilobytes from the last tutorial. That will change if we actually play the sound file.

Let’s now add two scripts we’ve prepared for another GameObject.

These two scripts do nothing but define a public AudioClip variable and a public AudioClip array. Let’s add an AudioClip to that and profile this.

Voilá. We have the second audio clip loaded.

For the sake of this demonstration, I will add another two AudioClips to the array and check the profiler once again.

As you might have guessed, without Preload Audio Data selected, Unity will not load the AudioClip until it is called, even though it is referenced in the scene. We’ll be going more in-depth on this in our next tutorial.

So, a reference is as simple as that. As long as you have a reference of any kind to an AudioClip, be it directly in the AudioSource, as a variable in a script, or even in a ScriptableObject, it will be loaded when the scene is loaded if you have checked Preload Audio Data.

 

Scene Transitions

Now: what happens if we change to another scene? Will the audio data we loaded in this scene be automatically unloaded?

Let’s go to the second scene. We’ll keep one AudioClip constant across both scenes but change the rest. Now we can build and profile this once again.

And then we’ll transition to the next scene.

We see here that all but one of our AudioClips from the first scene are already unloaded from the memory, leaving only the one that is used again in the second scene.

The unloading process took place as the scene was changed; this is a normal routine that Unity does in the background called GarbageCollection.

 

Final Words

Let’s summarize what we’ve learned:

  • Selecting Preload Audio Data means the scene will not start until all sounds with this setting are loaded into memory. This is most important for audio content that is needed right away in the scene, such as footsteps, UI, or anything synced to visual content that plays immediately upon the scene’s activation.
  • Unity determines which files to load in a scene by searching for references. If an audio file is referenced unnecessarily, for example, an AudioClip in an AudioSource that you ended up not using but didn’t delete from the scene, it will be loaded as well, even if the entire GameObject is deactivated. In that respect, it’s important to keep your scenes clear of unused references.
 

That’s it! We hope this tutorial has helped you to understand the Preload Audio Data option in Unity’s Import Settings and why this information is important for your game.

If you want to learn more about how audio functions in Unity, be sure to check out our other tutorials (linked below). If you have a question, leave it in the comments or contact us directly through our website:

 

 

[출처] https://medium.com/@made-indrayana/preload-audio-data-how-unity-decides-which-audio-assets-to-load-to-a-scene-a440a654e7e2

 

Preload Audio Data & How Unity Decides Which Audio Assets to Load to a Scene

Today we’ll be talking about the Preload Audio Data option in Unity’s Audio Import Settings and why it’s important for your game.

medium.com

 

반응형
Posted by blueasa
, |
반응형

Force To Mono

Unity 측에서 음원을 모노로 변환하여 용량을 줄여주는 설정
모바일이라고 ON하고 싶다.

인스펙터상이라면 이 설정을 ON으로 하면 Normalize옵션 설정을 선택할 수 있게 된다.
이것은 음량을 평균화해 주는 기능입니다만, 음소재측에서 음량 조정되고 있는 케이스도 있어, 「작은 소리로 하고 싶었는데 어쨌든 음량 오르지 않았어?」같은 것이 됩니다
.

그래서, 모노럴 설정은 ON으로 하면서, 노멀라이즈는 OFF로 해 두고 싶은 기분이 되네요.

 

가져오기 설정을 자동화하고 싶습니다.

수동으로 하는 것은 힘들어지므로,
AudioImporter 를 스크립트로부터 괴롭히고 어떻게든 하고 싶다.

그러나 AudioImpoter에는 forceToMono매개 변수가 있지만
Normalize관련 매개 변수가 노출되지 않았습니다.

 

결과

아래와 같이 해 주면, 해당의 파라미터를 취득해 재기입할 수 있었습니다.

 

var audioImporter = assetImporter as AudioImporter;
var serializedObject = new UnityEditor.SerializedObject(audioImporter);
var normalize = serializedObject.FindProperty("m_Normalize");
normalize.boolValue = false;

serializedObject.ApplyModifiedProperties();

audioImporter.SaveAndReimport();
UnityEditor.EditorUtility.SetDirty(audioImporter);
UnityEditor.AssetDatabase.Refresh();

 

https://answers.unity.com/questions/1016473/how-to-disable-normalize-in-audioimporter.html
https://docs.unity3d.com/ScriptReference/EditorUtility.SetDirty.html

 

 

[출처] https://qiita.com/mrhdms/items/85bd2e524a9c76e1273c

 

AudioImporter で Force to mono は有効にしつつ、Normalize だけ無効にする - Qiita

Force to mono Unity側で音源をモノラルに変換して、容量を削減してくれる設定 モバイルだとONにしたい。 インスペクタ上だと、この設定をONにすると、 Normalize というオプション設定が選択でき

qiita.com

 

[참조] https://www.jianshu.com/p/b389936ff1ad

 

Unity插件-音频参数优化

需求:需要对音频做出修改,压缩音频质量,检测是否设置为Mono与Normalize, 超过10秒LoadType设为Streaming. 思路:遍历所有的音频文件,拿到所有的...

www.jianshu.com

 

반응형
Posted by blueasa
, |
반응형

[링크] https://overworks.github.io/unity/2018/09/22/unity-audio-clip-import-guide.html

 

유니티 오디오 클립 임포트 설정 가이드

옵션 설명

overworks.github.io

 

반응형
Posted by blueasa
, |
반응형

모바일 게임을 제작하다 보면, PC-에디터에서는 잘 나오던 게임 사운드가 핸드폰에서는 밀려 나오는 경우를 종종 겪을 수 있다.

이런 상황을 해결하기 위한 설정값을 기록해 둔다.
출처 : https://docs.unity3d.com/kr/current/Manual/class-AudioClip.html

프로젝트 세팅

Edit > Project Settings > Audio에서 DSP Buffer Size Best latency로 설정
- Best Performance : 성능이 우선 되어 출력 시 지연이 발생할 수 있음
- Best latency : 지연이 발생하지 않는 것을 우선시하여 출력 품질이 저하될 수 있음


리소스 타입별 세팅

배경음 1
- Force To Mono : 언 체크(퀄리티에 따라 가변)
- Load In Background : 체크
- Load Type : Streaming
- Preload Audio Data : 언 체크
- Compression Format : Vobis (100%)

배경음 2
- Force To Mono : 언 체크(퀄리티에 따라 가변)
- Load In Background : 체크
- Load Type : Compressed In Memory
- Preload Audio Data : 언 체크
- Compression Format : Vobis (70%)

효과음 : 작은 크기의 빈번한 출력 
- Force To Mono : 체크
- Load In Background : 언 체크
- Load Type : Decompress On Load
- Preload Audio Data : 체크
- Compression Format :  PCM

긴 효과음(보이스) : 중간 크기의 빈번한 출력
- Force To Mono : 체크
- Load In Background : 언 체크
- Load Type : Compressed In Memory
- Preload Audio Data : 체크
- Compression Format :  ADPCM

작은 크기의 가끔 발생하는 Sound
- Force To Mono : 체크
- Load In Background : 언 체크
- Load Type : Compressed In Memory
- Preload Audio Data : 언 체크
- Compression Format :  ADPCM

중간 크기의 가끔 발생하는 Sound
- Force To Mono : 체크
- Load In Background : 언체크
- Load Type : Compressed In Memory
- Preload Audio Data : 언 체크
- Compression Format :  Vobis (70%)


개별 리소스 세팅 정보

Force To Mono(모노 강제조정)
- 스테레오를 모노로 강제 조정
- 모바일이고 최적화를 중시할 경우 설정(체크) 함

Load In Background(지연된 로딩)
- 체크 시 출력 타이밍을 엄격히 지키지 않고, 느긋하게 백그라운드에서 로드
- 따라서 배경음악일 경우 사용 FX 사운드의 경우 체크 해제


Load Type
- Decompress On Load
 실행과 동시에 압축을 해제
 작은 사이즈의 FX 사운드에 유용
 많은 메모리 점유 CPU는 적게 사용

- Compressed In Memory
 메모리에 압축 상태로 저장, 실행 시 압축을 해제하여 재생
 약간의 성능상 오버헤드를 발생시킴
 보이스 사운드 등에 사용

- Streaming
 저장소에 위치한 오디오를 실시간으로 읽어냄.
 보통 배경음악에서 사용


Preload Audio Data
- 씬이 로딩될 때 씬에서 사용하는 모든 오디오 클립을 미리 로드
- 언체크시 플레이시 로드 하기에 랙 발생 됨


Compression Format
- PCM
 최고품질 / 용량 큼 / 작은 파일 크기에 적합 / FX 사운드
 Load Type은 Decompress On Load로 하자
 즉시 재생해야 하는 매우 짧은 효과음

- ADPCM
 중간 품질 / 용량 중간
 PCM대비 3.5배의 압축비, 노이즈가 포함됨
 총격 소리와 같이 무압축에 가까운 품질 까지는 필요없지만,
 지연시간 없이 자주 반복 재생 되야 하는 경우 적절

- Vobis
 최저품질 / 용량 적음 / 배경음에 적합
 압축률 설정이 가능(보통 70%로 설정)
 지연 재생 되어도 무방한 일반적인 배경음

 

 

[출처] https://jwidaegi.blogspot.com/2019/07/unity-sound.html

 

Unity Sound 설정

모바일 게임을 제작하다 보면, PC-에디터에서는 잘 나오던 게임 사운드가 핸드폰에서는 밀려 나오는 경우를 종종 겪을 수 있다. 이런 상황을 해결하기 위한 설정값을 기록해 둔다. 출처 :  https://

jwidaegi.blogspot.com

 

반응형
Posted by blueasa
, |