概要
Windowsのゲームで画面サイズを16:9に固定して余白は黒で塗りつぶしたい。いわゆるレターボックス対応したいときの方法をメモっときます。
DPICustumScaleを設定する
まず最初にDPI Scalingをカスタマイズします。
プロジェクトにDPI_CustumScalingRuleの継承クラスを作成します。
クラスの中身はこんな感じ。
画面サイズはとりあえず1920x1080に決め打ちです。プロジェクトに合わせて変更してください。
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DPICustomScalingRule.h"
#include "MyDPICustomScalingRule.generated.h"
/**
*
*/
UCLASS()
class LETTERBOX_API UMyDPICustomScalingRule : public UDPICustomScalingRule
{
GENERATED_BODY()
public:
virtual float GetDPIScaleBasedOnSize(FIntPoint Size) const override;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyDPICustomScalingRule.h"
float UMyDPICustomScalingRule::GetDPIScaleBasedOnSize(FIntPoint Size) const
{
#if PLATFORM_WINDOWS
if (Size.X > 0 && Size.Y > 0)
{
float ax = Size.X / 1920.f;
float ay = Size.Y / 1080.f;
return FMath::Min(ax, ay);
}
#endif
return 1.f;
}
クラスができたらコンパイルして、プロジェクトに設定します。
編集->プロジェクト設定 を開き、User InterfaceのDPI Scalingに設定します。
DPI Scale RuleをCustom
Custom Scaling Rule Classに作成したクラスを指定。
カメラの設定
レターボックス状態、余白を黒で塗りつぶした状態にするには、カメラのフラグを設定する必要があります。プロジェクト用にGameMode,PlayerController,PlayerCameraManagerのBPクラスを作成し、ワールドセッティングに設定します。
作成したPlayerContollerの Player Camera Manager Classに作成したPlayerCameraManagerを設定
PlayerCameraManagerの Default Constrain Aspect Ratioにチェック
以上の設定でレターボックスが有効になります。
デフォルトの画面サイズを1920x1080(16:9)にしたので、画面サイズをどう変更しても、ゲーム画面は16:9になり、余白は黒で塗りつぶされます。
UMGのアンカー問題
これでレターボックス表示ができた!と喜んだのもつかの間、UMGのレイアウト問題が浮上します。UMGのアンカーで画面端を指定した場合、レターボックスではなく、実際の画面の端に吸着してしまいます。
実はこれも回避法があって、WidgetをAdd to Viewportで画面に追加すると、画面全体からアンカーを計算します。
これをAdd to Player Screenに変えると
このとおり、表示範囲に吸着します。
Add to Player Screenで解決?
ほとんどの場合はこれで大丈夫なのですが、Add to Player ScreenはLocal Playerが存在しないと機能しません。実際に困ったケースは、ゲームのロード画面を表示するタイミングではLocal Playerが存在せずにうまく表示されない事がありました。その時は時間がなかったのでエンジンに手を入れて無理やり対応しましたが、そういうケースもあるということを覚えて置くと良いかもしれません。