FC2ブログ

ゾンビ/Unity/あと何か

ゾンビや気になったオカルトネタ、Unityでのゲーム制作についてつづるブログです。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【UE4】 SNewって何?

Slate_DetailsPanelCustomize.png

要な説明がアンリアルエンジンのソースコードに書かれている
ソースコードのダウンロード方法は以下
[UE4] エンジンのソースコード取得とビルド手順のまとめ UE4.6改訂版
http://historia.co.jp/archives/1327/

ソースコード見るだけならビルドは必要ないので、GitHub登録してEpicアカウントで接続済みアカウントのGitHubアカウントを入力してあれやこれや(上記の記事参照)

で、SNew と SAssignNew について書かれているソースコード(厳密にはヘッダファイル)の場所は以下

Engine/Source/Runtime/SlateCore/Public/Widgets/DeclarativeSyntaxSupport.h

必要な部分を抜粋
/**
* Slate widgets are constructed through SNew and SAssignNew.
* e.g.
*
* TSharedRef MyButton = SNew(SButton);
* or
* TSharedPtr MyButton;
* SAssignNew( MyButton, SButton );
*
* Using SNew and SAssignNew ensures that widgets are populated
*/


#define SNew( WidgetType, ... ) \
  MakeTDecl<WidgetType>( #WidgetType, __FILE__, __LINE__, RequiredArgs::MakeRequiredArgs(__VA_ARGS__) )
    <<= TYPENAME_OUTSIDE_TEMPLATE WidgetType::FArguments()

#define SAssignNew( ExposeAs, WidgetType, ... ) \
  MakeTDecl<WidgetType>( #WidgetType, __FILE__, __LINE__, RequiredArgs::MakeRequiredArgs(__VA_ARGS__) )
  . Expose( ExposeAs ) <<= TYPENAME_OUTSIDE_TEMPLATE WidgetType::FArguments()

使い方は冒頭のコメント内に書かれている
スレートのインスタンスを生成して、そのまま変数に代入するとか、すぐに使いたい場合は SNew
どっかで変数を宣言しておいて、あとでその変数にスレートのインスタンスを割り当てたいときは SAssignNew
SNew と SAssignNew の違いは、インスタンスをすぐに使うか?あとで使うか?で使い分ければいいっぽい

056245.png



WidgetType


SNew と SAssignNew の WidgetType に指定できるものは以下(未検証含む)

SButton
プッシュボタンを表示する
例) SNew(SButton).Text(FText::FromString("ボタンに表示する文字"));

SCheckBox
チェックボックスを表示する
例) デフォルトでチェック状態にする
TSharedRef<TAttribute<ECheckBoxState>> a = MakeShareable(new TAttribute<ECheckBoxState>(ECheckBoxState::Checked);
SNew(SCheckBox).IsChecked(*a);

SComboBox
コンボボックスを表示するための型だが、SNew にそのままブチ込んでもうまく行かない
コンボボックスのサンプル→Slate SComboBox example
上記サンプルソースで定義してる SMyCombo を使う SNew(SMyCombo) でOK

SEditableLabel
編集可能なラベルを表示する
ラベルをダブルクリックすると編集できる状態に切り替わる
こうしないと正常に動作しない模様→http://bosukete666.blog.fc2.com/blog-entry-306.html

SHyperlink
ハイパーリンク(クリックするとリンク先にジャンプできるテキスト)を表示する
例) SNew(SHyperlink).Text(FText::FromString("http://www.google.com"))

SInputKeySelector
キーを割り当てるパーツを表示する
ボタンを押して何らかのキーを押すと、そのキー名がボタンに表示されるようになる
キーコンフィグ画面で使えそう
例)
TSharedRef<FInputChord> i = MakeShareable(new FInputChord(TEXT("A"), false, false, false, false));
SNew(SInputKeySelector).SelectedKey(*i)

SMultiLineEditableTextBox
複数行の編集可能なテキストボックスを表示する
例) SNew(SMultiLineEditableTextBox)

SSearchBox
検索ボックスを表示する
こうしないと正常に動作しない模様→http://bosukete666.blog.fc2.com/blog-entry-308.html

SRotatorInputBox
Rotator(角度を指定する)の入力ボックスを表示する

SSlider
スライダーを表示する
例) SNew(SSlider)


以下、未検証

SComboButton
SComboBoxの親クラス 直接使うことはなさそう(なさそう)

SEditableText
編集可能なテキスト(ラベルとの違いは不明)を表示する

SEditableTextBox
編集可能なテキストボックスを表示する

SExpandableButton
伸縮可能なボタンを表示する?

SMenuAnchor
メニューへのアンカー(クリックすると指定したメニューの項目にアクセスする?)を表示する

SNumericDropDown
数値のドロップダウンリスト?を表示する

SRichTextHyperlink
リッチテキスト形式のハイパーリンクを表示する

SSpinBox
スピンボックス?を表示する

SSubMenuHandler


SSuggestionTextBox
提案(ヒント?)テキストボックスを表示する

STextComboBox
テキストのコンボボックスを表示する

STextComboPopup
テキストのコンボポップアップ?を表示する

STextEntryPopup
テキストエントリーポップアップ(なんのことやら)を表示する

SVectorInputBox
ベクトル値(X、Y、Z)を入力するボックスを表示する

SVirtualJoystick
バーチャルジョイスティックを表示する?

SVirtualKeyboardEntry
バーチャルキーボードエントリーを表示する?

SVolumeControl
ボリュームコントロールを表示する

上記クラスのメンバ一覧は http://api.unrealengine.com/INT/API/Runtime/Slate/Widgets/Input/
これらのヘッダファイルは Engine/Source/Runtime/Slate/Public/Widgets/Input/ にある
よく使いそうなのは SButton SCheckBox SComboBox SEditableTextBox あたりか
SButton を使いたいなら、#include "SButton.h" が必要

056245.png



スレートを使って詳細パネルカスタマイズ


ず知っておくべきことが1つある

Epic公式に、スレートを使って詳細パネルをカスタマイズする方法が書かれたドキュメントがある
公式ドキュメントなら間違いないだろうと思って参考にして、ドキュメント通りにやってみたが全くうまく行かない
何が悪いのかを調べたところ、公式ドキュメントが間違っていたことが分かった
公式ドキュメントだからといって、正確である保証はない

スレートの使い方がある程度分かってからなら、参考になりそうな記事は山ほどあるが、何も知らない状態で参考になるような記事はほとんどない
だもんで、何も知らない状態で参考になるような説明を書いておく(己の幸福のために)


詳細パネルカスタマイズをするのに必要な下準備

1.UE4→新規追加→新規C++クラス→親はとりあえずUObjectにしとく
2.プロジェクトがあるフォルダを表示→Source/プロジェクト名/プロジェクト名.Build.csをテキストエディタかVisualStudioで開く
3.→のような記述がある行を PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Slate", "SlateCore", "EditorStyle" }); このように書き換えて保存
4.UE4→「コンパイル」ボタンを押す

ソースファイルを一切変更してないのでコンパイルは成功するはず
失敗するとしたら、3.でコピペミスしてる可能性が高い


詳細パネルカスタマイズをするソースコード

以下は何かのブループリント編集画面を開いたとき、詳細パネルに表示される項目をカスタマイズするサンプルソース
既存の項目を全て非表示にして、自前のカテゴリに自前のチェックボックスを表示させる

新規作成したC++のヘッダファイル(.h)を以下のように書き換える
#pragma once

#include "CoreMinimal.h"
#include "IDetailCustomization.h"
#include "IPropertyTypeCustomization.h"

class クラス名 : public IDetailCustomization, public IPropertyTypeCustomization
{
public:
  static TSharedRef<IDetailCustomization> MakeInstance();
  virtual void CustomizeDetails(IDetailLayoutBuilder&) override;
}

新規作成したC++のソースファイル(.cpp)を以下のように書き換える
#include "クラス名.h"

TSharedRef<IDetailCustomization> クラス名::MakeInstance() { return MakeShareable(new クラス名); }

void クラス名::CustomizeDetails(IDetailLayoutBuilder& layout)
{
  //既存の項目を非表示にする
  layout.HideCategory("Rendering");
  layout.HideCategory("Input");
  layout.HideCategory("Actor");
  layout.HideCategory("Transform");
  layout.HideCategory("Tick");
  layout.HideCategory("Replication");

  IDetailCategoryBuilder&
    c = layout.EditCategory("てきとうに1", FText::FromString("カテゴリ名"), ECategoryPriority::Important);
  TSharedRef<TAttribute<ECheckBoxState>>
    a = MakeShareable(new TAttribute<ECheckBoxState>(ECheckBoxState::Checked));
  c.AddCustomRow(FText::FromString("てきとうに2"))
    .NameContent()[ SNew(STextBlock).Text(FText::FromString("項目名")) ]
    .ValueContent().MinDesiredWidth(50)[ SNew(SCheckBox).IsChecked(*a) ];
}

書き間違いがなければ、これでコンパイルとリンクが通るはず

UE4は、この時点では、これが詳細パネルをカスタマイズするソースコードだと知らない
UE4にとってみると、なんだかよく分からないソースコードをコンパイルさせられただけで、その使い道が分かってない
なので、UE4に対して「このブループリント編集画面を開いたときに詳細パネルをこのように変更しろ!」という指示をどこかに書く必要がある


特定のブループリント編集画面を開いたときに詳細パネルを変更する指示を出す

指示の出し方はいくつかあるようで、私が試したのは、自前のGameModeクラスのコンストラクタでやる方法
自前のGameModeクラスはC++で作る
特定のブループリントの詳細パネルをカスタマイズするので、適当なブループリントクラスを新規で作り、それに対して指示を出す
全てのブループリントクラスの詳細パネルをカスタマイズする方法は分からない

1.UE4→新規追加→Blueprint Class(親は何でも良い)
2.UE4→新規追加→新規C++クラス(親はAGameModeBase、クラス名はMyGameModeとする)
3.UE4→編集→プロジェクト設定→Project - マップ&モード→Default GameMode→MyGameMode
4.MyGameMode.h にコンストラクタの宣言を追加
5.MyGameMode.cpp を以下のように書き換える
#include "MyGameMode.h"
#include "PropertyEditorModule.h"
#include "クラス名.h"

MyGameMode::MyGameMode()
{
  //詳細パネルのカスタマイジング
  FPropertyEditorModule& p = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
  p.RegisterCustomClassLayout("1で作成したブループリント名_C",
    FOnGetDetailCustomizationInstance::CreateStatic(&クラス名::MakeInstance));
}

6.UE4→「コンパイル」ボタンを押す

コンパイルが通れば、1で作成したブループリント編集画面を開いたとき、詳細パネルの内容が変わる
1のブループリントをレベルに配置し、クリックしたときの詳細パネルも同様に変わる

UE4エディタで見る限り、ブループリント名の末尾に _C(アンダーバーC)はついていないが、UE4内部では _C を付けて管理しているようで、C++からブループリントに対して何らかの指示を出す場合、ブループリント名_C と書かなければいけないようだ(ようだ)

UE4_Slate_DetailsPanelCustomize2.png

何も知らない状態で参考になったのは以下の記事
Customizing detail panels(英語)
https://wiki.unrealengine.com/Customizing_detail_panels

[UE4 エディタ拡張] 詳細パネルで UStruct のプロパティカスタマイズ
https://qiita.com/negimochi/items/bf67d7b1f9009c961178

ボタンを激しく連打するとD言語くんが大暴れする UE4 エディタ拡張
http://rarihoma.xvs.jp/2015/12/03/1

ヒストリア様がスレートとプラグインを使ってカスタムウインドウを表示させる、ありがた~い記事を書いている
この先、自前のウインドウを表示してあれやこれやする機能を作ることになりそうなので、それらの記事のリンクを貼っておく
[UE4] プラグインによるエディタ拡張(1) 空のプラグインを追加する
[UE4] プラグインによるエディタ拡張(2) エディタのメニューに項目を追加
[UE4] プラグインによるエディタ拡張(3) SlateUIを使用してウィンドウを作成する
※知人によれば、ヒストリアは日本で一番アンリアルエンジンに詳しい会社だそうです
スポンサーサイト

- 0 Comments

Add your comment

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。