環境:UE5.3、WebUI Plugin、Lottie 5.12.1
はじめに
こういうアニメーションをUE上で使ってみようという内容のお話です。
See the Pen Lottie Animation Example by deliciousbrains (@deliciousbrains) on CodePen.
ベクター画像とは?
ピクセルの集まりではなく、点や直線、曲線など数式の集まりで作られた画像の事です。
ベクター画像のメリットは
- 拡大しても画質が落ちない
- データサイズが小さい
- 変形が用意
などがあります。
参照:http://www.persfreaks.jp/main/tool/conic/
SVGとは?
SVG(Scalable Vector Graphics)は画像フォーマットの一種です。
XMLで記述でき、Webに適したベクターファイル形式です。
例:単純な矩形を描画するSVG
See the Pen SVGBox by 癒系 (@hrcvjbtz-the-bashful) on CodePen.
Lottieとは?
さて、このSVGのHTMLを手でチクチク作っても良いのですがそんなの大変すぎるのでGUIのツールを使って作りたいですよね。そこで出てくるのがLottieファイルです。
Lottieは、JSONベースのアニメーション形式で、こんな感じのファイルです。
LottieはAfterEffectsというツールから出力でき、手軽にベクターアニメーションを作ることができます。
参照:https://zenn.dev/getgotgoto/articles/7db64306a93193
準備
WebUIプラグインをUE5.3にインストール
これを使うとHTMLの表示、Javascriptとのイベント通知などができるようになります。
ランチャーエンジンであればFreeTrial版で試せます。ソースコードがほしい場合でも15$で購入できます。
インストール方法はドキュメントを見てください。
サンプルプロジェクトがついているのでこれで確認していきましょう。
プレイしてUEのアイコンが上下にふわふわしていたらHTMLを表示できています。
FPS表示とPlay、QUITボタン、音量調整のつまみがありますので
このサンプルでBPとのイベント通知の仕組みが確認することができます。
jQuery(function()
{
$("#playGame").click(function(e)
{
$("#logo").fadeOut(1000);
$("#playGame").fadeOut(1000);
$("#quitGame").fadeOut(1000);
$("#volumeSlider").fadeOut(500);
// executed in blueprints
ue5("play");
});
$("#quitGame").click(function(e)
{
// executed in blueprints
ue5("quit");
});
$("#volumeSlider").on("input", function(e)
{
// executed in blueprints
ue5("volume", parseFloat($(this).val()));
});
// notify blueprint that browser is ready
ue5("ready");
// delay for 1 sec
setTimeout(function()
{
// transmit data to the game
ue5("print",
{
"browser": navigator.userAgent,
"time": Date.now()
});
},
1000);
});
Lottie Playerをインストール
ここの
build/player
フォルダを
Contents/HTML
以下にコピーします。
playerじゃ分かりにくいのでlottieという名前に変更しました。
sample.htmlをちょちょっと改造します。
<html>
<head>
<script>
// create the global ue5(...) helper function
"object"!=typeof ue&&(ue={}),uuidv4=function(){return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,function(t){return(t^crypto.getRandomValues(new Uint8Array(1))[0]&15>>t/4).toString(16)})},ue5=function(r){return"object"!=typeof ue.interface||"function"!=typeof ue.interface.broadcast?(ue.interface={},function(t,e,n,o){var u,i;"string"==typeof t&&("function"==typeof e&&(o=n,n=e,e=null),u=[t,"",r(n,o)],void 0!==e&&(u[1]=e),i=encodeURIComponent(JSON.stringify(u)),"object"==typeof history&&"function"==typeof history.pushState?(history.pushState({},"","#"+i),history.pushState({},"","#"+encodeURIComponent("[]"))):(document.location.hash=i,document.location.hash=encodeURIComponent("[]")))}):(i=ue.interface,ue.interface={},function(t,e,n,o){var u;"string"==typeof t&&("function"==typeof e&&(o=n,n=e,e=null),u=r(n,o),void 0!==e?i.broadcast(t,JSON.stringify(e),u):i.broadcast(t,"",u))});var i}(function(t,e){if("function"!=typeof t)return"";var n=uuidv4();return ue.interface[n]=t,setTimeout(function(){delete ue.interface[n]},1e3*Math.max(1,parseInt(e)||0)),n});
</script>
<style>
#fpsMeter{font-family:'Open Sans',Arial,Helvetica,Verdana,sans-serif}
#fpsMeter{position:absolute}
#fpsMeter{top:3vh;left:5vh;color:#fff;font-size:18px;text-shadow:0 0 .2vh rgba(0,0,0,.5),0 0 1vh rgba(0,0,0,.5)}
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="lottie/lottie.min.js" type="text/javascript"></script>
<script>
// called in-game via blueprints
ue.interface.setFPS = function(fps)
{
// set element text
$("#fpsMeter").text(fps.toFixed(1) + " FPS");
};
// delay until browser is ready
jQuery(function()
{
// notify blueprint that browser is ready
ue5("ready");
});
</script>
</head>
<body style="background-color: transparent; -webkit-user-select: none;">
<p id="fpsMeter">0 FPS</p>
<div style="width:100%;height:100%;background-color:#333;display:inline-block;" class="bodymovin" data-bm-path="data.json" data-bm-renderer="svg"></div>
</body>
</html>
ポイントは
<script src="lottie/lottie.min.js" type="text/javascript"></script>
ここでプレイヤーのjsを指定して
<div style="width:100%;height:100%;background-color:#333;display:inline-block;" class="bodymovin" data-bm-path="data.json" data-bm-renderer="svg"></div>
ここでjsonファイルを指定すると勝手に再生してくれます。
やったー!再生できました。
使い所
NowLoading
See the Pen NowLoading by 癒系 (@hrcvjbtz-the-bashful) on CodePen.
ボタン
画面遷移
画面遷移なんかをラスタ画像でやろうとするとテクスチャサイズがデカくなりがちですが
こういう全画面に表示する場合でも小さいサイズのデータできれいに表示できて良さそうです。
divタグのbackground-colorをtransparentにすれば背景透過もできました。
運用についての提案
UIを全部HTMLで作れるかもと検討してみたのですがHTMLでレイアウトを書くのは大変ですし、かといってホームページビルダーみたいなツールが吐く自動HTMLコードは保守が大変そうです。
ということで、基本はUMGで作ってボタンやカーソルなど部品として使うのがよさそうです。
処理負荷について
ちゃんと調べてないですがエディタで21個再生してこれくらいなのでボタンとか数個程度なら心配する必要はなさそうです。
まとめ
UMGのアニメーションやマテリアルで頑張ればやれるかもしれないですが
編集環境にAfterEffectsを使えるというのは強い気がします。
手軽にかっこいいアニメーションを作ってユーザーにいいね!
って思ってもらえるようなUIを作っていきたいですね。
自分はプログラマなのでデザインできないですが。
以上。