ユーティリティ関数1

using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using MemoryPack;
using UniRx;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;

namespace Assets.Scripts.Utility
{
    public static class Functions
    {
        static Functions()
        {
#if DEBUG && UNITY_ANDROID
            Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
#endif
        }

        public static byte[] Serialize<T>(T data) where T : class
        {
            try
            {
                return MemoryPackSerializer.Serialize(data);
            }
            catch (Exception ex)
            {
                WriteLog(ex);
                return null;
            }
        }

        public static T Deserialize<T>(byte[] bytes) where T : class
        {
            if (bytes == null || bytes.Length == 0) return null;

            try
            {
                return MemoryPackSerializer.Deserialize<T>(bytes);
            }
#if DEBUG
            catch (Exception)
            {
            }
#else
            catch (Exception ex)
            {
                WriteLog(ex);
            }
#endif

            return null;
        }

        public static byte[] SerializeCompressed<T>(T data) where T : class
        {
            try
            {
                using (var compressor = new MemoryPack.Compression.BrotliCompressor())
                {
                    MemoryPackSerializer.Serialize(compressor, data);
                    return compressor.ToArray();
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex);
                return null;
            }
        }

        public static T DeserializeCompressed<T>(byte[] bytes) where T : class
        {
            if (bytes == null || bytes.Length == 0) return null;

            try
            {
                using (var decompressor = new MemoryPack.Compression.BrotliDecompressor())
                {
                    var decompressedBuffer = decompressor.Decompress(bytes);
                    return MemoryPackSerializer.Deserialize<T>(decompressedBuffer);
                }
            }
#if DEBUG
            catch (Exception)
            {
            }
#else
            catch (Exception ex)
            {
                WriteLog(ex);
            }
#endif

            return null;
        }

#if PLAYFAB_SUPPORT
        public static string SerializeJson<T>(T data) where T : class
        {
            try
            {
                return PlayFab.Json.PlayFabSimpleJson.SerializeObject(data);
            }
            catch (Exception ex)
            {
                WriteLog(ex);
                return null;
            }
        }
#endif

        [System.Diagnostics.Conditional("DEBUG")]
        public static void WriteLog(params object[] messages)
        {
            WriteLog(LogType.Log, string.Join(" ", messages));
        }

        [System.Diagnostics.Conditional("DEBUG")]
        public static void WriteLog(Exception ex)
        {
            Debug.LogException(ex);
        }

        [System.Diagnostics.Conditional("DEBUG")]
        public static void WriteLog(LogType logType, params object[] messages)
        {
            string message = string.Join(" ", messages);
            switch (logType)
            {
                case LogType.Assert:
                    Debug.LogAssertion(message);
                    break;
                case LogType.Warning:
                    Debug.LogWarning(message);
                    break;
                case LogType.Error:
                case LogType.Exception:
                    Debug.LogError(message);
                    break;
                default:
                    Debug.Log(message);
                    break;
            }
        }

        static int defaultScreenWidth = 0;
        static int defaultScreenHeight = 0;

        public static void LoadDefaultScreenValues()
        {
            int width = Screen.currentResolution.width;
            int height = Screen.currentResolution.height;
            defaultScreenWidth = Math.Max(1280, Math.Max(width, height));
            defaultScreenHeight = Math.Min(720, Math.Min(width, height));
        }

        public static int GetScreenWidth(Defines.ScreenSize screenSize)
        {
            switch (screenSize)
            {
                case Defines.ScreenSize.AspectRation16x9: return 1280;
                case Defines.ScreenSize.AspectRation16x10: return 1280;
                case Defines.ScreenSize.AspectRation18x9: return 1440;
                default: return defaultScreenWidth;
            }
        }

        public static int GetScreenHeight(Defines.ScreenSize screenSize)
        {
            switch (screenSize)
            {
                case Defines.ScreenSize.AspectRation16x9: return 720;
                case Defines.ScreenSize.AspectRation16x10: return 800;
                case Defines.ScreenSize.AspectRation18x9: return 720;
                default: return defaultScreenHeight;
            }
        }

        public static void TogglePinSecret(InputField inputField)
        {
            switch (inputField.contentType)
            {
                case InputField.ContentType.IntegerNumber:
                    inputField.contentType = InputField.ContentType.Pin;
                    break;
                case InputField.ContentType.Pin:
                    inputField.contentType = InputField.ContentType.IntegerNumber;
                    break;
            }
            inputField.ForceLabelUpdate();
        }

        public static IEnumerable<T> ArrayMerge<T>(params IEnumerable<T>[] arrays)
        {
            foreach (var array in arrays)
            {
                foreach (var item in array)
                {
                    yield return item;
                }
            }
        }

        public static bool IsScreenLandscape
        {
            get
            {
#if !UNITY_EDITOR && (UNITY_IOS || UNITY_ANDROID)
                return Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.LandscapeRight;
#else
                return Screen.height < Screen.width;
#endif
            }
        }

        public static void CheckRotate(MonoBehaviour parent, Action action)
        {
#if UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE_WIN
            Observable.Timer(TimeSpan.Zero, new TimeSpan(1000))
                .Select(_ => IsScreenLandscape)
                .StartWith(IsScreenLandscape)
                .DistinctUntilChanged()
                .Subscribe(bLandscape => action(bLandscape))
                .AddTo(parent);
#else
            action(IsScreenLandscape);
#endif
        }

        public static async UniTask ForceRotate(bool bLandscape)
        {
            if (bLandscape)
            {
                Screen.orientation = Input.deviceOrientation == DeviceOrientation.LandscapeRight
                                    ? ScreenOrientation.LandscapeRight
                                    : ScreenOrientation.LandscapeLeft;
            }
            else
            {
                Screen.orientation = Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown
                                    ? ScreenOrientation.PortraitUpsideDown
                                    : ScreenOrientation.Portrait;
            }
            try
            {
                var observe = Observable.Timer(new TimeSpan(100), new TimeSpan(100)).Where(_ =>
                {
                    switch (Screen.orientation)
                    {
                        case ScreenOrientation.AutoRotation:
                            return true;
                        case ScreenOrientation.LandscapeLeft:
                        case ScreenOrientation.LandscapeRight:
                            return Input.deviceOrientation == DeviceOrientation.LandscapeLeft ||
                                    Input.deviceOrientation == DeviceOrientation.LandscapeRight;
                        case ScreenOrientation.Portrait:
                        case ScreenOrientation.PortraitUpsideDown:
                            return Input.deviceOrientation == DeviceOrientation.Portrait ||
                                    Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown;
                        default:
                            return false;
                    }
                });

                await Observable.Timeout(observe, new TimeSpan(3000)).First();
            }
            catch (TimeoutException)
            {
            }
            finally
            {
                Screen.orientation = ScreenOrientation.AutoRotation;
            }
        }

        public static bool IsDisplayLanguageJapanese => UnityEngine.Localization.Settings.LocalizationSettings.SelectedLocale?.Identifier.Code == Defines.LanguageCode_Japanese;

        public static bool Approximately(Quaternion q1, Quaternion q2)
        {
            return Quaternion.Angle(q1, q2) < 0.01f;
        }

        public static void OpenGooglePlayStorePage()
        {
#if UNITY_ANDROID
            Application.OpenURL($"market://details?id={Defines.ApplicationID}");
#endif
        }
    }
}