PaperSloth’s diary

主にゲーム開発関連についての記事を書きます。

UE4 敵の頭上に表示されるHPバーの実装方法

環境

UE4.25.3

完成イメージ

f:id:PaperSloth:20200923191904p:plain

実装方法

Widgetの用意

まずはHPバーとなるWidgetを用意します。
今回は「WBP_HealthGauge」という名前でWidgetを作成しました。
「Progress Bar」を置くだけです。
f:id:PaperSloth:20200924013650p:plain

Anchorを中心に設定し、おおまかなサイズとAlignmentを設定しておきます。
f:id:PaperSloth:20200924021434p:plain

また、初回はHPゲージを満タンで表示したいため「Percent」を1.0に初期化しておきます
f:id:PaperSloth:20200924014936p:plain

後ほどBlueprintで更新処理を作成しますが、まずは見た目だけ。

敵のBlueprintにWidgetを設定

敵のBlueprintは既に存在するものとして進めます。

新規にComponent追加で「Widget」Componentを追加します。
f:id:PaperSloth:20200924013908p:plain

Widgetを追加したら、表示位置をちょうど敵のActorの頭上にくるように調整して
先程設定したWidgetWidget Classに設定します。
ここでは「WBP_HealthGauge」という名前で先程のWidgetを作成したためそれを設定します。
また、Speceの欄は「World」から「Screen」に変更しておきます。
f:id:PaperSloth:20200924015121p:plain

ここまでで実行すると以下のような感じになるかと思います。
f:id:PaperSloth:20200924015031p:plain

HPバーの更新処理

続いて敵のHPバーを更新をする処理を追加していきます。
まずは先程作成したWidgetのBlueprintを開き、新規に関数かCustom Eventを作成して以下のように処理を組みます。
ここでは「UpdateHealthProgress」というCustom Eventを追加しました。
f:id:PaperSloth:20200924014711p:plain

次は敵のBlueprintに戻ってHP更新処理を組んでいきます。
WidgetのBlueprintへの参照情報を取得したいため、「Get User Widget Object」でWidgetを取得して
「WBP_HealthGauge」にCastし、新規に「WBPHealthRef」という変数を作成して変数に保存しておきます。
f:id:PaperSloth:20200924015245p:plain

型情報とか諸々がよく分からないという場合もPin上で右クリックで変数に昇格することで自動的に型情報を補完してくれます。
f:id:PaperSloth:20200924015416p:plain

続いてHPと最大HPの変数を2つ追加します。
「Health」と「MaxHealth」を追加し、それぞれ100.0で初期化しました。
f:id:PaperSloth:20200924020039p:plain

f:id:PaperSloth:20200924020053p:plain

次に実際にダメージを受けた時の処理を組みます。
まずはダメージを受けると現在のHPから引いてHPを更新します。
「Max (0.0)」を挟むことで0以下になった場合には0になるように設定できます。
(0以下になったら0 にするという組み方でも何も問題はないです)
f:id:PaperSloth:20200924020345p:plain

スクショを撮る都合上長いのでMathExpressionでまとめておきます。
余談ですが、MathExpressionでは変数名をExpression内で使用すると自動的に参照してくれます。
f:id:PaperSloth:20200924020533p:plain

ダメージ計算後は死亡判定を行います。
残りHPが0 未満になった場合は0 になるように設定したため、Nearly Equal で0と近い値かどうかを判定します。
Trueの場合は死亡処理、Falseの場合はHPバーの更新処理を行うようにします。
f:id:PaperSloth:20200924020846p:plain

次にHPバーの更新処理と死亡処理です。
現在HPと最大HPの割合を計算してWidgetのProgress BarのPercentに設定しています。
f:id:PaperSloth:20200924021053p:plain

これもスクショ都合でMathExpressionにしておきます。
f:id:PaperSloth:20200924021241p:plain

最後にダメージ処理の全体像を貼っておきます。
f:id:PaperSloth:20200924021255p:plain

今回はダメージを与える側のBlueprintは省略します。

最終的に以下のような形になります。
f:id:PaperSloth:20200924022232g:plain

参考資料

Action RPGではこの方式でHPゲージが実装されています。
「BP_EnemyCharacter」に「WB_EnemyHP」のWidgetが関連付けられていますので
その2つのBlueprintを見ていただければと思います。
Action RPG:Epic Games:Epic Content - UE4 マーケットプレイス

UE4 Niagaraのサンプルプロジェクトを公開しました!

環境

UE4.25.3

概要

第14回UE4ぷちコンに応募したプロジェクトのコアロジックのみの最小構成サンプルを公開しました!

プロジェクトの詳細は前回の記事を参照
papersloth.hatenablog.com


GitHubとBOOTHにて公開しましたので、お好きな方からDLいただければと思います。
github.com

papersloth.booth.pm

また、ゲーム自体の実行ファイルも下記BOOTHにて公開しました。
こちらのゲームもぜひとも遊んでいただければ思います。
papersloth.booth.pm


内容としては下記のようにシンプルな構成になっています。

ざっくりと中身を説明しますと
LevelBlueprintで無限ループを行い花火のSpawnを行っており
Blueprint x 3は回転するSkydome、花火、GameModeの3つです。

GameModeではマウスの位置を始点にMultiSphereTraceで花火のBlueprintに付けたSphereCollisionとのヒット判定を行っています。
花火ではNiagaraからの位置情報の取得とヒット判定後の花火の爆発を行っています。


Niagara System x 3は
打ち上がる花火のエフェクト、時間経過での小さな爆発、カーソルヒット後の大きな爆発の3種類です。
打ち上がる花火のエフェクトでは「Generate Location Event」と「Receive Location Event」を使用しており
Emitter間での位置情報のやり取りについて学べるかと思います。
これはカーソルヒット後の大きな爆発でも同様です。
特にRibbon Rendererでの位置情報の追従は便利で何かと使い所があるかと思います。


自作のNiagara Moduleでは「Add Velocity in Cone」をベースに簡単な計算の補正を行ったものと
前々回の記事で解説したBlueprintに位置情報を渡すためのModuleの2種類です。
詳細はこちらをご覧いただければと思います。
papersloth.hatenablog.com


自作Moduleに深入りしたりSimulation Stageに手を出すと複雑化していくのですが
Niagara自体は結構シンプルで分かりやすいものですので、気軽に触ってみてください!

以上です!

制作日記 第14回UE4ぷちコンに応募しました

環境

UE4.25.3

概要

こんなゲーム作りました
www.youtube.com

技術的な詳細実装の解説記事というよりはあくまで日記程度のものです。

ゲームのコアロジック部分に関してはほぼほぼNiagaraで作成してます。
ゲーム全体のロジック(シーケンスやスコア管理やUI等)はBlueprintとUnreal C++で作成しました。
今回の比率的には7 : 3(Blueprint : C++)くらいの割合です。

C++でなければ実装ができないような部分は1,2%程度ですが
Blueprintでも代替可能な部分ではあるので、実装は全てBlueprintでも可能です。

コア部分の花火の実装

Niagaraの実装

花火は大きく分けると打ち上げ部分と爆発部分の2つのEmitterで作成しています。
実際には細々とした装飾を施しているため、以下の構成です。
・打ち上げ部分 : 核となる玉、Trail(Ribbon)、Trail(Sprite)、煙(なくても良かったかも)の4 Emitter(無駄に贅沢)
・爆発部分 : 飛び散る玉、Trail(Ribbon)、Trail(Sprite)、四散する玉の4 Emitter
Particle自体はプロのアーティストでもない素人が作ったものなので深く解説する部分は特にないです。

それよりはBlueprintとNiagaraの連携部分に比重を置いて解説していこうと思います。
基本的には前回記事にしたParticleDataのやり取りがメインの部分です。
papersloth.hatenablog.com

まず打ち上げ部分のParticleについてですが、1つだけ自作のNiagara Module Scriptを使用しています。
f:id:PaperSloth:20200830071231p:plain

NMS_ExportというNiagara Module Scriptを作成しました。(元は検証用で作成していたとはいえ酷い命名ですね)
詳細は先程貼った前回の記事を見ていただければですが、処理内容としてはParticleの位置と速度をBlueprintに受け渡しするために設定しているだけです。
f:id:PaperSloth:20200830071411p:plain

ひとまずこれでBlueprintに位置と速度を渡せるようになりました。
最終的に速度は使用しなかったので、位置情報だけで良いのですが。

Blueprintの実装

花火のBlueprint側はActorを継承してNiagaraSphere Collisionだけのシンプルなものです。
f:id:PaperSloth:20200830071826p:plain

通常今回のゲームのような処理を組む時はNiagara で見た目だけ作成してBlueprint で動きの制御をすることが多いと思うのですが

今回のアプローチとしては逆でNiagara の動きの制御に合わせてBlueprint で当たり判定を追従させるという作りにしています。
Niagara Particle Callback HandlerをInterfaceに追加して
Receive Particle Dataで先程設定した打ち上げ部分の玉の位置情報を受け取るようにしています。
受け取るデータは配列ですが、打ち上げ部分の玉は1つしか生成していないため
その位置情報を元に当たり判定となるSphere Collisionの位置を設定しているだけです。
f:id:PaperSloth:20200830071923p:plain

これで打ち上げた玉の位置と実際のコリジョンが一致するようになります。
f:id:PaperSloth:20200830072947g:plain

あとは一定時間が経過するか、カーソルにヒットした少し後に爆発用のエフェクトを生成するだけです。
これだけでこのゲームのコア部分自体は完成です。

その他の実装

このゲームらしい部分の解説らしい解説はこれで終わりなんですが、その他の細々とした実装もちょっとだけ解説します。

天球

それっぽい夜空があれば何でも良かったんですが、Infiltrator Demoの背景とかそのまま使えそうだなと思ったのでそのまま使うことにしました。
なので、実は背景にあのロボがいるんですね
f:id:PaperSloth:20200830074645p:plain
Scene Capture CubeでCube Mapを作成してMaterialにペタッと貼っておしまいです。
これだけで背景完成!お手軽!
f:id:PaperSloth:20200830074551p:plain
詳細は以前に記事にしたので、こちらを参照ください。
papersloth.hatenablog.com

大きな花火とタイトルのキラキラ

特定コンボ数で出現する大型の花火とタイトルにはキラキラしたエフェクトを付け足しています。
大型花火
f:id:PaperSloth:20200830073815g:plain
タイトルロゴ
f:id:PaperSloth:20200830074945g:plain

Particle自体はNiagaraのテンプレートのOmnidirectionalBurstにちょっと手を加えただけのものです。
見た目的には良さそうなんですけど、実装としては大問題が1点あります。
使用してるテクスチャが「DefaultBloomKarnel」なんですよね。
Engine/EngineMaterialsに入ってるテクスチャなんですが、2Kのテクスチャを使用してる割にこれだけしか描かれてないです。
f:id:PaperSloth:20200830075319p:plain
なので、通常は使用しないでリサイズしたりしてパッケージサイズを圧迫しないようにしたりすることが多いと思います。

で、今回は贅沢にもこのテクスチャをそのまま使用しています。
f:id:PaperSloth:20200830075538p:plain

まとめ

今回は技術記事というより日記なので薄っぺらい感じの解説になっています。
特に全く意識したわけではなかったんですが、このゲームでは光源が0です。
タイトルからリザルトに至るまで、全部Emissiveだったんですよね。
みんなそれぞれ輝いています。

以上です!久々にぷちコン参加できて楽しかったです!

UE4 ParticleDataを使用したNiagaraとBlueprintの連携

環境

UE4.24.3 (解説は基本的にすべて4.25です)
UE4.25.2

NiagaraEmitterの情報にBluerprintからアクセスする方法

UE4.25 以前のアクセス方法
UE4.24.3等ではGet Niagara Emitter XXでEmitterの情報にアクセスが可能でした
こちらはEmitter名を指定するだけなので非常にお手軽でした
f:id:PaperSloth:20200801100245p:plain


しかし、UE4.25からはこれらのノードが廃止されています
f:id:PaperSloth:20200801100437p:plain

そこで、UE4.25以降ではNiagara Emitterの情報をどのようにしてBluerprintから取得するのかという点について解説していきます

Niagara側の設定

data export用のModule作成

まずはFX -> Niagara Module Scriptから新規にModuleを作成します
f:id:PaperSloth:20200801100658p:plain

名前はひとまず「NMS_ExportExample」としました
f:id:PaperSloth:20200801100841p:plain

Niagara Module Scriptを作成したら先ずは忘れないように
「Expose to Library」にチェックを入れます
ここにチェックをしないと、Niagara Emitterから使用することができません
f:id:PaperSloth:20200801101004p:plain

続いて、dataをexportするための「New Export particle data」を追加します
f:id:PaperSloth:20200801101141p:plain
f:id:PaperSloth:20200801101149p:plain

次に「Store Particle Data」を使用してDataを格納します
f:id:PaperSloth:20200801101435p:plain

  • Store Data : データを保持する条件です。

チェックを入れた場合は常時値を保持するようになります
条件式を加える例として、PaticleにCollision Moduleを追加してHitした時のみ位置情報を格納するなどの使い方が考えられます

Position, Size, Velocityは特別解説するようなこともないので、素直に値を入れてあげればよいです
今回の例では位置情報のみを使用するため、以下のように設定しました
f:id:PaperSloth:20200801101737p:plain

しかし、これだけではMap Setしていないためエラーになってしまうので値を追加してあげます
Particle Attributesに新規にbool型の変数を追加し「StoreSuccess」と名付けました
名前はなんでもいいです
f:id:PaperSloth:20200801102019p:plain

追加したAttributeをMapSetに追加して、StoreParticleDataの返り値を設定します
f:id:PaperSloth:20200801102135p:plain
f:id:PaperSloth:20200801102230p:plain

これでModule Scriptは完成です。
f:id:PaperSloth:20200801103107p:plain

Niagara Systemの作成

新規にNiagara Systemを作成し、New system from selected emitter(s) を選択します
f:id:PaperSloth:20200801105318p:plain

Emitterは「Omnidirectional Burst」を選択します
Emitter to Addから追加し、作成完了です
f:id:PaperSloth:20200801105437p:plain

名前は「NS_Example」としました
f:id:PaperSloth:20200801105619p:plain

NS_Exampleを開いて「Particle Update」に先程作成した
「NMS Export Example」を追加します
f:id:PaperSloth:20200801105723p:plain

このままではCallback Handler Parameterに設定可能なParameterがないため、新規にParameterを追加する必要があります
f:id:PaperSloth:20200801105836p:plain

Parametersの「User Exposed」に「Object」型のParameterを追加します
f:id:PaperSloth:20200801105856p:plain

ひとまず「ExportHandler」と名付けました
名前はなんでもいいですが、後ほどBlueprintと連携する際にこの名前が必要になります
f:id:PaperSloth:20200801110005p:plain

Object型のParameterを追加したことでNMS Export Exampleに設定可能なHandlerができました
「NMS Export Example」を選択し、Callback Handler Parameterに「User.ExportHandler」を設定します
f:id:PaperSloth:20200801110204p:plain

これでNiagara Emitter側の設定は完了です

おまけとしてCollisionを追加しておきました
後のデバッグでの挙動確認用です
f:id:PaperSloth:20200801111953p:plain

Blueprint側の設定

長かったですが、ここまできてようやくBlueprintからのEmitterの値の取得が可能になります。
「Actor」を継承したBlueprintを作成し、「BP_ExampleActor」と名付けました
f:id:PaperSloth:20200801110437p:plain
忘れないうちにLevel上の適当な位置に配置します

「BP_ExampleActor」を開くと、まずはComponentの追加で
Niagara Particle System」を追加します
f:id:PaperSloth:20200801110558p:plain

追加したComponentを選択し、先程作成した「NS_Example」を割り当てます
f:id:PaperSloth:20200801110636p:plain

続いてNiagara Systemの「ExportHandler」の初期化を行います
NiagaraのComponentから「Set Niagara Variable(Object)」を選択し
「BeginPlay」から呼び出し、図のように繋ぎます
f:id:PaperSloth:20200801110937p:plain
これで「NS_Example」の「ExportHandler」に対して「BP_ExampleActor」を割り当てることができました

次にNiagaraのCallback関数の呼び出しを行います。
「Class Setteings」を選択して
f:id:PaperSloth:20200801111059p:plain

Interfaceの追加から「Niagara Particle Callback Handler」を選択します
f:id:PaperSloth:20200801111215p:plain

MyBlueprintタブのInterfacesに「Receive Particle Data」が追加されていれば設定ができています
f:id:PaperSloth:20200801111318p:plain

続いて「Receive Particle Data」から「Implement Function」を選択して
Receive Particle Dataに処理を追加します
f:id:PaperSloth:20200801111416p:plain
f:id:PaperSloth:20200801111437p:plain

Niagara EmitterのPosition情報を取得してDebug用のSphereを描画してみました
f:id:PaperSloth:20200804174154p:plain
これで値が正しく取得できていることが確認できました
f:id:PaperSloth:20200801112144g:plain

まとめ

今回の作例ではNiagara Module ScriptからPositionにのみ値を設定したため
Position以外には値が割り当てられていません
逆にModule Script内で処理を書くことで様々なカスタムした値の割り当てが可能です

また、ModuleのStore Dataフラグの工夫次第でヒット判定など様々な条件の判定が可能です

ここまで読んでいただいた方はよく分かったと思うのですが
UE4.24に比べてUE4.25でのNiagara Emitterの情報を取得するのが大変手間です
他にもっとスマートな方法を知っている方はTwitter等で教えてもらえると嬉しいです。以上です。

おまけ
この機能を使ってこんなゲームを作って簡単な解説記事を書きました
www.youtube.com

papersloth.hatenablog.com


以上です

UE4 Editorの言語設定を一時的に変える方法

環境

UE4.25.1

言語設定を一時的に変える方法

普段UE4を英語環境で使用しているけれど、他の人にEditorで説明する場合等に一時的に日本語環境に変えたいというケースがあります。

そういった時にUE4ではコンソールコマンドから変更することが可能です。
ただし、この機能は一時的なものでEditorを再起動した時には元に戻ります。
また、全てが正しく変更されるわけではないため、ブログやスライド作成時には後述の永続的に変える方法から変更してEditorを再起動することをオススメします。

変更方法は簡単で実行中またはOutput Logから
"culture=(言語)"です。
日本語に変更したい場合は"culture=ja"
英語にしたい場合は"culture=en"
実行時のコンソールコマンド入力は以下のどちらからでもよいです。
f:id:PaperSloth:20200621213537p:plain
f:id:PaperSloth:20200621213638p:plain

以下のようにOutput Logから入力した場合でも問題ありません。
f:id:PaperSloth:20200621213734p:plain

このコマンドで使うことはないかと思いますが、ConstrunctionScriptやBeginPlay等でも動作します。
f:id:PaperSloth:20200621213840p:plain

言語切り替えは他の多くの言語にも対応していますが、よく使うのは上記だと思いますので、他の言語は割愛させていただきます。

言語設定を永続的に変える方法

こちらは多くの情報が出てくると思いますが、一応紹介しておきます。
Editor Preferences(エディタの環境設定)から変更可能です。

General - Ragion & LanguageからEditor Languageを変更することで変更されます。
この方法で変更した場合はEditorを終了しても適用されます。
念のためEditorの再起動をしておくと部分的に言語が変わる恐れもなくて安心です。
f:id:PaperSloth:20200621214153p:plain

日本語の場合は一般 - 地域 & 言語のエディタの言語から変更可能です。
f:id:PaperSloth:20200621214424p:plain

UE4 LockOnCursorの実装

環境

UE4.25.1

概要

UE4でのロックオンの記事はちらほら見かけるけど、ロックオンカーソルの記事は少ないというのを見て書き始めました。
本記事ではロックオンする対象は1体を想定しています。
マルチロックオンでの運用も可能ですが、Widgetの場合は少し工夫が必要になります。

ロックオンの処理自体は事前に組まれていることを想定しています。
良いサンプルとは言えませんが、とりあえずのロックオンのサンプルとして下記を利用していただいても良いかと思います(このサンプルにはロックオンカーソルのロジックは実装されておりません)
github.com


完成イメージは以下のようになります。
f:id:PaperSloth:20200619223101p:plain


※実装に使用している「LockOnTarget」という変数がありますが
これはActor型の変数でPlayerやLockOn用のComponent等
ロックオン処理を行っているBlueprintから事前にHUD/Widgetに渡されている上での実装になります。
f:id:PaperSloth:20200620145352p:plain

一例としてPlayer側でロックオン処理を組んでいる場合のものを載せておきます。
PlayerRef : プレイヤーBlueprintへの参照
IsLockOn : プレイヤーがロックオン状態か判定するためのフラグ
LockOnTarget : ロックオン対象となるActor(必ず対象がいるとは限らないため、IsValidチェック)
f:id:PaperSloth:20200620145535p:plain

ロックオンカーソル実装(HUD編)

先ずはHUDでの実装についてです。
個人的にはWidgetでの実装をオススメしますが、こちらも紹介しておきます。

下図のようにHUD Blueprint内で処理を組むことでロックオンカーソルを表示できます。
f:id:PaperSloth:20200619211120p:plain

ここで注目すべきは「Project」ノードです。
「Project」ノードでロックオン対象の3次元座標を画面の2次元座標に変換してくれます。
あとはその位置データを元にDraw TextureやDraw Materialでロックオンカーソルを描画するだけです。

注意点として、このノードはHUD内でしか使えず「Event Receive Draw HUD」の中でしか機能しません。
そのため、Tick等で同じノードを組んだ場合には動作しません。

ロックオンカーソル実装(Widget編)

続いてWidgetでの実装です。
Widget内のDesignerでは図のようにCanvasPanelとImageだけのものを用意します。
f:id:PaperSloth:20200619220738p:plain

この時にLockOnCursorのVisibilityを「Hidden」か「Collapsed」にしておきます。
表示されてほしいのはロックオン中のみですので、デフォルトでは非表示でよいです。
f:id:PaperSloth:20200619220906p:plain


あとは図のようにBlueprintを組めば完成です。
f:id:PaperSloth:20200619221524p:plain

ロックオン対象が存在する時は表示して座標を更新し、いない時は非表示に切り替えています。
HUDではProjectを使用して2次元座標に変換していましたが
ProjectはHUD専用ですので、こちらではPlayerControllerの「Project World to Screen」を使用します。

この辺りの処理は何度か使うようであれば、関数ライブラリ等にまとめてしまってもよいかもしれませんね。
f:id:PaperSloth:20200619222328p:plain
f:id:PaperSloth:20200619222357p:plain

ロックオン処理の実装にもよりますが、開始/終了判定が取れる場合は以下のようによりシンプルにまとまると思います。
f:id:PaperSloth:20200619222708p:plain

まとめ

個人的にはWidgetでの実装をオススメしますが

とHUD編で書いたのですが、この理由についていくつか解説します
1. ロックオン開始時のアニメーションを追加できる
 ロックオンした時のカーソルの回転や拡縮や色替えなど各種アニメーションをWidgetで組んで実装することができます。
 HUDでも出来るかもしれませんが、結構な手間なので避けたいところです。
 ロックオン開始時ではなく、常時回転などを行いたい場合は以下のようにMaterialで組めばよいです
 papersloth.hatenablog.com

2. 画面サイズの変更に強い
 HUD版の現実装では画面解像度等を変えた時にロックオンカーソルも大きさが変わってしまいます。
 これでちょうど良いサイズになってくれると良いのですが、少し処理を加えて調整してやる必要があります。
 Widget版ではViewportScaleを考慮して計算しているため、表示 / 非表示の切り替えくらいで特に何も手を加える必要がない想定です。

HUDでの利点もないわけではないです。
マルチロックオンを行いたい場合は比較的処理が楽です。
Draw Texture/Materialが同時にロックオンした数と同じだけ描画されることにだけだからです。
例で渡したLockOnTargetを配列にしてループを回すだけで済みます。
f:id:PaperSloth:20200619211913p:plain

同じことをWidget版でやりたい場合は少し手間です。
図のようにLockOnCursorだけのWidgetを作成しておき
f:id:PaperSloth:20200619215814p:plain

ロックオン開始時にメインのWidgetのPanelにAdd Childして終了時にRemove Childする等でしょうか。
f:id:PaperSloth:20200619220053p:plain


ロックオンカーソルについては以上になります。

UE4 MaterialでTextureを回転させる

環境

UE4.25.1

CustomRotatorを使用する

Engine Content内のMaterial FunctionにCustomRotatorというものがあります。

これを使うだけでTextureの回転が可能です。
f:id:PaperSloth:20200615001731p:plain

引数について
・UVs : UVを渡す
・Rotation Center : 回転の中心位置
・Rotation Angle : 0-1で回転量を渡す 0.5 -> 180°, 1.0 -> 360°

使い方は簡単で180°回転させたい場合は以下のように繋ぐだけです。
上の画像が元画像で下が180°回転させたものです。
f:id:PaperSloth:20200615002338p:plain


ただし、このテクスチャをそのまま回転させるとテクスチャの繰り返し部分が見えておかしな表示になっていしまいます。
f:id:PaperSloth:20200615002836g:plain

これを修正するにはImportしたTextureを開いて
X/Y-axis Tiling MethodをWrapから「Clamp」に変更することで防げます
f:id:PaperSloth:20200615003003p:plain
f:id:PaperSloth:20200615003153g:plain

Textureを回転させる方法

Material内で回転させるためにはRotation Angleに「Time -> Frac」を渡すだけでよいです
f:id:PaperSloth:20200615003412p:plain

これはTimeの小数点部分だけを渡しているのですが
何をしているのかを見ていきましょう

先ずは以下のようにTime -> Fracした値を「DebugScalarValues」に繋ぎます。
f:id:PaperSloth:20200615004309p:plain

続いて「DebugScalarValues」ノードの上で右クリックして「Start Previewing Node」を選択します
f:id:PaperSloth:20200615003654p:plain

すると以下のように小数点部分が0から0.9999999までカウントされていることがわかります。
こうすることでRotation Angleの0-1の範囲に収まった上で回転させることができます
f:id:PaperSloth:20200615003803g:plain

最後にMaterial Instance側で調整しやすいように「ScalarParameter」を追加し、「RotationSpeed」としておきました
f:id:PaperSloth:20200615004455p:plain

これを応用することで以下のようなクルクル回転するロックオンカーソル等が作成できます
f:id:PaperSloth:20200615001622g:plain