UnrealEngineのApple開発でやったことまとめ(iOS/tvOS/macOS対応)
あいさつ
こんにちは
ブラストエッジゲームズでリードエンジニアをしているNARIといいます。
機会があってApple系(iOS/tvOS/macOS)のGame Center対応を
させていただいたので、セットアップから実装時の注意点やトラブルなどを
いろいろ紹介させていただきたいと思います。
途中UEのGitHubソースコードのリンクが出ますが、以下の登録をすることで
閲覧できます。
https://www.unrealengine.com/ja/ue-on-github
よろしくお願いします。
Unreal Engine5.3を対象にしています。
5.4以降は、問題が解消されていたりしますので
都度調べてもらえたらと思います。
やったこと
以下のことをやりました。
それぞれやったことについて解説していきます。
カスタムUnreal EngineのXcodeプロジェクトの作成
WindowsリモートビルドのiOSビルド対応
Game Centerのフレンド周りの追加実装
Game Centerのリーダーボードの修正(手伝い)
macOSのGameCenter対応
tvOSのGame Center対応
iOSのアクセス許可ダイアログの表示
OSのダイアログのローカライズ方法
特定iPhone端末でメモリ周りでクラッシュする
その他いろいろなトラブル対応
カスタムUnreal EngineのXcodeプロジェクトの作成
カスタムなUnreal Engineのセットアップマニュアルが
ほとんどなかったため、調べたことをまとめます。
通常のUnreal Engineで作業する場合は、MacでC++でプロジェクトを作れば
Xcodeのプロジェクトが自動で作られますが
ソースコードビルドのUnreal Engineでプロジェクトをセットアップする場合
以下の手順でXcodeプロジェクトのセットアップができます。
sh /{UnrealEngineSourceCodeProjectPath}/GenerateProjectFiles.command
エラーが出たら以下を入力してもう一度↑を実行
sudo chmod -R 777 /{UnrealEngineSourceCodeProjectPath}
// 自分のプロジェクトの初期設定をする
sh /{UnrealEngineSourceCodeProjectPath}/GenerateProjectFiles.sh -project="{MyProjectPath}/{MyProject}.uproject" -game
処理が無事終わったら
{MyProject}(Mac).xcworkspaceができているので開きます。
このままビルドするとアプリをそのままビルドしてしまうので
{MyProject}Editorに切り替えてビルドしましょう。
また、chmod以外はsudoをつけないようにしましょう。
UEビルド時に自動生成ファイルがうまく生成できなくなり
ファイルの権限周りの修正が大変なことになります。(経験談)
WindowsリモートビルドのiOSビルド対応
iOSをビルドする際にWindowsからビルドができますが
署名などはMacが必要になります。
その場合、リモートビルドを設定することでWindowsで
ipaファイルを生成することができます。
基本的にはドキュメントのやり方に従えば問題ないです。
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/building-ios-projects-on-windows-in-unreal-engine
この作業に関しては別のエンジニアがほとんど対応を終えていて
MetalシェーダーのWindowsコンパイル対応などを行いました。
注意点として、WindowsからMacへのリモートビルドは
Macで直接ビルドするときと挙動が違い
WindowsでのリモートビルドだとUEのエンジン側で
提出に必要なplistの設定など行っています。
しかしMacで直接ビルドするとデフォルトの設定は
Xcodeの設定を参照してビルドされます。
そのため、Windowsでうまく行った環境でもMacでビルドすると
一部構成が変わることがありますので注意してください。
逆にWindowsでリモートビルドするとうまくいくのにMacでビルドすると、
うまくいかないケースなどもあります。
例えばplistの作成や設定などは、WindowsはXcodeのプロジェクト設定で
なくUnreal Engine側で作成したテンプレートを中心に設定を行いますが、Macビルドの場合はProject SettingsでModern XcodeがOnの場合にXcode側でplistの追加や設定が必要になったりしますので注意ください。
TestFlightなどを行うときは上記の違いに注意しましょう。
また、MacでMac版をビルドする場合は、ProjectSettings->Xcode Projectsの
Nac: Development Entitlements(なぜかUE側MacとNac誤字っている・・・)
Mac: Shipping Entitlements
でGame Centerなどの対応を記載しておくとよいです。
Game Centerのフレンド周りの追加実装
Unreal EngineではOnlineSubsystemのプラグインを使うと
様々なプラットフォームでネットワークサービスの機能を
共通で使うことができます。
この機能でSteamやEpic Online Servicesやゲーム機のプラットフォームの
オンラインサービスなどの対応を
共通のインターフェースで扱えるようになります。
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/online-subsystem-in-unreal-engine
ソースコードは、エンジン側の{EngineProjectPath}\Engine\Plugins\Online
にあります。
今回はAppleのGame CenterをUnreal EngineのOnlineSubsystemを
使って実装しましたがフレンド周りの機能が未実装の状態でした。
そのためフレンドの取得や読み込みをする作業を行ったので説明します。
前提としてApple系でiOSなどのネイティブの関数を
呼び出す必要があります。
呼び出しにはObjective-C++の記述が必要ですが、
Objective-C++はC++の中に記載できる言語になっています。
C++の中でObjective-C++を記載するときに注意点があります。
Game Centerの関数などを呼び出す場合に別スレッドで
読み込み待ちなどが発生してObjective-C++側でコールバックなどで
デリゲート関数を指定する必要があります。
そこにUnrealのデリゲートを呼び出すことは可能です。
ただし、Apple側のスレッドで実行されるためUnreal Engineのスレッドに
デリゲート呼び出し時に戻ってくるのですが
その際にクラッシュする可能性があります。
※NewObjectなどを実行していると発生しやすいです。
そのため基本的にはデリゲートを呼び出す場合は
フラグ更新などの小さい処理に留めて
World TimerなどのTimer処理でUE側でフラグの更新待ちを行い
Game Center側の処理を待つような実装をすると良いです。
FOnlineFriendsIOSにあるReadFriendsListを以下のように修正しました。
bool FOnlineFriendsIOS::ReadFriendsList(int32 LocalUserNum, const FString& ListName, const FOnReadFriendsListComplete& Delegate /*= FOnReadFriendsListComplete()*/)
{
UE_LOG_ONLINE_FRIEND(Verbose, TEXT("FOnlineFriendsIOS::ReadFriendsList()"));
FOnlineIdentityIOS* LocalIdentityInterface = static_cast<FOnlineIdentityIOS*>(IOSSubsystem->GetIdentityInterface().Get());
if (LocalIdentityInterface == nullptr) {
UE_LOG_ONLINE_FRIEND(Warning,TEXT("Local player not authenticated"));
Delegate.ExecuteIfBound(LocalUserNum, false, ListName, FString(TEXT("Local player not authenticated")));
return false;
}
GKLocalPlayer* GKLocalUser = LocalIdentityInterface->GetLocalGameCenterUser();
CachedFriends.Empty();
if (GKLocalUser != nil && GKLocalUser.isAuthenticated) {
FOnReadFriendsListComplete CopyDelegate = Delegate;
[GKLocalUser loadFriends:^(NSArray<GKPlayer *> * _Nullable friendPlayers, NSError * _Nullable error) {
if (error == nil) {
for (GKPlayer *friendPlayer in friendPlayers) {
// フレンドの情報を取得する処理
FString PlayerID = FString(friendPlayer.gamePlayerID);
FString PlayerDisplayName = FString(friendPlayer.displayName);
CachedFriends.Add(MakeShareable(new FOnlineFriendIOS(PlayerID, PlayerDisplayName)));
UE_LOG_ONLINE_FRIEND(Display, TEXT("Friend ID: %s, Display Name: %s"), *PlayerID, *PlayerDisplayName);
}
CopyDelegate.ExecuteIfBound(CachedFriends.Num(), true, ListName, FString(TEXT("Read FriendList Success")));
} else {
UE_LOG_ONLINE_FRIEND(Warning,TEXT("Game Center FriendList cannot be accessed %s"), *FString([error.localizedDescription UTF8String]));
CopyDelegate.ExecuteIfBound(LocalUserNum, false, ListName, FString(TEXT("Game Center read FriendList cannot be accessed")));
}
}];
return true;
} else {
UE_LOG_ONLINE_FRIEND(Warning,TEXT("Local player not authenticated"));
Delegate.ExecuteIfBound(LocalUserNum, false, ListName, FString(TEXT("Local player not authenticated")));
}
return false;
}
Game Centerのリーダーボードの修正(手伝い)
先ほど解説したOnlineSubsystemで共通化されている
リーダーボード(スコア機能)も追加対応が必要でした。
別のエンジニアが担当していたところでトラブルがあり
一緒に原因を探していました。
もともとあるOnlineSubsystemにあるWriteLeaderboardを使用しても
リーダーボードが書き換わりませんでした。
最初はアカウントなどが特別であるのかと思っていたのですが
調べてみると違うことがわかりました。
StackOverflowで同じ症状になっている方がいましたが
関数の引数が違っているという話でした。
https://stackoverflow.com/questions/65153511/gamecenter-scores-are-not-being-posted-to-the-leaderboard
エンジン側では以下のようなコードですが
[CachedLeaderboard submitScore:ScoreReportInt context:0 player:LeaderboardPlayer completionHandler: ^ (NSError *error)
これを以下のように修正して対応しました。
[GKLeaderboard submitScore:ScoreReportInt context:0 player:LeaderboardPlayer leaderboardIDs:nsLeaderboardID completionHandler: ^ (NSError *error)
差分としては「leaderboardIDs:nsLeaderboardID」を引数として
追加していることです。
macOSのGame Center対応
OnlineSubsystemは、iOSとtvOSでは、Game Center対応において
非常に有用なのですがmacOSでは対応した
Mac用のOnlineSubsystemはないため
Game Center対応を1から作る必要があります。
一応Macでも使用可能なAppleのOnlineSubsystemはあります。
OnlineSubsystemAppleというものなのですが
Apple IDのログインのみ実装されているため
Game Centerの機能はMac向けにないため、追加対応が必要になります。
今回はOnlineSubsystemAppleを改造して
Game Center機能を持つように修正しました。
MacでのGame Center対応ですが、iOS/tvOSは、OnlineSubsystemIOSがあり
こちらで必要機能が実装されています。
そのためMacでもOnlineSubsystemIOSの機能をベースにすれば
Game Centerの対応は可能です。
ただしコードを移植するだけでなく
macOSでOnlineSubsystemを使うために様々な作業が必要になります。
■OnlineSubsystemAppleの有効化
{MyProjectFolderPath}/Platform/Mac/MacEngine.iniに以下を追加
[/Script/Engine.Engine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemApple",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=Apple
[OnlineSubsystemApple]
bEnabled=True
エンジン側のプラグインでOnlineSubsystemApple.build.csにも修正が必要です
// ... Plugins/Online/OnlineSubsystemApple/Source/OnlineSubsystemApple.build.cs 19行目
else if (Target.Platform == UnrealTargetPlatform.Mac)
{
// TODO: Mark.Fitt enable Mac support
bSignInWithAppleSupported = true;
PublicFrameworks.AddRange(new string[]{"GameKit"});
PublicFrameworks.AddRange(new string[]{"AppKit"});
}
■OnlineSubsystemAppleの修正
基本的にはOnlineSubsystemIOSから必要なファイルをコピーして
IOSをAppleに置換すれば動きます。
注意点としては、OnlineSubsystemApple本体に追加したファイルを
つなぎこむ必要があります。
また、Macで実績UIなどを出す場合はiOSと実装がかなり異なるため
コードの修正や実装が必要です。
さらに、一部iOSでしか使えないライブラリなどをMac用に
置き換える必要もあります。
実績UI表示は、以下のような実装で動きました。
FOnlineExternalUIApple.cppを以下のように修正しました。
#if PLATFORM_MAC
@interface GameCenterManager : NSObject <GKGameCenterControllerDelegate>
+ (instancetype)sharedManager;
- (void)showAchievements;
@end
@implementation GameCenterManager
+ (instancetype)sharedManager {
static GameCenterManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)showAchievements {
GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];
gcViewController.gameCenterDelegate = self;
gcViewController.viewState = GKGameCenterViewControllerStateAchievements;
auto mainWindow = [[NSApplication sharedApplication] mainWindow];
[mainWindow.contentView addSubview:gcViewController.view];
gcViewController.view.frame = ((NSView*)mainWindow.contentView).bounds;
GKDialogController *presenter = [GKDialogController sharedDialogController];
presenter.parentWindow = mainWindow;
NSApplication *app = [NSApplication sharedApplication];
NSWindow *window = mainWindow;
[window.contentViewController presentViewControllerAsModalWindow:gcViewController];
}
// GKGameCenterControllerDelegate methods
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController {
}
@end
#endif
bool FOnlineExternalUIApple::ShowAchievementsUI(int32 LocalUserNum)
{
#if PLATFORM_MAC
// Call the Objective-C method
[[GameCenterManager sharedManager] showAchievements];
#endif
return false;
}
その他上記以外にも色々細かい対応をしていきました。
iOSAsyncTaskを呼び出しているところをAppleAsyncTaskを新しく作り対応
UIViewControllerなどiOS用のUIKitで呼び出していた処理をNSApplicationに置き換え
XcodeのCapabilitiesでGame Center機能を有効化
Game Centerのentitlements.plistの修正
「WindowsリモートビルドのiOSビルド対応」の項目で述べた作業です
以下のプロジェクト設定のXcode Projects項目で変更できます
Mac: Shipping EntitlementsとNac: Development Entitlements
Unreal Engineの以下のTechブログも大変参考になりました。
https://www.unrealengine.com/ja/tech-blog/integrating-unreal-into-apple-s-mac-ecosystem
tvOSのGame Center対応
tvOSでもGame Centerのトップ画面などのUIが表示されないという
不具合が発生していました。
原因は、UE側の処理の問題でiOSのみでGame Centerの画面表示を
行っていたのが原因でした。
なぜそうなっていたかですが、iOSとtvOSでもUIの呼び出し方が
微妙に異なるようでUnreal Engineでは、こうした処理を呼び出し処理を
ベタ書きでなくinterfaceとclassにして実装していたようなので
tvOS用のOS切り分けが難しかったように見えます。
今回は、決まった画面だけ呼び出したいので以下のような感じで呼び出します。IOSAppDelegate.cppを以下のように修正します。
/**
* Show the achievements interface (call from iOS main thread)
*/
-(void)ShowAchievements
{
#if !PLATFORM_TVOS
// create the leaderboard display object
GKGameCenterViewController* GameCenterDisplay = [[[GKGameCenterViewController alloc] init] autorelease];
[GameCenterDisplay initWithState : GKGameCenterViewControllerStateAchievements];
GameCenterDisplay.gameCenterDelegate = self;
// show it
[self ShowController : GameCenterDisplay];
// 上記までは、エンジンコード
// 以下修正コード
#elif PLATFORM_TVOS
GKGameCenterViewController* GameCenterDisplay = [[[GKGameCenterViewController alloc] init] autorelease];
if (GameCenterDisplay != nil)
{
GameCenterDisplay.gameCenterDelegate = self;
// slide it onto the screen
[[IOSAppDelegate GetDelegate].IOSController presentViewController : GameCenterDisplay animated : YES completion : nil];
}
#endif // !PLATFORM_TVOS
// 修正コード終わり
}
iOSのアクセス許可ダイアログの表示
Appleはユーザーの個人情報にゲームがアクセスする場合に
アクセス許可ダイアログを表示してユーザーから許可を
得る必要があります。
これはiniを編集すると表示されます。
例としてフレンド情報を取得するアクセス許可ダイアログが
以下になります。
Platform/iOS/iOSEngine.iniとPlatform/tvOS/TVOSEngine.ini
を修正してください。
;iOS/tvOSどっちのIOSRuntimeSettingsです
[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
AdditionalPlistData=<key>NSGKFriendListUsageDescription</key>\\\\n<string>XXX機能のためにフレンド情報にアクセスします。</string>
アクセス許可ダイアログのローカライズ方法
多言語向けにリリースする場合は、アクセス許可ダイアログの
翻訳が必要です。
こちらは、特定の場所にファイルを配置してローカライズ可能です。
注意点があり以下のファイルのみ対応しています。
InfoPlist.strings
上記のファイルを言語コードごとに作り
Build/IOS/Resources/{言語コード}.lproj/
へ配置してください。
詳しくは公式のドキュメントにまとまっています
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/localize-plist-and-nslocalizedstring-in-an-ios-project
またリモートビルドでは、場合によってファイルが
パッキングされない場合があります。
その場合は、エンジンの改造が必要です。
IOSToolChain.csのPackageStub関数でLocalizationsフォルダを
ディレクトリごとコピーする処理を差し込んでください。
特定iPhone端末でメモリ周りでクラッシュする
特定のiPhoneでクラッシュする報告がありました。
クラッシュログを調べてみるとアセンブリなので分かりづらいのですが
メモリアロケーション周りでクラッシュしているようでした。
どうしてもわからず調べまくっていたところAWSのマニュアルにヒントが
ありました。
https://docs.aws.amazon.com/ja_jp/gamekit/latest/UnrealDevGuide/launch-package-ios.html
以下を{MyProject}.Target.csに入れたところ動くようになりました。
確かにiOSは調べてみるとファイルシステムやメモリ管理をOSごとに
刷新することがありそうしたことが原因で発生しているようでした。
そのためメモリ管理システムをUE独自でなく
OSのアロケーションに任せることで解決しました。
余談ですが、エンジン側のMacビルドでも同様のコードが
呼ばれていました。(UEBuildMac.csで記載されてました)
if (Target.Platform == UnrealTargetPlatform.IOS)
{
GlobalDefinitions.Add("FORCE_ANSI_ALLOCATOR=1");
}
その他いろいろなトラブル対応
以下のようなトラブルが発生して対応しました。
■MacPCでビルドすると容量が足りなくなってしまう
Windowsよりも容量を占有します。特に3端末(Mac、iOS、Apple TV)
対応する場合は注意です。
1TB容量のM3 ProのMacBookで作業しましたがすぐにいっぱいに
なってしまいました。
要因としては以下のものがありました。
UE本体をソースコードビルドすると中間生成ファイルが大量にできる
プラットフォームの対応CPUに応じた中間生成ファイルが作られる
例えばMacはArmとIntelで中間生成ファイルが作成される
上記のファイルがDevelopment/Shippingなどビルドに応じてそれぞれでファイルが生成される
生成される実行ファイルが3つできる(StageBuild/Binaries/OutputFolderで3つできている)
上記は容量は違いますがWindowsでも発生する問題ですが
Macでは追加で以下の問題が発生します。
Xcodeがキャッシュを大量にとる
プロジェクトのindexファイルが40~70GBになる
Mac/iOS/tvOSでプロジェクトが分かれているため3倍増えて120GB以上取っていたりする
提出用ファイルをUEで作ると開いた際にXcode側でキャッシュする
提出ファイルはdsymを入れるため実際の容量の3倍ぐらいのサイズになる
3GBなら10GB近くなる
それが開くたびに増えていく
XcodeでビルドやデバッグをするとアプリをXcode側が別途キャッシュすることがある
macOSと端末を接続した際に本体のデバッグデータがコピーされる
(例えば端末Aと端末Bと端末Cをつなぐと最低9GB増えている)
MacでUnreal Engineを扱う場合は外付けSSDを用意して
プロジェクトを入れるか2TB以上の本体サイズにしましょう。
また、Xcodeが無尽蔵にキャッシュをとるため定期的に削除しましょう。
Xcodeの不要なキャッシュについては以下のサイトが参考になりました。
https://qiita.com/shtnkgm/items/c96a58579ec406194fa8
Xcodeはキャッシュの保存先を変更できずMac本体に保存されるので
特に注意が必要です。
一応再起動するとXcodeのキャッシュはある程度削除してくれるため
定期的に再起動することである程度防げます。
MacBookは、調査でビルドすることと持ち出して移動なども多かったため
最終的に必要なプラットフォーム以外は
キャッシュやビルドファイルを消しておき
帰宅時に次のプラットフォームのビルドをするなどの対処をして
容量を空けるようにしました。
ビルドマシン用でMac miniがありましたが
こちらは外付けSSDを使うことでこの問題を回避することができました。
(しばらくするとXcodeキャッシュでストレージが再びいっぱいになるため定期的に削除していました)
今回、3機種対応したことが容量をさらに圧迫する原因に
なっていたと思います。
3機種対応する場合は、ストレージの確保に注意してください。
■画面がぼけてしまう
拡大した際にぼけないようにしたいと要望があり調査しました。
ぼけてしまう原因は、AAとアップスケール、画像設定が原因でした。
DefaultEngine.iniを以下を設定するとにじみやぼやけなしで拡大されます。
r.AntiAliasingMethod=0
r.Mobile.AntiAliasing=0
r.Upscale.Quality=0
これでエディタ上では、拡大してもぼけることはなくなりました。
しかし、パッケージビルドをするとなぜテクスチャがぼけてしまう
トラブルがありました。
原因は、画像設定は、TextureのFilterをDefaultでなく
Nearestにする必要があります。
ややこしいことにEditor上だとDefaultでもぼけなくなるため
パッケージ化する際と挙動が違いました。
このあたりは、パッケージ側でテクスチャ表現がおかしいと思ったら
Filter設定を明示的に指定が必要なようです。
海外でも似たような問題に総合して対処している記事があったので紹介しておきます。
https://weareludicrous.com/blog/2018/3-tricks-to-improve-pixel-art-rendering-in-ue4/
■XcodeでデバッグするとFStringやFNameがウォッチ式で表示されない
Macのホームディレクトにある.llbdinitの設定が正しくないときがあります。
GenerateCommanを実行するとlldbinitに自動で必要なファイルを登録するのですが
カスタムビルドだと上手くパスが作られないようです。
以下のフォーラムを参考にしました
https://pafuhana1213.hatenablog.com/entry/2018/12/13/031521
UE5だとファイル名が変わっています。
以下のように.lldbinitに追記してください。
(ターミナル開いて open .lldbinitで開くと思います
command script import "{UnrealEngineSourceCodeProjectPath}/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py"
これで、Xcodeでも実機デバッグ中に
FStringやFNameの変数を確認できるようになります。
最後に
Unreal EngineでiOSやApple端末の開発を初めて行いましたが
自前で実装する要素が多く想定よりも苦労しながら進めました。
Apple対応もここで載せていない対応やトラブルも発生して
非常にやりがいがありました。
対応は大変でしたがUnrealEngineは、エンジン側のコードが見れるのと
Unreal Engineのフォーラムだけでなく
Apple DeveloperフォーラムやStack Overflowなど
参考になる情報が多かったので
Game Centerの対応や不具合の対応なども進めることができました。
個人的に一番大変だったのは実機でのデバッグでした。
Xcodeでブレークポイント付きでデバッグできますが
IDEはシンタックスも利かない上にcppファイルがプロジェクトに
含まれていないので外部ファイルとしてブレークポイントを
貼りたいデータを読み込んでくる必要があったりして
色々な作業が発生しました。
Riderでもエディターの立ち上げやビルドはできるのですが
iOSビルドなどでデバッグするのはできなかったので
このあたりはまだXcodeが必要そうです。
逆にプロファイルはより深いところまでツールで
見ることができたので助かりました。
Unreal InsightsやSession Frontendだけでなく
Xcode Instrumentsも使いましたが
Timer ProfilerなどはMetalの深い処理まで見れたので結構参考になりました。
(Timer ProfilerだとMetal側のSetTexture処理までプロファイルで確認することができた)
3ヶ月ほどiOSの開発をさせていただきましたが同時並行で
別のタイトル(GOMAN)のPS版の審査提出や
パッチのアップデート対応なども進めつつ
Apple対応も行っており、大変でしたが無事対応できてよかったです。
普段のゲーム実装では学べない領域や仕組みなどを調べたり実装することが
できたのでとても有意義に作業ができたと感じています。
今回、紹介した内容が今後の参考になればと思います。
最後に宣伝ですが、株式会社ブラストエッジゲームズでは
プラットフォームの対応などもやってみたい方や得意な方も含めて
一緒に開発してくれる仲間を絶賛募集中です!
会社へのエントリーもお待ちしてます!
https://www.blastedge-games.co.jp/recruit
一緒にUnreal Engineでゲームを作りましょう!
今回の知識が少しでも皆さんのゲーム開発に役立てばと思います。
では皆さん良いゲーム開発を!