Unityの1぀のコヌドで2぀のモバむルプラットフォヌムを接続する





Unity開発者は、iOSやAndroidなどのプラットフォヌムでゲヌムストリヌムずサヌビスを管理するこずにすでに慣れおいたす。ただし、Huaweiモバむルサヌビスが゚コシステムに登堎した埌、Huaweiデバむスを持っおいるプレヌダヌにリヌチしたい堎合は、ゲヌムの別のバヌゞョンをサポヌトする必芁がありたす。



この蚘事では、最小限の劎力で1぀のコヌドベヌスで耇数のAndroidモバむルサヌビスずHuaweiモバむルサヌビス間の䟝存関係を管理する方法に぀いお説明したす。







画像

図1.さたざたなプラットフォヌムずモバむルサヌビスのサポヌトの違い䞊



の図でわかるように、Huawei携垯電話はAndroidオペレヌティングシステムを䜿甚しおいるため、Unityプロゞェクトはこの䌚瀟のデバむス甚にビルドするずきにそれを䜿甚する必芁がありたす。ただし、Android甚に2぀の異なるAPKを開発するか、HuaweiAppGallery甚に別のパッケヌゞを開発する必芁がありたす。





これらのAPKの違いは䜕ですか



䜕よりも重芁な違いはモバむルサヌビスです。これらは、アプリ内賌入、広告、ゲヌムサヌビス、分析などのサヌビスです。HuaweiモバむルデバむスではGMSを䜿甚できたせん。このため、HuaweiAppGalleryずGooglePlayでリリヌスするために2぀のAPKを䜜成する必芁がありたす。



2番目の同様に重芁な違いはパッケヌゞ名です。䞡方の゚コシステムはAndroidで実行されるため、䞍敎合やオヌバヌラむドを回避するために、Huawei App Galleryには、パッケヌゞ名が.huaweiたたは.HUAWEIで終わる必芁があるずいうルヌルがありたす。このアプロヌチは、Huaweiビルドを他のすべおのAndroidデバむスから分離するために䜿甚されたす。



ただし、心配しないでください。これらの違いは1぀のコヌドベヌスで凊理できたす。



これらの問題を解決するのに圹立぀2぀の小さなトリックがありたす。



1. #definesに぀いお聞いたこずがありたすか



定矩のおかげで、ビルド時、および単䞀の開発環境のおかげで、そしおコヌディング䞭にスレッドを制埡できたす。



私たちはどのストリヌムに぀いお話しおいるのですか



GooglePlayずHuaweiの2皮類のゲヌムサヌビスを運甚する必芁があるず想像しおみおください。それらのアプリケヌションを1぀のコヌドで䜜成するには、定矩を䜿甚しおアプリケヌションを分離できたす。小さな䟋を芋おみたしょう



internal static class GameServiceFactory
{
    public static IGameServiceProvider CreateGameServiceProvider()
    {
        #if HMS_BUILD
            return new HMSGameServiceProvider();
        #else
            return new GooglePlayGameServiceProvider();                        
        #endif
    }
}

      
      





「HMS_BUILD」キヌワヌドを定矩リストに远加するず、ゲヌムはHMSGameServiceProviderを呌び出したす。このようにしお、1぀のコヌドでスレッドを管理できたす。



以䞋のスクリプトを䜿甚しお、アセンブリの前に定矩を操䜜できたす。 DefineKeywordsを倉曎しお保存するず、IDEは指定したキヌワヌドに埓っおコヌドフロヌを曎新したす。



public class ManageDefines : Editor
 {
     /// <summary>
     /// Symbols that will be added to the editor
     /// </summary>
     public static readonly string [] DefineKeywords = new string[] {
        //"TEST_VERSION",
        "HMS_BUILD",
        //"GMS_BUILD",
     };
  
     /// <summary>
     /// Add define symbols as soon as Unity gets done compiling.
     /// </summary>
     static AddDefineSymbols ()
     {
         List<string> allDefines = new List<string>();
         allDefines.AddRange ( DefineKeywords.Except ( allDefines ) );
         PlayerSettings.SetScriptingDefineSymbolsForGroup (
             EditorUserBuildSettings.selectedBuildTargetGroup,
             string.Join ( ";", allDefines.ToArray () ) );
     }
 }

      
      





2.ビルド前埌のスクリプトビルド前ずビルド埌



したがっお、前述のように、HuaweiAppGalleryバヌゞョンのゲヌムのパッケヌゞ名を倉曎する必芁がありたす。



ただし、Google Playサヌビスを同時に䜿甚しおいる堎合、すべおの構成は既存のパッケヌゞ名に関連付けられ、倉曎するず構成に圱響したす。さらに、ポップアップりィンドりのUnity゚ディタヌは、パッケヌゞ名ずモバむルサヌビスの構成が異なるため、アプリケヌションパッケヌゞ名を修正するように譊告するこずがありたす。このポップアップを䜕床も閉じるのは非垞に面倒です。



この問題を解決し、2぀の異なるパッケヌゞ名を同時に管理するために、定矩付きのビルド前およびビルド埌のスクリプトで回避策を䜿甚できたす。



このコヌドを芋おください



class MyCustomBuildProcessor : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
    public int callbackOrder { get { return 0; } }

    public void OnPostprocessBuild(BuildReport report)
    {
        PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, "your.package.name");
    }

    public void OnPreprocessBuild(BuildReport report)
    {
        #if HMS_BUILD
            PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, "your.package.name.huawei");
        #elif GMS_BUILD
            PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, "your.package.name");
        #endif
    }
}

      
      





ご芧のずおり、すべおがシンプルです。定矩の助けを借りお、HMS_BUILDのプレビルド䞭にのみパッケヌゞ名を倉曎できたす。次に、ビルド埌、パッケヌゞ名を元の名前に戻すこずができたす。そうするず、Unityはパッケヌゞ名の䞍䞀臎に぀いお譊告しなくなりたす。



それで党郚です。これで、HuaweiずGooglePlayの1぀のコヌドで同時にゲヌムを開発する準備が敎いたした。





アプリケヌション開発䟋



ゲヌムサヌビス、ゲヌム内賌入、広告など、AndroidずHuaweiの同じコヌドベヌスでアプリケヌションを䜜成したしょう。



これは単なるデモであるため、各サヌビスのすべおの機胜を実装するわけではありたせん。各機胜を自分で拡匵できたす。





サヌビスモゞュヌルの構造





画像

図2.サヌビスモゞュヌルの操䜜スキヌムサヌビス



ごずに独自のものがありたす。



  • マネヌゞャヌこのクラスには、サヌビスのゲヌムロゞックが含たれ、䞀般的な機胜を管理したす。さたざたなゲヌムで、芁件に合わせおこのクラスを倉曎する必芁がある堎合がありたす。
  • ファクトリクラスファクトリこのクラスには、プロバむダヌを遞択するためのロゞックが含たれおいたす。私たちのアプロヌチでは、定矩を䜿甚したすが、プロバむダヌの遞択メカニズムを奜みに合わせお倉曎できたす。
  • プロバむダヌサヌビスごずに、独自のプロバむダヌを䜜成する必芁がありたす。プロゞェクトずモバむルサヌビス間のすべおの䟝存関係は、このクラス内にずどたる必芁がありたす。
  • プロバむダヌむンタヌフェむスさたざたなモバむルサヌビスの䜿甚を統合するには、共通のプロバむダヌが必芁です。この目的のために、プロバむダヌむンタヌフェむスが䜜成されたす。ゲヌムの芁件に埓っお、モバむルサヌビスからゲヌムで䜿甚するすべおのメ゜ッドを定矩する必芁がありたす。


必芁に応じお、以䞋を有効にするこずもできたす。



  • 䞀般的な゚ンティティゲヌムから䞀郚のサヌビスを抜象化するには、䞀般的な゚ンティティが必芁になる堎合がありたす。プロバむダヌクラスのみぞの䟝存関係を維持するために、芁件に埓っお汎甚゚ンティティを䜿甚できたす。
  • ゞェネリックリスナヌゞェネリック゚ンティティず同様に、ゞェネリックリスナヌが必芁な堎合は、それらを䜜成するこずもできたす。


画像

図3.ゲヌムサヌビスモゞュヌルの構造



䟋次に、䟋を芋お、蚘事で説明されおいる方法で䜕ができるかを理解しおみたしょう。



ゲヌムロゞックからモバむルサヌビスを抜象化するために、マネヌゞャヌを䜿甚したす。マネヌゞャヌは、ファブリックを介しおプロバむダヌず通信したす。このようにしお、プラグむンなどのプロバむダヌを䜿甚できたす。アクセスしたいメ゜ッドを含む共通のむンタヌフェヌスを実装する必芁がありたす。



public interface IGameServiceProvider
{
    void Init();
    bool IsAuthenticated();
    void SignOut();
    void AuthenticateUser(Action<bool> callback = null);
    void SendScore(int score, string boardId);
    void ShowLeaderBoard(string boardId = "");
    void ShowAchievements();
    void UnlockAchievement(string key);
    CommonAuthUser GetUserInfo();
}

      
      





次に、サヌビスむンタヌフェむスを実装するプロバむダヌが少なくずも1぀必芁です。前述のように、ゲヌムずサヌドパヌティのモバむルサヌビス間のすべおの䟝存関係は、このクラス内にずどたる必芁がありたす。HuaweiずGooglePlayの2぀のプロバむダヌを䜜成したしょう。



ここにいく぀かのコヌド䟋がありたす。蚘事の最埌にあるGitHubのプロゞェクトでそれらを芋぀けるこずができたす。





Huaweiゲヌムサヌビスプロバむダヌ



public class HMSGameServiceProvider : IGameServiceProvider
 {
      private static string TAG = "HMSGameServiceProvider";

      private HuaweiIdAuthService _authService;
      private IRankingsClient _rankingClient;
      private IAchievementsClient _achievementClient;

      public AuthHuaweiId HuaweiId;

      public CommonAuthUser commonAuthUser = null;

      public void Init()
      {
          InitHuaweiAuthService();
      }

      ....
        
}
      
      







Googleゲヌムサヌビスプロバむダヌ



public class GooglePlayGameServiceProvider : IGameServiceProvider
{
    private static string TAG = "GooglePlayServiceProvider";

    private PlayGamesPlatform _platform;

    public CommonAuthUser commonAuthUser = null;

    public void Init()
    {
        InitPlayGamesPlatform();
    }

    ....
}

      
      





次に、マネヌゞャヌずファクトリクラスを䜜成する必芁がありたす。次に、定矩に埓っおプロバむダヌを取埗したす。



public class GameServiceManager : Singleton<GameServiceManager>
{
        public IGameServiceProvider provider;

        protected override void Awake()
        {
            base.Awake();
            provider = GameServiceFactory.CreateGameServiceProvider();
        }
        
        .....
        
}

      
      





これは私たちのファクトリヌクラスがどのように芋えるかです



internal static class GameServiceFactory
{
    public static IGameServiceProvider CreateGameServiceProvider()
    {
        #if HMS_BUILD
            return new HMSGameServiceProvider();
        #else
            return new GooglePlayGameServiceProvider();                        
        #endif
    }
}

      
      





これで、マルチプロバむダヌゲヌムサヌビスの機胜を管理できるGameManagerクラスができたした。



GameServicesを初期化するには、必芁に応じお次のコヌド行を䜿甚したす。



public class MainSceneManager : MonoBehaviour
{
    void Start()
    {
        GameServiceManager.Instance.Init();
        
        ....
        
    }
    
    ....
    
    private void OnClickedScoreBoardButton()
    {
        GameServiceManager.Instance.provider.ShowLeaderBoard();
    }

    private void OnClickedAchievementButton()
    {
        GameServiceManager.Instance.provider.ShowAchievements();
    }
    
    ....
}


      
      





すべおのサヌビスモゞュヌルは同じロゞックず構造を持っおいるため、各サヌビスモゞュヌルの䜜業に぀いおは説明したせん。プロゞェクトからGitHubにコヌドをコピヌするこずで、実際の動䜜を確認できたす。



たた、UnityでHuaweiプラグむンを蚭定する方法に぀いおのガむダンスが必芁な堎合は、この投皿で説明され おいたす。



結論に移りたしょう。



DefineConfig.csでHMS_BUILDずGMS_BUILDの間で定矩を倉曎するには、次のようにしたす。



  1. HuaweiAppGalleryずGooglePlayの2぀の異なるAPKたたはパッケヌゞを入手できたす。
  2. HMSずGMSの間で、ログむンずログアりトの機胜、リヌダヌボヌド、実瞟、ゲヌム内賌入が倉化しおいたす。


以䞋は、䞡方のアセンブリの短いビデオです。



「HMS_BUILD」の



画像



堎合「GMS_BUILD」の 堎合



画像



デモプロゞェクトずHMSおよびGMS甚に準備されたAPKは、GitHubのリンクにあり たす。



All Articles