Typescriptにおけるカラーコードの文字列型の定義方法 - typeとinterfaceの比較と使い分け
カラーコードを入れるための変数の型を定義したかったんだけど、interfaceとtype どちらを使えばいいか曖昧だったのでまとめといた。
Typescriptでカラーコードの文字列を扱う変数の型を定義する方法には、typeとinterfaceの2つのアプローチがあるが、それぞれの違い 向き不向き どちらを使うべきか。
1.-typeを使う
type ColorCode = string;
typeキーワードを使用して型エイリアスを定義。ColorCodeはstring型の別名として定義される。
type ColorCode = `#${string}`;
テンプレートリテラルを使用することで、カラーコードの文字列を#で始まるものに制約することができる。
この書き方だと#
から始まる文字列ってことしか制限できないけど、とりあえず大体の制限は設けられる。
2- interfaceの使用
interfaceを使用してオブジェクトの形状を定義。ColorCodeはvalueプロパティを持つオブジェクトの形状を表jsu。この方法では、カラーコードを表すオブジェクトを宣言し、valueプロパティにカラーコードの文字列を格納する。
interface ColorCode { value: string; }
interfaceの利点:
カラーコード以外の文字列を受け入れない制約がある(あとから拡張とかできない)。 オブジェクトの形状を詳細に制御できる。 interfaceの制限:
シンプルな型エイリアスよりも記述が煩雑になる場合がある。 実際にこの型で宣言した変数に値を代入しようとすると
const color:ColorCodes = {value: '#000000'}
というオブジェクトになってしまい冗長な感じになる。また制限をがかけられないので、別途ベリデーションを作る必要がある。
interface ColorCode extends String {}
という風にもできるけど、多少の制限がワンラインでかけられるtype使う方が今回はよさそう
PlantUMLで項目名に括弧とかの記号を使いたい時
記号を含めたテキストを項目名とかで使いたい時は
"文言(注釈)"
って感じで項目内のテキストを丸ごとダブルクォートで囲う。シングルクォートでもいけた。
TypeScript、ここ2年くらい一切書いていなかったので思い出すためにも軽いWebアプリをNext.jsで作ろうとしてる。なんならNext.js自体は初めて触るから色々調べつつ書いてる。
数年前までと本当にWebフロントの環境が変わってて浦島太郎状態になってる。公式でCRAが非推奨になってたのは本当にびっくりした。
まだNext.jsのディレクトリ構成の仕様とかが把握しきれていないので本当に手探り状態。
せめてサービスの流れだけは見失わないようにPlantUMLでシーケンス図をメモしておいてる。
【UE4.26】NiagaraのAgeについて
この記事は Calendar for Unreal Engine (UE) | Advent Calendar 2021 - Qiita 2 の14日目の記事です。13日目の 独自のタブをエディタのメニューから呼び出す方法 - Qiita は、最近独自の自作ツールを作ったりしてたりしてたので個人的にホットな記事で 参考にさせてもらおうと思っています。
なにについて書くか
Niagaraでパーティクルの大きさや色を変えたりする時に使っている "CurveIndex"に設定する値には"~~~Age"ってのがよく使われると思います。
これについて整理しました。自分自身、Niagaraでパーティクルを作ろうかなって始めた時に知りたかった情報でもあるので 初心者の人に見てもらえると嬉しいです。
今回は、普段自分がよく使うSystem系、Emitter系、Particle系について調べました。
その他のAge系についてはよくわからんなのでいずれ...。
自分自身、理解の及んでいないところもあるので、実際の動きを見ながら検証して確認していきました。
Niagaraでパーティクルを作成する際に、「パーティクルの更新」や「エミッタの更新」の場所で、カーブ等の値を設定する時があると思います。
例えばこれは、"ScaleColor"の"ScaleAlpha"の値をカーブにして設定しているもので
時間軸(横軸の値)0から0.5にかけて指定の値(縦軸の値)を1に増加、その後 時間が1にかけて0に指定の値を現象させています。
"エミッタの更新"欄で、"Spawn Burst Instantaneous"のSpawnCount"を1に設定して、パーティクルをひとつスポーンさせます。
"パーティクルのスポーン"内の"Initialize Particle"の"Lifetime"を5.0に設定して、パーティクルの寿命を5秒に設定して動かしてみます。
また、Lifetimeに設定した時間が来ても パーティクルが消滅はしないように"ParticleState"内の"Kill Particles When Lifetime Has Elapsed"のチェックを外しています(ライフタイム後の挙動まで見たいからです)。
— 東京高速戦術@VR音ゲー「Bullet_Live」制作中 (@kousoku_tactics) September 12, 2021
5秒毎に点滅しているのがわかります。
もうちょっと詳しく書くと、2.5秒かけて最大まで明るくなり、その後 2.5秒かけて暗くなっていっています。
この時、時間の値には0から1までの指定しかしておらず、5秒の制御をしているとは思えません。
多分、パーティクルの一生を(スポーンしてからキルされるまで)割合的に0から1にしてやるんだと思いますが、もっと詳しく 他の時間の指定方法等も含めて調べていきます。
(このカーブの指定方法、自分が勉強してた時は「0から1の割合内で考えてカーブのポイント打っていってね」って指示が多くて よくわからんままつかっていました)
最初に 今回、検証用に使うパーティクルのマテリアルを紹介しておきます。
NiagaraSystemからマテリアルの数値をいじった事がわかりやすいように、入力された数値をそのまま表示できる(主にデバッグ用に使われることを想定されたマテリアルノードですが)DebugScalarValuesにDynamicParameterをつないだマテリアルを用意しました。
これで、Niagaraから"Dynamic Material Parameters"を使ってマテリアルにどのような数値が入力されているのかわかりやすくなります。
こんな風に。
まず、Particle系の値からあてはめてみていきます。
なお、今回の検証では
Systemの"LoopDuration"を5.0
Emitterの"LoopDuration"を4.0
Particleの"LifeTime"を3.0にしています
これらは確認の際に必要に応じて無効にしたりLifeCycleModeを変更したりはしますが、値として利用する場合は上記の通りにして動かしていきます。
Particle系
— イイノテン (@iinoten) December 14, 2021
上から順に、"Particle.Age"、"Particle.NormalizedAge"を入れています。
Particle.Ageの方は3秒間かけて0から3に増加、Particle.NormalizedAgeの方は3秒間かけて0から1に増加していっています。
Ageは単純にパーティクルがスポーンしてからの経過時間(正確にはLifeTimeが切れるまでの時間)を表わしており、NormalizedAgeの方は言葉の通り Ageをノーマライズ(0から1の間にスケールさせた(正規化))した値のようです。
— イイノテン (@iinoten) December 14, 2021
パーティクルがスポーンされるまでの時間にディレイを持たせてみました。
待機の1秒が経過した後に、スポーンし 0からカウントが始まっているのがわかります。
— イイノテン (@iinoten) December 14, 2021
Particle.NormalizedAgeを利用して色を変えています。
スポーンされた時には青のパーティクルが、消える時間(LifeTime)を迎える毎に赤色になっていっています。
Emitter系
— イイノテン (@iinoten) December 14, 2021
上から順に、"Emitter.Age"、"Emitter.LoopedAge"、"Emitter.NormalizedLoopedAge"を入れています。
また、ParticleStateのLoopParticlesLifeTimeのチェックを外してParticleがLifetimeを過ぎても消えないようにしました。
Ageの方はSpawnしてからの時間が表示されています。
LoopedAgeは、EmitterのLoopDurationとして設定した4秒の時間が過ぎたら、また0からカウントされている値が表示されているようです。
NormalizedLoopedAgeには、4秒間かけて0から1までの値が入っているようです。
— イイノテン (@iinoten) December 14, 2021
Particle.NormalizedAgeを利用して色を変えていっています。パーティクルのスポーンされたタイミングに関わらず、時間経過により一斉に色が変化しています。
System系
— イイノテン (@iinoten) December 14, 2021
上から順に、"System.Age"、"System.LoopedAge"、"System.NormalizedLoopedAge"を入れています。
Ageはパーティクルシステムが始まってからカウントが始まっており、
SystemのLoopDurationは5.0を指定しているので、System.LoopedAgeはカウントが始まってから5秒経過後、また0秒からカウントする値が入っています。
NormalizedLoopedAgeはLoopedAgeを正規化した値が入っています。
— イイノテン (@iinoten) December 14, 2021
FountainをベースにしたEmitterを複数用意して、スポーンの位置と出現のタイミングをずらしてみました。
System.NormalizedLoopAgeに応じて色が変わるようになっているので、エミッタの出現タイミングに関わらず、一斉に色が変化するようになっているのがわかります。
以上です。
なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。
[ この記事はブログ投稿者の憶測や考えによりつくられています。
よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]
【UE4 .26】音とパーティクルを連携させてみる
この記事でわかることです。
- グニョグニョ動く球に使ったマテリアルの作りかた
- ワイヤフレームのみを描画するマテリアルの作りかた
- Wavファイルから流れる音量値をパーティクルに伝える方法
今回の記事内で解説した内容で作ったパーティクルが下のツイート内の動画になります。十字部分やクルクル回るエミッタの所等の作成方法については、過去の解説記事で作ったものを流用してたりするので 今回は書きません(要望があったら詳しく書きますが、基本的には他の書かれた記事を参照していただけるといいかと思います)。
#Niagara で未来感のある音声通話UIを模したパーティクルを作りました。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) July 1, 2021
音に合わせてパーティクルが変化しているのが分かりますか? やり方も簡単なので、ブログの方で解説記事書きたいと思います! RT、いいねしてくださると励みになります~!! #ue4 #gamefx #realtimevfx #3dcg #cyberpunk pic.twitter.com/dsvcPpUfX3
グニョグニョ動く球に使ったマテリアルの作りかた
"SimpleGrassWind"ノードを使います。
本来、葉っぱや旗等に使うマテリアルに起用して 風に揺れるオブジェクトを表わしたりするものです。これを球に使うことで、グニョグニョ動くようにさせます。
繋げ方はこんな感じです。"WindIntencity"と"WindWeight"ノードに与える値の変化でグニョグニョの強さを変えます。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) July 2, 2021
これでグニョグニョするようになります。
Niagaraからグニョグニョの強度を変えられるようにDynamicParameterノードに繋げておきます。
ワイヤフレームのみを描画するマテリアルの作りかた
これを作る方法です。
色んな方法があると思うんですけど、一番簡単な方法で僕はやりました。
マテリアルの詳細から、"Wireframe"にチェックを付けます。以上です。
さっき作ったグニョグニョマテリアルの"Wireframe"をチェックしてみると
こんな風になりました。
Wavファイルから流れる音量値をパーティクルに伝える方法
音に応じて動くパーティクルに絞って作ります。
ブログ用です pic.twitter.com/esI27rM6HV
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) July 2, 2021
これを作ります。
使用するマテリアルはなんでも良いです。
自分はコレを使いました。"RadialGradientExponential"ノードを使用して二重丸を描画したマテリアルです。
システムの概要です。"Empty"を基に作りました。重要な所を説明していきます。
10個のパーティクルを一気にスポーンさせます。
ここは特に特別な事はしていません。"(パーティクル) SpriteFacingを設定"でスプライトパーティクルの向きを上向きにして、"(パーティクル) SpriteAlignmentを設定"でカメラに対する角度を固定させます。
後は色を赤にしました。
最初の二つのパーティクルに関しては、モジュールに含まれていないので
パラメータの中のパーティクル属性にあるのをみつけて、システムの概要の方にドラッグ&ドロップします。
パーティクル属性の中になかったら、右上の+ボタンを押して
検索して追加します。
"パーティクル更新"にパーティクルの動きをつけるモジュールを追加します。
"NMS_MoveDepthPosition"です。
これは最初から用意されているものではない、自作したものです。
作っていきます。
マップ取得で、パーティクルの移動を受けとるVector型のピンと パーティクルシステムの位置を取得する"(エンジン)(オーナー)Position"を +ボタンを押して追加します。
その後、写真の通りにノードを組みます。
内容はコメントの通りです。入力されるVector型にパーティクルのインデックスを表わす"Execution Index"を乗算して新しいパーティクル程位置の差が大きくなるようにします。
それとパーティクルをスポーンさせた座標である"(エンジン)(オーナー)Position"と加算させます。 "Map Set"ノードに"(パーティクル)Position"を追加してそこに加算した内容を繋げて完成です。
NiagaraSystemの方に戻ります。
公開されたユーザーにfloat型の値を追加して"VoicePower"と名付けておきます。
パーティクルと音を流すアクターを後で作成するのですが、そこからこのfloat変数を操作することになります。
さっき作ったNiagaraモジュールをパーティクルシステムに追加します。
今回は高さを動かしたいので、Z軸の場所にさっき作ったユーザー変数を追加します(少し値を大きくしたかった(動きを大きくしたかったので)MultiplyFloatで2を乗算しています)
これでパーティクルの方は完成です。
パーティクルと音量を連携させるのを作っていきます。
アクターを作成し、NiagaraSystemComponentとAudioComponentを追加します。
NiagaraのNiagaraSystemAssetにさっき作ったパーティクルをセットします。
AudioComponentに使いたいWavファイルを設定します。自分は文章の読み上げがわかりやすいと思ったので(楽曲よりも、単純な読み上げ音声とかの方が音量の抑揚が大きくビジュアライズ化した時にわかりやすいと思います)
ここを使いました。とても自然な読み上げ音声を作成して、簡単にWavファイルにしてダウンロードできるので便利でした。
AudioComponentの詳細内にある"On Audio Single Envelope Value"を追加します(緑の+ボタンを押します)。
このイベントノードからは、現在流れている音の大きさがEnvelopeValueから出てくるようになっています。
それを"Set Niagara Variable(Float)"に繋げて、NiagaraComponentのユーザー変数である"VoicePower"に渡します。
これで完成です。
ブログ用です pic.twitter.com/esI27rM6HV
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) July 2, 2021
このようにできたでしょうか。
なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。
[ この記事はブログ投稿者の憶測や考えによりつくられています。
よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]
【UE4 .26】警告アラート的なHUD風パーティクルをNiagaraで作る
リクエストくれた人がいたので、緊急アラートっぽいパーティクルを #Niagara を使って作りました!
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
某ロボットアニメっぽくなってて好きです!!#gamefx #realtimevfx #3dcg #cyberpunk https://t.co/40ub35TUrJ pic.twitter.com/6Etz4MwPI9
コレを作ります。
まず、このパーティクルを作る上で要素を分けます(作成する過程が一緒で少し中の数値をいじったものをまとめます)。
ブログ用です pic.twitter.com/1uMaiiMSlF
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
パーティクルを単純に回転させているものです(使っているマテリアル等に関しては後述します)。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
丸い円が広がりながら上昇してフェードアウトしていくものです。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
「緊急」の文字のついたパーティクルがランダムにスポーンされアニメーションするものです。
ひとつめから説明していきます。
パーティクルを単純に回転させているもの
やっている事は、真四角の平面メッシュに表示させたいマテリアルを張りつけて回転させているだけです。
基本はEmptyからエミッタを作成してMeshパーティクルを設定し、設定を少しいじっているだけなので特別なことはしていません。最低限、必要なモジュールを説明すると
PositionMode内のPositionOffsetのZ軸を変更させ、高さを変えています。
また、MeshAttributesのMeshScaleModeをUniformに設定して数値を1.2にしてサイズを変更しています。
SpawnCountに1を設定することで、パーティクル生成時にひとつだけスポーンされます。(このモジュールと設定は今後説明するエミッタ達でも基本共通して追加してあります)
色の設定をしています。今回作るパーティクルでは、共通する色を持ったエミッタが複数存在しているので ひとつの場所から一括で変更できるようにした方が、調整が楽です。ユーザー属性の場所に色の情報の値を保持させてそれぞれのエミッタに設定しています。(システム属性で良いとも思いましたが、後々ゲーム内などで扱う際に外部から変更できた方が使い勝手が良さそうだなと思ったので...)
ユーザー属性にパラメータを追加する方法を書きます。
「パラメータ」ウインドウから「公開されたユーザー」の横の+ボタンをクリックしてcolorと入力し、「Liner Color」を選択します。設定した値をエミッタに適用させたい場合は、追加した値をエミッタ内のモジュールにドラッグアンドドロップすればOKです。
各エミッタで共通する色の情報等の変数を持たせておくと、一括で変更できるので 調整、後々の変更などがしやすくて便利です。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 26, 2021
一定時間でエミッタが消えてしまわないように設定しました。
「パーティクル更新」に追加します。メッシュパーティクルにZ軸を基とした回転を加えています。
数値を正の値にしたり負の値にすることで回転の方向を変更できます。
メッシュとマテリアルの設定の概要です。使うマテリアルは好きな物を使うといいと思います。
ten0313.hateblo.jp今回使ったマテリアルはこの記事内で作ったものを流用しています。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
輪状のパーティクルがサイズを変えながら上に上がっていくエミッターです。
かいつまんで解説していきます。
SpawnRateを3に設定して、たえまなく連続的にスポーンしつづけるようにします。
Z軸に正の値を入れて重力を上向きにかけました。コレで上昇するようになると思います。
パーティクルの更新にScaleColorを追加しました。透明度を表わすalphaにカーブで数値を入力して色がフェードイン・フェードアウトするようにしました。
パーティクルのサイズをカーブで更新するようにしています。写真ではスポーンしてから徐々に大きくなるようにしています。
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
「緊急」の文字がポップアップするものです。
内容は画像作成ソフトで作ったものをTextureSampleとか使って動かしたりしています。
どんな形でも大丈夫です。好みのを作ってください(なんならtextureSampleとParticleColorで繋げるだけでもそれらしくなるとは思います)
内容を説明していきます。NiagaraEmitterのFountainを基に作成します。
スポーンさせる量をこれで設定します。数値を調整することで、スポーンされる量等を変更できたりします。
円柱状の場所を指定してパーティクルをスポーンさせるものです。
CylinderHeightとCylinderRadiusで平たい円柱(高さ10、直径100の円柱)を作って、その中にスポーンさせるようにしました。
OffsetでZ軸の数値を変更して、少し高い位置にパーティクル群が出るようにしました。
Y軸方向の大きさをCurveで指定して、スポーンしてからキルされるまでに パーティクルがピコンと動くようにしました。キー補完を「ユーザー」にして
出現した時と消える際に少し大きくなるようにすることでちょっとかっこよくしました。
パーティクル上部にこのエミッタが多数出現するので、下にあるパーティクル達は重なって見えにくくなってしまいそうです。対策として、Alphaを少し小さくすることで半透明にしました。このエミッタ同士が重なった時にも効果を発揮するはずです。
最後に表示方法の選択です。AlighnmentとFacingModeを設定することで、プレイヤーのカメラの位置に依存することなく、一定の方向を向き続けてくれるようになります。
リクエストくれた人がいたので、緊急アラートっぽいパーティクルを #Niagara を使って作りました!
— 東京高速戦術@VR音ゲー制作中 (@kousoku_tactics) June 25, 2021
某ロボットアニメっぽくなってて好きです!!#gamefx #realtimevfx #3dcg #cyberpunk https://t.co/40ub35TUrJ pic.twitter.com/6Etz4MwPI9
これで完成です。
なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。
[ この記事はブログ投稿者の憶測や考えによりつくられています。
よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]
【UE4 .26】Niagaraでサイバー風のパーティクルを作る方法
サイバーチックなカウントアップするUIをパーティクルで作りました! 気に入ってもらえたらRTしてもらったら作成方法のまとめ記事とか書くモチベになります💪
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
#UE4 #Niagara #gamefx #realtimevfx #3dcg #gamedev pic.twitter.com/i0DStm7GXy
これを作ります。
・角度の範囲を指定してマテリアルを減算する
UE4小ネタ : 円形ゲージの作り方 - ぼっちプログラマのメモ
・平面のメッシュをパーティクルにする
【UE4】4.25でNiagaraを使って魔法陣エフェクトを作ってみよう - アルゴンUE4&アプリ開発日記
・メッシュパーティクルの回転
今回作るパーティクルですが、Niagaraの方でやることはほぼないです。マテリアルで円を書いたり線を引いたりする事の方が多いです。
まずはNiagaraEmitterの方を作っていきます。
NiagaraEmitter、NiagaraSystem等がよくわからない方は
www.youtube.comこの解説動画がすごいわかりやすいのでオススメです。
今回作るパーティクルに使うNiagaraEmitterは4種類です。
NE_RotateLockArrow
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
NE_RotateArrowSquiz
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
NE_BorderCircle
ブログ用です。 pic.twitter.com/OpI6PN7I1i
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
NE_CoolUINumber
今回のParticleには共通して平面状のメッシュを利用します。
正方形のひとつの面を持ったメッシュを作成しておきます。UV展開等はそのまま正方形でやっておきます。
僕はBlenderで作成しましたが、シンプルな形状なのでなんのツールでも作れると思います。
一応GigaFile便でダウンロードできるようにしました。他ツールを使うのがめんどくさい時は使ってください。
作っていくエミッタ達は、ほぼ全て
- マテリアルを作成する
- 平面メッシュにマテリアルを張りつける
- エミッタ内でMeshRendererとしてスポーンさせて動かす(色を調整する)
といった流れで作っていきます。
ひとつめのNiagaraEmitterから説明していきます。
NE_RotateLockArrow
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
くるくる回る細い線です。
まずはマテリアルから作っていきます。
やっていることとしては、真ん中に丸の穴の空いた図からその丸より大きい丸の形状を引いて 出来た円の線から角度を指定して切りとっています。
参考にしたもの:
・丸を描く
[UE4] [UMG] はじめてのマテリアル、円を描く|GiRAFFIC ARTS ジラフィックアーツ|note
・角度を指定して切りとる
UE4小ネタ : 円形ゲージの作り方 - ぼっちプログラマのメモ
作ったマテリアルをエミッタに利用します。
エミッタの概要です。
基本的にエミッタの内容は使用するマテリアルを除いて、ほぼ共通した内容なので 詳しく説明します。
Emptyを開始点に作ります。
エミッタの更新からです。
SpawnBurstInstantaneousで最初に一度エミッタをスポーンさせています。
パーティクルのスポーン
PositionModeをSimulationPositionに設定、PositionOffsetを有効化します。
Z軸を調整します。これはパーティクル上でエミッタをどの位置にスポーンさせるか(表示位置)を指定しています。
エミッタの色を指定するColorは後でNiagaraSystemの方にエミッタを追加した際に複数のエミッタに対してまとめて色の変数を追加して管理するので、今はいじらなくて大丈夫です。
パーティクル更新
ParticleStateのKillParticlesWhenLifeTimeHasElapsedのチェックを外します。ライフタイムを無効化して時間経過でエミッタの表示が消滅しないようにするためです。
エミッタの永続化についてはこの記事が参考になります。
UE4 NiagaraのLifetimeを無制限にする方法 - PaperSloth’s diary
UpdateMeshOrientationではメッシュのZ軸の回転を制御しています。NiagaraSystemにエミッタを追加した後で個別に回転を調整(回転の速度を変えたり、逆回転にしたり...)するので、スクショでは-0.3を指定していますが 実際は数値を入れなくても大丈夫です。
レンダリングのタブの"SpriteRenderer"を削除して"MeshRendere"を追加します。
PartickeMeshには最初につくった平面のメッシュを設定します。
"OverrideMaterials"を有効化してさっき作ったマテリアルを設定します。
これでこのエミッタに関しては完成です。
左回りするエミッタが作れているでしょうか
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
次にこのエミッタを作ります。さっき作ったものの、伸び縮みする版みたいな感じです。
エミッタの方はさっきのと共通ですが、伸ぼ縮みするマテリアルを作る必要があります。
マテリアルのノードの概要です。円を作るところは、伸び縮みしないモノを作ったのとほぼ同じです(円の大きさを少し大きくしましたが)。
ここで伸び縮みさせています。Timeの小数点以下を取りだし、sine波にかけて動きをなめらかにします。
出力された数値を角度に変換して円から一部の線を取りだしています
できたマテリアルからエミッタを作ります。
さっき作ったエミッタを複製して作ります。
マテリアルを変更しておきます。
この要領でもうひとつ作ります。
ブログ用です。 pic.twitter.com/OpI6PN7I1i
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 10, 2021
回転する点線のマテリアルを作ります。
ノードの概要です。
放射の図を作ってそこに円状の図を掛けて点線上の円を作りました。
さっきと同じく
作った既存のエミッタを複製して
マテリアルをセットします。
これで今回使うエミッタ、主要な4つのうち3つができました(回転するモノです)。
次に文字を表示するマテリアルを利用したカウントアップしてくれるエミッタを作っていきます。
使用するマテリアルです
この中の"DebugScalarValuesSegment" ノードなのですが、既存のノードを解像したものになっています。
マテリアル上で数値を確認する"DebugScalarValues"ノードを複製します。
使いたい数字反転させ 縦に配置したテクスチャを用意します。
複製したマテリアルノードの中の"Composite"というコメント内のTextureSampleのTextureをさっきの画像のものに設定します
マテリアル内に数値を表示させる方法を色々やったんですけど(実際ある程度上手くいってたんですけど)既存のをいじった方が楽だって気付いちゃいました。
表示する内容を入力するNumberのピンにDynamicParameterのひとつ目のピンに繋ぎます(DynamicParameter側のピンを"Number"とかにしておきます)。
MaximumNumberOfDigitsは表示する小数点以下の桁数を入力しておきます。
文字を表示するエミッタを作ります。"Empty"を元に作成します。
基本的にはさっきまで作ったエミッタと共通ですが、UpdateOrientationで回転を加えることはことはしません。
「パーティクル更新」のタブに
"DynamicMaterialParameter"を追加します。描画した数字のパーティクルの数値を変更するためです。
直接数値をFloat型で指定してもいいと思いますし、僕はfloat from curveで目紛しく数値が変わるようにしました。
マテリアルを数値を表現するマテリアルにしておきます。
NiagaraSystemを作成します。
さっきまで作っていたエミッタを好きなだけ追加します。
基本的には追加するだけでいいのですが、InitializeParticleのPositionOffsetのZ軸をそれぞれ設定します。
要は高さを変えます。
MeshScaleModeをUniformに設定、Scaleをそれぞれ設定します(エミッタのおおきさを変えます)。
UpdateMeshOrientationのRotationVectorのZ軸を変更します(回転量を変えます)。負の数を指定する事で逆回転ができます。
これでNiagaraSystemの完成です。出来たパーティクルをレベルに配置してみてください。
できていますか?
ポストプロセスで露出を少し上げることでもっと「映え」させることができます!
なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。
[ この記事はブログ投稿者の憶測や考えによりつくられています。
よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]
【UE4 .26】スケルタルメッシュのモーションに合わせてパーティクルを発生させる【Niagara】
YMCAダンスを踊るパーティクル達です!! (どうやって活かすかは思いつかないんですけど、けっこうかっこいいので後でブログにまとめます~~~!!) #UE4 #gamedev #niagara pic.twitter.com/c2Ec2XtGz8
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 8, 2021
これを作ります。
スケルタルメッシュの形に合わせてパーティクルをスポーンさせる
www.youtube.com
ほぼコレの通りにしたんですけど、パーティクルの各種設定とか UnrealEngineのバージョン違いで詰まった所もあるのでそういう所も含めて全部書いていきます。
作成の流れとしては
- 指定したスケルタルメッシュの形にパーティクルをスポーンさせるNiagaraModuleScriptを作る
- 「パーティクルのスポーン」に作ったNiagaraModuleScriptを追加する
- メッシュをセットする
です。ところどころ詰まった箇所はあるんですけど、youtubeの解説が丁寧だったので楽にできました。
NiagaraModuleScriptを作っていきます。
持たせる役割としては「スケルタルメッシュの形にパーティクルをランダムにスポーンさせる」ってものです。
最初に「スクリプトの詳細」タブからModuleUsageBitmaskを写真の様にします。
これってどこでこのScriptを使うかを指定するモノって認識なんですけど合ってますか?
とりあえず今回はスポーンの時に使用するので(「メッシュの形に沿ってスポーンさせる」って機能を作りたいので)、"ParticleSpawnScript"を指定しています。
ノードの方を説明していきます。
基本的にスクショの通り組んでいって貰えればいいんですけど、自分の使っている4.26バージョンでは左下の"GetRandomInfo"のノードが検索しても出てきませんでした。過去のバージョンでは存在するノードだったのですが 、いつのまにか表示されないようになっちゃってるみたいです
エディタ内には存在しているようなので、表示されるように設定します。
コンテンツブラウザ内の「Niagaraコンテンツ」内で「Get Random Info」を検索するとでてきます。
「スクリプトの詳細」内の「LibraryVisiblity」を"Exposed"にセットして、コンパイルしてから適用させます。
これで自分の作るModuleScript内でも"Get Random Info"が使えるようになりました。
ModuleScriptを作成する上で詰まるところはこれでもう無いと思います。
やってることの内容としては
スケルタルメッシュをマップ取得で受けとって、"RandomTriangle"でポリゴンメッシュでメッシュ上のポリゴンをランダムで取得します。("RandomInfo"は乱数の生成に関する設定を扱かってるんだと思う)
Calculates info needed by other RNG functions about seeds and determinism,
"Get Random Info"ノードのDescriptionより
シードと決定論について他の RNG 関数が必要とする情報を計算します。
Google翻訳の結果
RNG関数ってのはRandomNumberGeneratorについての事であることから、RandomTriangleノードで扱う乱数の設定をしているんだと思いました。
ModuleScriptの後半です。
"RandomTriangle"で取得したポリゴンメッシュの情報を"Get Skinned Triangle WS"でワールド基準のものに変換します(ノード名の"WS"とは"WorldSpace"の略です)
その中の"Position"のピンをひっぱって"Map Set"のパーティクルの位置を指定する"Position"に繋ぎます。
これでパーティクルの位置がメッシュの形にセットされるようになります。
"NMS_SetPositionSkeletalMesh"って名前で保存します。
NiagaraSystemを作成して設定をいじっていきます。
Emitterも含めての概要です。「パーティクルのスポーン」にさっき作ったModuleScriptを追加しています。
"Empty"を元にエミッタを追加します。
基本的に これで追加したエミッタそのままで、いくつかモジュールを追加していったのでそれらを説明します。
「エミッタの更新」に"Spawn Rate"を追加しました。ベースとなるスケルタルメッシュがモーションさせている間も連続してパーティクルに出てきてもらいたいので設定しました。"SpawnRate"は100000にしました。正直ここまで要らないと思うんですけど、ゲームに組みこむわけでもないし、多い方がSNS映えするかな~って魂胆です。
「パーティクルのスポーン」の"Initialize Particle"です。ライフタイムを短かくして、スプライトのサイズを小さくしています("Sprite Size Mode"を"Random Uniform"にしている部分です)
さっき作ったモジュールです。今回はグレイマンにモーションを付けてパーティクルをつけようと思っているので、"SK_Mannequin"を指定しました。
男の子なので青くしました
「パーティクル更新」の欄です。重力を適用させました。
スプライトのサイズをスポーン後、徐々に小さくするようにしました。今回はスプライトのライフタイムが比較的短いので、地面に達する前に徐々に消滅するようにしました。
これでNiagaraSystemは完成です。"NS_BurstMesh"って名前で保存しました。
次に踊らせるグレイマンの方でNiagaraパーティクルをセットしていきます。
UnrealEngineのに用意されているThirdPersonテンプレート内の"ThirdPersonCharactor"のイベントグラフに↓を追加します。
これでパーティクルをセットします。
これで大体は完成なのですが、このままではグレイマン自身のメッシュが見えてしまっています。パーティクルのスポーンでグレイマンの形を表現したいので、グレイマンのマテリアルに透明なのを適用させます
メッシュのvisibleとかHidden in Gameをオンオフにしたらいいのかなって最初は思ってたんですけど、それをするとパーティクルがメッシュのモーションに追従してスポーンしてくれないのでこの方法をとりました。もっと良い方法が探せばあると思います。
これでグレイマンのメッシュに沿ってパーティクルが発生するようになっています。
ブログ用です #UE4Study #UE4 pic.twitter.com/c6MlzfAN6G
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 8, 2021
こんな感じです。
ダンスを踊らせると
YMCAダンスを踊るパーティクル達です!! (どうやって活かすかは思いつかないんですけど、けっこうかっこいいので後でブログにまとめます~~~!!) #UE4 #gamedev #niagara pic.twitter.com/c2Ec2XtGz8
— 東京高速戦術@VRゲーム制作 (@kousoku_tactics) June 8, 2021
こんな感じになったでしょうか。
なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。
[ この記事はブログ投稿者の憶測や考えによりつくられています。
よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]