コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】Addressable Asset System の AddressableAssetGroup に登録されているエントリが重複していないか確認するテストコード

概要

using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;

public sealed class Addressables用テスト
{
    private sealed class DuplicateEntryResult
    {
        private readonly string m_groupPath;
        private readonly string m_entryPath;
        private readonly string m_entryGuid;

        public DuplicateEntryResult
        (
            string                                   groupPath,
            IGrouping<string, AddressableAssetEntry> duplicate
        )
        {
            m_groupPath = groupPath;
            m_entryPath = duplicate.First().AssetPath;
            m_entryGuid = duplicate.Key;
        }

        public override string ToString()
        {
            return $"{m_groupPath},{m_entryPath},{m_entryGuid}";
        }
    }

    [Test]
    public void グループに登録されているエントリが重複していないか()
    {
        var settings = AddressableAssetSettingsDefaultObject.Settings;

        if ( settings == null ) return;

        var type        = typeof( AddressableAssetGroup );
        var bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
        var fieldInfo   = type.GetField( "m_SerializeEntries", bindingAttr );

        var duplicates = settings.groups
                .Select
                (
                    group =>
                    {
                        var entries        = ( List<AddressableAssetEntry> ) fieldInfo.GetValue( group );
                        var groupAssetPath = AssetDatabase.GetAssetPath( group );

                        return entries
                                .GroupBy( x => x.guid )
                                .Where( x => 1 < x.Count() )
                                .Select( x => new DuplicateEntryResult( groupAssetPath, x ) )
                                .ToArray()
                            ;
                    }
                )
                .Where( x => 0 < x.Length )
                .SelectMany( x => x )
                .ToArray()
            ;

        if ( duplicates.Length <= 0 ) return;

        Assert.Fail
        (
            $@"グループに重複して登録されているエントリ(アセット)が存在します
--------------------------------------------------------------------------------
{string.Join( "\n", duplicates.Select( x => x.ToString() ) )}
--------------------------------------------------------------------------------"
        );
    }
}
  • AddressableAssetGroup の .asset がコンフリクトして解消した時に誤って m_SerializeEntries に同 m_GUID のエントリが複数登録されてしまったりすると、ビルド時にエラーが発生するため、事前に確認するためのテストコード