#ARLyra 遂に悲願の、影ポリが見えない綺麗なAR shadowが出来た!!😆 禁断のエンジンシェーダーいじりしちゃったけど、実現出来る事が分かったのは大きい。
— LazyKozy (@LazyKozy) January 24, 2024
あとAIもちょっと修正して、遊べるようになった…、か?😅#UnrealEngine #UE5 #AR #ARCore #Pixel7 pic.twitter.com/L6EYwhOZ7V
はじめに
ARグレイマンを歩かせてみよう!!
さて、この記事を投稿したのがなんと3年前
諸般の事情でまた自由時間が出来てしまったので😥
Lyraの調査ついでに、世界初(たぶん😅)Lyra ARサポートをさせてみました。Lyraそのまま動いてるのでちゃんと(?)FPSとして遊べます。懸案事項のAR Shadowも表示されてます😆
Lyra サンプル ゲームに関してはUnrealの公式ドキュメントを見て下さい。
開発環境
UE5.3.2
デバイス Pixel7 (ARCore)
とりあえず縦画面
やっぱARは縦画面だよね! という事でとりあえずAndroidビルドを縦画面化してみましょう。
[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
Orientation=Portrait
[/Script/Engine.UserInterfaceSettings]
ApplicationScale=2.000000
\Plugins\GameFeatures\ShooterCore\Content\UserInterface\W_ShooterHUDLayout.uasset
レイアウトはこのウィジェットで定義されているので、いい感じにレイアウトを変更します。
これでAndroidで縦画面になりました!!
ARモードをスタート
[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
bSupportsVulkan=False
私の知る限り、未だにAndroid-VulkanではARモードは起動しません
どのタイミングでAR Sessionをスタートさせるのかどうかは、ゲームによって変わると思いますが、とりあえずB_LyraPlayerController
を新規作成してBeginPlay
からスタートさせました。
Godモード、Postprocessをオフ、AR World Originを変えてカメラの位置を目線にセットしています。
これをB_LyraGameMode
にセットします。
AR Shadowを設定
[/Script/Engine.RendererSettings]
r.AllowStaticLighting=True
r.Shadow.Virtual.Enable=0
r.Mobile.EnableStaticAndCSMShadowReceivers=True
とりあえず私のコンフィグの変更はこんな感じです、以下のサイトなどが参考になります。
TIP: How to enable Dynamic Shadows & Correct Reflection Maps on mobile
ShadowMesh
を作って、丸影マテリアル/テクスチャをセット。AIキャラやネットワークキャラはこの丸影を使います。
これを\Plugins\GameFeatures\ShooterCore\Content\Game\B_Hero_ShooterMannequin.uasset
のコンポーネントに追加します。
ローカルキャラクターにはAR Shadowを適用します。マテリアルは以前の記事に沿って作ります。
ARグレイマンを歩かせてみよう!!
キャラクターBPに少し変更を加えます。
Event Possessed
に追加。Begin Play
ではIsLocalPlayerController
が取得出来ないので、ここに足します。
Event Tick
に追加。AR Shadowの更新と、ジャンプした時にShadowMesh
が常に地面に張り付く処理を足します。
AR Shadow用にシェーダーを変更
影ポリがライティングの影響を受けて、微妙に影ポリが見えてしまう問題が、どーーうしても解決出来なかったので、EngineのShaderをちょっと変更してしまいました
あまり褒められたやり方ではないので参考程度に…。
UE5.3 \Engine\Shaders\Private\MobileBasePassPixelShader.usf
Line:890
UE5.4 \Engine\Shaders\Private\MobileBasePassPixelShader.usf
Line:989
辺りに、これを追加。
影が落ちたピクセルは必ず暗くなるので、ライティング適用前のピクセルを比べて明るくなっている場合は除外させます。この変更を使ってないClearCoatにのみに適用させます。
#if MATERIAL_SHADINGMODEL_CLEAR_COAT
DirectLighting.TotalLight.r = min(DirectLighting.TotalLight.r, BaseColor.r);
DirectLighting.TotalLight.g = min(DirectLighting.TotalLight.g, BaseColor.g);
DirectLighting.TotalLight.b = min(DirectLighting.TotalLight.b, BaseColor.b);
DirectLighting.TotalLightDiffuse = 0;
DirectLighting.TotalLightSpecular = 0;
#endif
それから、ShadowマテリアルをClearCoatに設定します。
入力スキームを変更
二本スティックモードでラジコンみたいに動す事は出来るのですが、これだとARっぽくないので常にカメラの前にキャラクターが移動するようにしてみました。
もの凄く大雑把に言うとこんな感じです。
void ALyraPlayerController::PlayerTick(float DeltaTime)
{
...
// ターゲットに移動
if (StartMoveDist*StartMoveDist < DistSquared2D)
{
UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, MoveTargetLoc);
// キャラクターの向きをカメラと同じに
{
bAutoManageActiveCameraTarget = true;
CurrentPawn->FaceRotation(PlayerCameraManager->GetCameraRotation());
Rifle/ShotGunの発砲をタッチ操作で行えるようにする
Winビルドだと発砲出来るのに、タッチ操作にするとRifle/ShotGunの発砲が出来ない問題で悩んでいたのですが、これの追加で解決しました。
\Content\Input\InputData_Hero.uasset
IA_Weapon_Fire_Auto
がタッチ操作では発行されないのが問題でした。正しい解決法とは言えるかどうかは微妙ですが、まあとりあえずオッケーでしょ
マップを設定
\Plugins\GameFeatures\ShooterCore\Content\Maps\L_ShooterGym.umap
このマップから余分なオブジェを削除して作りました。グラウンドはHideInGame
にします。
TIP: How to enable Dynamic Shadows & Correct Reflection Maps on mobile
ライトの設定に関してはこの投稿が参考になります。
重要なのは、以下の通りです。
-
LightmassImportanceVolume
を置く -
SkyLight
はStatic
。Cast Shadows = false
-
DirectionalLight
はMovable
。Cast Shadows = true
Cast Dynamic Shadows = true
- レベルのビルドをする。
とりあえず動きました!!
最初のムービーの様にとりあえず動いてます。
ちなみにGodモードを外すとAIに秒殺されます
まあやっぱりフルFPSをARでプレイさせるのは無理があるので、ポケモンGoみたいなスタイルか、目の前の相手とやり合うテニスみたいなゲーム以外は難しいですねぇ
もうちょっとちゃんとプレイ出来るようにしてみたいのですが、シングルプレイだとAIをがっつりと変えなきゃいけませんね。
マルチプレイは簡単なはずですが携帯を一台しか持ってないからテスト出来ない…。Windows<->Androidでのクロスプレイなら、自分一人でもテスト出来るかも?
あとSceneDepthForOcclusion
が上手く動きませんでした これは要調査事項です。