コガネブログ

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

【Unity】Enum.HasFlag の GC Alloc

概要

public sealed class Example : MonoBehaviour
{
    private void Update()
    {
        var hasFlag = JobType.SORCERER.HasFlag( JobType.SOLDIER );
    }
}

Enum.HasFlag を使うと毎フレーム 40 B の GC Alloc が発生する

public static class EnumExtensions
{
    public static bool CustomHasFlag<T>( this T self, T flag ) where T : Enum
    {
        var selfValue = Convert.ToUInt64( self );
        var flagValue = Convert.ToUInt64( flag );

        return ( selfValue & flagValue ) == flagValue;
    }
}

public sealed class Example : MonoBehaviour
{
    private void Update()
    {
        var hasFlag = JobType.SORCERER.CustomHasFlag( JobType.SOLDIER );
    }
}

上記のような独自の拡張メソッドを定義すると
Convert.ToUInt64 の呼び出しで合計 80 B の GC Alloc が発生する

public static class JobTypeExtensions
{
    public static bool HasFlagNonAlloc( this JobType self, JobType flag )
    {
        return ( self & flag ) == flag;
    }
}

public sealed class Example : MonoBehaviour
{
    private void Update()
    {
        var hasFlag = JobType.SORCERER.HasFlagNonAlloc( JobType.SOLDIER );
    }
}

列挙型ごとにビット演算する拡張メソッドを定義すると GC Alloc を 0 にできる

参考サイト様