takeda_san’s blog

JavaFXと機械学習を頑張る方向。

VRで焚火を眺めたい その1(焚火を作る編)

なぜつくるのか

焚火をぼんやり眺めるのが好きなので。
あと、Unityのパーティクルの勉強もかねて。

初手Standard Asset

火ってStandard Assetにありそうよね。
とおもってインポートしてみたら、本当にあった。

  • FIreMobile
    松明っぽい。
    f:id:takeda_san:20180217142030g:plain

  • FIreComplex
    火の魔法みたい。
    f:id:takeda_san:20180217142155g:plain

んー、素晴らしいクオリティ。
これを使ってもいいけどお勉強のために自分でも作ってみよう。

火の表現

火というか、エフェクトはパーティクルを使って作るらしい。
Unityのパーティクルでエフェクトを演出 - Qiita

ありがとう、先人の方
Unity パーティクル(2) 炎のエフェクト 松明風と某悪魔風 - LemonteaのUnity部屋

  • パーティクルを追加して
    Create -> Effects -> Particle System f:id:takeda_san:20180217163926p:plain

  • 火っぽい色にして
    Inspector -> Start Color f:id:takeda_san:20180217163930p:plain

  • たくさん粒子を出すようにする
    一度に出る粒子数を指定できる。
    Inspector -> Emission -> Rate over Time f:id:takeda_san:20180217163934p:plain

  • 粒子をもやっとした画像にする
    RendererのMaterialに任意のテクスチャが設定できる。
    Inspector -> Renderer -> Material f:id:takeda_san:20180217164627p:plain

ここまでの途中経過。
火事だこれ。
f:id:takeda_san:20180217164905g:plain

  • 粒子の消えるまでの期間を短く、初速を遅くする
    Inspector -> Start Lifetime
    Inspector -> Start Speed

  • 粒子を時間が経つごとに小さくする
    このグラフの縦軸が粒子の大きさ、横軸が時間の経過。
    Inspector -> Size over Lifetime -> Size
    f:id:takeda_san:20180217170000p:plain

  • 粒子がゆらゆら動くようにする
    Noiseを設定することで、今まで放射状に出ていた粒子が不規則に動くようになる。
    Unity5.5 パーティクルシステム | ギャップロ

Inspector -> Noise
f:id:takeda_san:20180217171437p:plain

  • 最後にちょっと調整
    最初の粒子の大きさがちょっと小さくて燃えてる感がないので調整。
    Inspector -> Start size

できた(1回目)

だいぶ火っぽい。
(焚火とはいいがたい燃え方に目をそらしつつ)
f:id:takeda_san:20180217171610g:plain

風にゆらめく感を出したい

風にゆらめく火は良いものだ。
さすがに、これは自分でスクリプト書かないとないでしょ。

WindZone。あるね。うん、何でもあるね。
Wind Zone - Unity マニュアル

  • WindZoneを追加
    WIndZoneで任意の方向に風を吹かせることができる。
    Modeで吸い込むか吐き出すかを指定できる。
    Directional-> 一方向の風/Spherical-> 球の中心から外側への風
    Create -> 3D Object -> Wind Zone
    f:id:takeda_san:20180217174336p:plain

  • particleがWindZoneの影響を受けるようにする
    External Forcesにチェックを受けると外部からの影響を受けるようになるようだ。
    Multiplierの数値を調整することで影響を受ける度合いを変えることができる。
    Inspector -> Multiplier
    f:id:takeda_san:20180217174734p:plain

できた(2回目)

すごいきょうふうだ。
f:id:takeda_san:20180217174830g:plain

よし、焚火をつくろう

パーティクルを""""完全に理解した""""ので、アセットを組み合わせて焚火を作ろう。

使ったもの

  • Camfire Pack(modelBonfire)
  • Standard Asset(FIreComplex)

いろいろ試したんだけど結局、Sandard Asset最高ってやつです。

できた(3回目)

f:id:takeda_san:20180217214820g:plain

変えたのは、FIreComplexの中のSparksFallingの個数を2に変更したぐらい。
火の粉がぱちぱち飛んで危なそうだったので。
f:id:takeda_san:20180217215140p:plain

次回やることと課題

今回パーティクルで作ったんだけれども、この焚火上から見ると平面なのよね。
f:id:takeda_san:20180217215503p:plain

火のテクスチャをアニメーションさせて表示しているので、側面からなら常に正面の絵を表示すればよいけど、 真上から見たときの絵がないのよね。
次回は実際にHMDで見えるようにして、確認してみる。
あと、マシュマロ焼けるようにする。

SteamVRでSURIYUNのNaokoさんの表示がおかしくなるやつ

SURIYUNのNaokoさんファンの皆様、お待たせいたしました。

問題

SteamVRでSURIYUN殿のNaokoさん(↓のメイドさん)を動かすと、輪郭がぶっとくなって表示がおかしくなる。

外のカメラから見ると、こうだけど。 (かわいい)
f:id:takeda_san:20180215211850p:plain

自分のHMDからはこう見えてる。
f:id:takeda_san:20180215212209p:plain

この問題、前の記事ではField of Viewの値が書き換わってて表示が変になってそうだけど、動的に変わるから直せないとあきらめてました。

takeda-san.hatenablog.com

でもね、自分で自分を見たときにかわいくなければVRじゃないと思うんです。

直し方

ちゃんと原因わかってないので、アレなんですけどシェーダーを変えてあげると、直りました。
デフォルトでついてたシェーダーがVRには向かないってことなんかなぁ。
勉強したいことが次々と増えていく…

手順

Naokoさんのシェーダーを変更します。 対象は↓の画像の通り。
f:id:takeda_san:20180215213705p:plain

これを選択状態にしたまま、シェーダー選択する。

f:id:takeda_san:20180215215903p:plain

今回はToonのBasic Outlineにしてみました。
ほかにもtoony Freeとかでも、お好きなものをどうぞ。
(Toonってボダランみたいな見た目になって良い)

f:id:takeda_san:20180215215830p:plain

あとはOuline Colorを薄めの色にして、Outline widthを細くすると… 自分のHMDで見てもカワイイヤッター
(顔色が悪いのは、多分ライトが適当だからだと思います)

f:id:takeda_san:20180215215119p:plain

f:id:takeda_san:20180215215231p:plain

元ネタ

モデルの作者SURIYUN殿がVRChatに自身が出してるモデルをアップロードする方法を動画で上げてるんだけれども、それをそのまま設定したら、あ、動いたってなったので。
アフターサービスもばっちりなんて素敵…

Import Riko to VRchat. - YouTube

バーチャルユーチューバーになりたい その2 ~websocketを添えて~

やること

WebアプリケーションのUIからUnityアプリケーションのオブジェクト操作できるようにする。
YoutubeLive中のUnityアプリケーションに外から干渉出来たら楽しそうじゃないかって思いました。
通信の方法として、websoketを使うんだけれどもYoutubeLiveを通したときの遅延具合はどんなもんかも確認してみる。

成果発表

今回もおじさんが登場しますので、ご注意ください。


生放送向けの機能をつくりました

つかったもの

websocketサーバ

Unityアプリケーション

  • websocket-sharp
    Unityでwebsocketやる用

  • 前回まで作ったScene

takeda-san.hatenablog.com

作業記録

おためし動作確認

ここを参考にしました。
ブラウザからのアクセスして使う例としてSTOMPのサンプルがあったんだけど、今回はUnityがあるから使えないという認識。
コード見る限りSTOMPのほうがコード量が少なくて楽そう…

UnityアプリをSpringbootのWebSocketでつないでみた - SSSSLIDE

SpringでSTOMPを使わずにWebSocket - vaguely

あと、当たり前すぎて書いてないんだろうけどスクリプトを空のオブジェクトにかなんかにアタッチして動作確認が必要…
確かにひよこ本でも、さんざんやったね。
で、Unityアプリケーションから、websocketサーバのメッセージを受け取れるか確認する。

f:id:takeda_san:20180208210515p:plain

ほぼ、そのまんまでテキストデータのやり取りができた。

座標データを送る

つぎはオブジェクトのデータをやり取りしよう。
といっても同じテキストデータでjson形式でやりとりなんだけどもね。

Unity側のスクリプトをこんな感じで書き換えて。

[Serializable]
public class Item
{
    public float x;
    public float y;
    public float z;
}

public class ClientExample : MonoBehaviour
{

    private WebSocket ws;
    private Item item;

    private void Start()
    {
        ws = new WebSocket("ws://localhost:8080/ws");
        item = JsonUtility.FromJson<Item>("{ \"x\": 0, \"y\": 0, \"z\": 0 }");

        // 接続開始時のイベント.
        ws.OnOpen += (sender, e) =>
        {
            Debug.Log("Opended");
        };
        // メッセージ受信時のイベント.
        ws.OnMessage += (sender, e) =>
        {
            Debug.Log("Received " + e.Data);
            item = JsonUtility.FromJson<Item>(e.Data);
            Debug.Log(item.x+ ":" + item.y+ ":" + item.z);
        };
        // 接続.
        ws.Connect();

    }

    private void Update()
    {
        transform.Translate(item.x * 0.08f, item.y, item.z);

        if (Input.anyKey)
        {
            ws.Send("Unityから疎通テスト");
        }
    }

    private void OnDestroy()
    {
        ws.Close();
    }

実行、そして、Webから入力を受け取って等速直線運動をする何か。
壮大な遠回りである。
f:id:takeda_san:20180208221324g:plain

これでWebページから入力をUnityのアプリケーションに伝えられるようになった。

やりたいこと

WebページにYoutubeLiveを埋め込んで、UIつけてUnityアプリケーション内のオブジェクトを動かせたら楽しいだろうなぁと、妄想していたのですが動画配信時の遅延のことを忘れていました。
YoutubeLiveの遅延は、超低遅延設定で3~5秒ぐらいとのこと。

YouTube Liveが超低遅延になった話 – たまには叫びたいこともある – Medium

普通にコメントを拾ってお話しする分には、十分すぎるぐらいに早いが今回やろうとしていたことは無理そうね。
そもそも、こういう用途は専用のクライアントを事前に配布→サーバで映像にしたものを配信するのが大正解な気がする。
VRLIVEとかって、そんな感じっぽいよね。

vrlive.party

でもでも、アプリインストールとかしなくて、もうちょっと気楽に参加したいし、サーバの規模も最小限にしたい。
というわけで、数秒遅延してもそんなに気にならないようなものを考える。

ひらがな並び替えるやつ

なんか昔に、みんなでよってたかってアルファベットを並び替えるFLASHゲームがあったのを思い出した。
あれをちょっと変えて、ひらがなで実装してみよう。
頑張ってメッセージを作ろうとすると妨害されてムキになって、人生の貴重な数十分を無駄にした思い出がある。
これ、生配信の背景とかでやったら、意外にたのしいんじゃなかろか。
放送禁止用語になっちゃう、アッ、アッみたいなハラハラドキドキ。

できたもの

f:id:takeda_san:20180212191336g:plain

これを、Unity上で映せばそれっぽいものが出来上がる。
(最初の動画参照)

ここから遊べます。
(監視とかしてないので、落ちてたらすいません)
http://35.203.14.233:8080/

コードはここに置いてあります。

github.com

反省

結局UnityもVRもあんまり関係なくなってしまった感がある…
この文字をSteam VR上から動かせれば、さらに楽しくなりそうなので、もう少しバージョンアップ予定。

バーチャルユーチューバーになりたい その1

読み始める前に

バーチャルユーチューバーおじさんが登場します。
精神に負荷がかかるシーンが多少ありますので、心に余裕がある方のみ読み進めてください。

成果発表


バーチャルユーチューバーになりたい

なぜ、やるのか

かわいい女の子になってみたかったんです。
あと、Youtubeに動画上げてみたい。

つかったもの

  • HTC Vive
    ヨドバシで購入 85,000円ぐらいでした。

  • GTX1060 VRAM6G
    おなじくヨドバシで購入 40,000円ぐらいでした。
    GTX960を使っていて、これでもギリギリ動くっぽいのですが、公式的には1060以上らしいので買い替え。
    取り替えて、いくつかゲームしてみましたが快適動作でした。

  • Final IK
    IK…少ないトラッカーで人間型のモデルを動かすスーパ技術のことらしい。
    今回はHMDとコントローラー2つという少なさなので必須。
    90ドル。

  • OVRLipSync
    リップシンクさせるために使いました。
    使うときはまずは動作確認で、LipSync Demoで声を出したときに動くか見たほうがいいかもしれない。

  • UnityCam
    Unityの映像をWebカメラ映像として出力できるプラグイン
    撮影に使います。
    GitHub - mrayy/UnityCam: Unity3D Virtual webcam plugin, streams unity viewport contents to other applications as virtual camera

  • ユニティちゃん
    動画ではアセットストアで購入したモデルを使ってますが、その前のお勉強中はユニティちゃんを使いました。
    unity-chan.com スクリプトが初めから全部入りで、サクサク進められました。
    (インポートして少し設定しただけでカワイイ!なものが出来上がる)
    あと、ライセンスがちゃんと書いてあって安心して使えるのも良いですね。

  • Unity 2017入門
    モデルとの同期をUnityで実装するのですが、一度も使ったことないので入門書を一冊。
    プログラム初学者でもつまづかないぐらいの絵の多さと説明の丁寧さで、スイスイ読み進められました。
    とにかくすべての手順にスクリーンショットがあるし、躓きそうなところにはヒントがたくさん。
    これとC#の文法勉強用に何か一冊あれば最初は十分なのかなぁという感じ。
    (Unityがすごすぎて、あんまりコードは書かなくて良いんだけどこの機会にC#も覚えたいという動機)

実践編

Unity、VR未経験者がこんなかんじで勉強してみました。という記録です。
何かの参考になれば。

VRで遊ぼう

何はともあれ、ワクワクが止まらないので遊んでみる。
我が家は6畳ワンルームなのですが、お掃除したらギリギリ、ルームスケール使えました。
でも、数歩あるくと壁に当たってしまってあんまり意味ないかなぁという感想。

お試しで、無料のThe Labというゲームをやってみました。(Valve製!)
途中、ドローンをラジコンで飛ばせるんだけど、これがすごい楽しくて気が付くと1時間ほどたってました。
f:id:takeda_san:20180130231541j:plain

↑ドローンを追いかける犬っぽい何かの様子

シューティング、ホラーなどなど、こんなことできまっせ的なショウケースゲームでした。
(個人的には、ポータルのキャラクターが出てきたのが、すごくうれしい)

ユニティちゃん編

Unity 2017入門をひと通りやり終えて、"""""Unity完全に理解した"""""感あるので、VRしてみる。

とはいいつつ、この辺の内容をそのまま、ポチポチ設定すれば動いてしまった。
偉大な先駆者の皆様のおかげで私もかわいい女の子になれました。

VRで「結月ゆかり」になって生放送する - Qiita

【Unity道場スペシャル 2017札幌】おっさんでも美少女になれる?!VRアイドルの作り方

違うところは、ユニティちゃんを使ったところ。
そのままの設定だと右手首が真逆に曲がってたので、ちょっと調整。

f:id:takeda_san:20180201230027p:plain

あと、当たり前すぎて書いてないんだろうけど↓が最初に必要。

  • SteamVR -> Prefabs 内の [CameraRig][Status][SteamVR]Hierarchyのところに入れておく
  • メインカメラは削除する
  • [CameraRig] -> Controllerのleftとright配下のModelを削除しておく(そのままだとviveのコントローラーが表示される)
  • 毎回出てくるSteamVRのポップアップはSteamVR_Settings.csのconst bool recommended_ShowUnitySplashScreen = false;tureにする
    stackoverflow.com

うん、これ一時間ぐらい悩んだ…

f:id:takeda_san:20180201230643g:plain

© Unity Technologies Japan/UCL

自分の姿が見えないので、鏡をおいてみました。
自分、かわいい。

Naokoさん編

上の動画を撮った後にちょっとした事故があり、Stageをイチから作り直しになりました…
気分転換にモデルも変えようということで、Asset Storeでモデルを買って再出発。

Naoko - Asset Store

Naokoさんです。
同じようにViveとFInalIK設定を済ませて、リップシンク用の設定を確認。

OVRLipSync設定

ユニティちゃんのようにあ・い・う・え・おの口の形は、ないようだが、表情用の設定があるのでそれを使う。
(Naoko -> Root_M -> RootPath1_M -> Spine1_M -> Chest_M -> 'Neck_M' -> Head_M -> Face_AのSkinned Mesh Rendererの各項目)

Face_smile = 100にしたときのご尊顔。
表示がちょっとおかしいですが、後の設定で直します。
f:id:takeda_san:20180202231344p:plain

はまったところ

  • なぜか数回に一回うまく設定できる

わからん…デバッグの仕方もわからんし、どこでエラーが出てるのかもわからん…
1回目…動かないプロジェクトごと再作成
2回目…動かないプロジェクトごと再作成
3回目…なぜか動く、手順確認のためプロジェクト再作成
4回目…動かない 深夜4時
とりあえず、切り戻して3回目のプロジェクトで再開。
Unityわからない…Unityこわい…

ちなみに設定値はこちら。
パッとみて違和感がないぐらいの調整ぶりです。
f:id:takeda_san:20180203035021p:plain

表情をつけよう

Viveのコントローラーのボタンを押している間は表情を変えるようにしてみます。
コントローラーの入力は下記を参照しました。

Unity+HTC Vive開発メモ - フレームシンセシス

表情の変更はNaokoさんのデモ用SceneのUIの設定を参考にしました。

で、これを右手にアタッチしてNaokoさんをAnimatorに指定しておきます。

f:id:takeda_san:20180203111157p:plain

f:id:takeda_san:20180203111215g:plain

にっこり。

表示がおかしいのを直す

Naokoさんの周りにオレンジ色の何かと緑色の何かが出る件を対応します。
f:id:takeda_san:20180202231344p:plain

Naokoさんのデモ用Sceneではアップにしても同じ現象が起きないので、設定を比較してところ、CameraのField of Viewという設定値を10にすると表示が直った。
Field of Viewとは何ぞや。
カメラ - Unity マニュアル

ローカル のY 軸方向の角度から算出した、カメラ視野角の広さ。
この値が、VRデバイス側から更新されるため表示が変になっているらしい。
視野角が広いと表示がおかしくなるというのが、いまいち納得できないが撮影用のカメラの設定を変えれば良さそうなのでいったん保留。

【2018/02/15 追記】
自分のHMDで見たときもちゃんと表示されるように設定できました。

takeda-san.hatenablog.com

撮影用のカメラを作る

撮影に使いたいアングルでカメラを設置して、Target Eye に Noneを設定する。
こうすることでHMDとモニタ上に映る映像を別にできた。

カメラの設定値
f:id:takeda_san:20180203123231p:plain

f:id:takeda_san:20180203123136p:plain

下の撮影用のカメラはアップで映しても、Field of Viewが変更されないのできれいに映る。
あと、自分かわいい。

撮影編

最低限の設定はしたと思うので、映像を録画できるように環境を構築する。

UnityCam

github.com

ここからプロジェクトまるごとzipで落としてきて、適当な場所に解凍。
あとはReadmeのUsage通りだと思います。

OBS

Open Broadcaster Software | ホーム

ここからインストーラをダウンロードしてきて、インストール。
Unityのほうを実行状態にして、
起動後、画面下のソースの+ボタンから映像キャプチャデバイス -> 新規作成でOK -> デバイスをUnityCamを選択
録画しようとするとUnityがフリーズするので調べてみると、設定 -> 詳細設定 -> 自動的に再接続をオフ。

f:id:takeda_san:20180203133049p:plain

ばっちりですね。

カメラ、撮影の準備

自分がどう映っているのかがわからないと不安なので、鏡をカメラの後ろに置きます。
あと、カメラ目線がカワイイと気が付いたのでカメラの位置に適当なオブジェクトを置きました。

台本作成・撮影・編集

何かをほかの人に説明するというのが非常に苦手なので、完全台本にしました。
バーチャルユーチューバーのレジェンド方を参考に作成。

撮影は途中で止めずに最後までやり切って、編集時に聞き取りにくかったりする良くないシーンだけ撮り直して差し替えました。
なんか、プレゼンテーションの練習してるみたいでひどく疲れた。

動画編集はShotcutというソフトを使いました。
デフォルトで使いやすくて、UIも直感的、キャプション入れるのにHTML+JSが使えるのに惚れました。

www.shotcut.org

動画公開

こうしてできたのが、記事の最初の動画です。
ここまでHTC Viveが届いてから二週間ぐらいでした。
Unityを使ったことがある人なら週末で出来ちゃうぐらいのお手軽さでバーチャルユーチューバーデビューできるとは素晴らしい世の中。

やってみての感想

  • 設定を進めるほど自分がかわいくなっていくのがうれしい
  • プログラムをほとんど書かない(10行ぐらいしか書いてない)
  • かわいいというのは、高い癒し効果がある

次回予定

これ、すごく楽しかったのでもちっとだけ続きます。
ちょっとずつ出来ることを増やしてよりカワイイを目指します。

  • 物を持てるようにする
  • 手の形を変えられるようにする

このあたりはVRChatとかで見かけて、是非とも取り入れたい機能なので真っ先に作ります。

Spring MVC + Thymeleafでバリデーションしたい

いつも書き方を忘れて、ネットの海をさ迷っちゃうのでいい加減自分でまとめようと思う。

コードはここです。
Kotlinなのは特に意味はないけれど、定期的に書かないと忘れちゃうからです。

github.com

とりあえず入力チェック編

まずは、必須入力チェックをしてみる。

f:id:takeda_san:20180115231808p:plain

ポイントその1:@NotNullじゃなくて@NotBlankを使うよ
@NotBlank
var name: String = ""

ここ、HTMLのtextフォームからフォームクラスにStringで値が入るときには、空""で入ってくる仕様らしい。
なのでnullかどうかを見る、@NotNullだとバリデートエラーにならなくて、空白か空かどうかも見てくれる、@NotBlankのほうがよさそう。

ポイントその2:BindingResultは必ず@Validatedの後
@RequestMapping(method = arrayOf(RequestMethod.POST))
fun doPost(@Validated inputForm: InputForm, bindingResult: BindingResult, model: Model): String {

    return "input/form";
}

BindingResultには、@Validatedを付けた引数のバリデート結果が入る。
んで、このBindingResult@Validatedが付いた引数の後ろに定義するという村の決まりごとがあって、これをしないとエラーでこける。

日本語で表示したい編

これ、エラー表示が英語じゃないですか!
そうですね、日本語で表示しましょう。

resourcesディレクトリの直下にValidationMessages.propertiesというファイルを作って、以下を書く。

org.hibernate.validator.constraints.NotBlank.message={0}:必須入力ですよ

んで、もう一度アプリケーション起動して、送信してみる。

f:id:takeda_san:20180116223249p:plain org.springframework.context.support.DefaultMessageSourceResolvable: codes [inputForm.name,name]; arguments []; default message [name]:必須入力ですよ

なんかtoStringっぽいのが出ているが、無事指定したメッセージが出でる。 @NotBlankは、hibernate validatorのアノテーションなので、そのデフォルトのメッセージ定義を上書きしてあげればよい。
ほかのアノテーションの定義は↓から、確認できる。

github.com

ポイントその3 プロパティファイルのはエンコーディングUTF-8

IDEとかで、プロパティファイルを作ると ISO-8859-1でエンコードされたりするんだけど、これだと日本語が文字化けしてうまく出力されない。
ちゃんと、エンコードの設定を確認する。

ポイントその4 {0}を使うときはメッセージ定義ファイルを作る

で、ここ({0})の部分。
ほかの解説ページとかだと、プロパティ名(今回の例だとname)が出るって書いてあるんだけど、うまく出てない。
org.springframework.context.support.DefaultMessageSourceResolvable: codes [inputForm.name,name]; arguments []; default message [name]

なぜかはわからんが、メッセージ定義ファイルを作ってあげるとちゃんと出る。
(しばらくなんでか調べたけどよくわからんかった)

外部にメッセージ定義(リソース?)を持つ設定の仕方は、いろんなところに書いてあると思うので説明は割愛。
application.propertiesに以下を設定。

spring.messages.basename=messages
spring.messages.cache-seconds=-1
spring.messages.encoding=UTF-8

resourcesディレクトリの直下にmessages.propertiesを作る。
(ファイルの名前は設定と一致してればなんでもよさそう)

もう一度起動しなおして、送信。
f:id:takeda_san:20180116224841p:plain

プロパティ名が出ました。
エラーメッセージにプロパティ名が出たのはいいけど、ユーザからしたらnameって何ぞや状態なので、これも差し替えましょう。
さっき作ったmessages.propertiesに、↓を書く。

name=名前

すると、ちゃんとnameのところが差し変わっている。
f:id:takeda_san:20180116225135p:plain

ちなみに、nameの部分はプロパティ名で、inputForm.nameとかでもちゃんと置換される。

独自のメッセージを表示したい編

おなじ、@NotBlankエラーでも違うエラーメッセージを項目ごとに出したいことがある。
その時は、次のようにアノテーションを指定する。

InputForm.kt

@NotBlank(message="年齢も恥ずかしがらずにちゃんと入力しよう")
var age: String = ""

アノテーションに直接メッセージを埋め込みたくない、几帳面なあなたはValidationMessages.propertiesにメッセージを書いて、それのキーを埋め込もう。

InputForm.kt

@NotBlank(message="{E0001}")
var age: String = ""

ValidationMessages.properties

E0001=年齢も恥ずかしがらずにちゃんと入力しよう

E0001、業務感がすごくてわくわくする

f:id:takeda_san:20180116230339p:plain

相関チェックしたい編

独自のチェックだったり、二つ以上の項目についてチェックしたいことがある。
そんな時は、自分でアノテーションを定義して、それを使う。

長々と書いてあるが、isValidがfalseならエラーになる。
それだけ。

    public boolean isValid(Object value, ConstraintValidatorContext context) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(value);

        String param1 = (String)beanWrapper.getPropertyValue(this.param1Field);
        String param2 = (String)beanWrapper.getPropertyValue(this.param2Field);

        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(message)
                .addPropertyNode(this.param2Field)
                .addConstraintViolation();

        return Objects.equals(param1, param2);
    }

なぜここだけJavaなのか…
それはKotlinでアノテーションの書き方がわからなかったからだよ。
悲しい。

ポイントその5 アノテーションは、クラス宣言の上につける

相関チェックみたいに複数のプロパティを対象とするバリデートのアノテーションは、クラスの宣言部分の上につける。

@Equals(param1 = "email1", param2 = "email2")
class InputForm {

こんな感じ。

f:id:takeda_san:20180118223931p:plain

はじめてのSass

なぜ書くのか

Springでいろいろとやっていくうちに、WebサイトのHTMLとCSSをたくさん書くようになった。
自由奔放にCSSを書いて、そのあとに『サイトのテーマカラー変えようぜ!』と言われると非常に困ることがあった。
たとえば

  • テーマカラーとしての青
  • 決定ボタンとしての青
  • リンクの色の青

これが全部、同じ色のコードでスタイルの名前からは推測が難しい場合に一括置換できなくて泣きそうになる。
変えたいのはテーマカラーの青だけなのに、スタイルが意図しないところで使われてて、ほかのところも変わっちゃったり。

ほかにも、同じ部品用のスタイルがcssファイルに点在していて非常に見づらい。
点在しているはぐれスタイルを直し忘れて、つらい思いを日々している。
故郷のサーバーのサービスクラスのコードを書く仕事に帰りたい…

で、やりたいことが

  • 色の定数定義がしたい
    定数定義をスタイルで使って、色を変えたいときは、定義のコードを直すだけで、すべてのスタイルが適切に置き換わるようにしたい

  • 同じ部品のスタイルは一か所にまとめたい
    商品表示用のdivの配下につけるスタイルは、一か所にまとめて書く!みたいのを制限としてつけたい

でも、CSSでそんなことできるわけが…
それが、できるみたいなんですよ奥様。

SASS

なんかこれ、界隈では常識なのね。
CSSを直書きしていたのが、恥ずかしいわ。

sass-lang.com

上で書いたようなやりたいことが、このSassで出来るらしい。
CSSを便利に書けるようにしたSASSをコンパイルしてCSSにしてからHTMLに読み込ませるらしい。

やってみよう

  1. SASSを書きたい
  2. SCSSをCSSに変換するため、コンパイル環境が必要
  3. コンパイル環境の作成にはnode-sassというものが必要(本当はRubyでやるのが公式っぽい)
  4. node-sassを入れるためにパッケージ管理のnpmが必要
  5. npmの動作にはnode.jsが必要

うーん、この、RPGのTODOを箇条書きにした感じ。
そして、ついにナウさの頂点であるWeb界隈に本格入門する時が来てしまったか…

歴史編

作業の前にイマイチ、npmとかnode.jsが何者かわからないので歴史の勉強。
歴史大事。
npm とか bower とか一体何なんだよ!Javascript 界隈の文脈を理解しよう - Qiita

読んだ感想:Web界隈、進歩が早すぎる
Java EEとかだと仕様をじっくりねっとり考えて、固めて、各ベンダーが実装。
さらに開発者が使えるようになって、システムに組み込まれて、世に出るには1~2年ぐらい遅延がある。

対して、Web界隈はナウさの頂点だけあって課題解決のためには使ってみて、ええやん!だったものが、
標準になって、さらにそれを元に進化していくみたいな感じなのね。
戦場で鍛えられた実践主義みたいな感じでカッコイイ。

環境構築編

↓の通りにやってみよう。
なぜならcmderをオススメし、使っている為だ。+100万点。
みんなも使おうcmder。
xn--web-oi9du9bc8tgu2a.com

node.jsのインストールとnpmの動作確認

node.jsは、Windowsの場合初期設定がいろいろ必要なようなので、そのままインストールせずにnodistというので入れるのが良いらしい。
PATHの管理とかめんどくさそうだもんね…

C:\Users\takeda
λ nodist -v
0.8.8

また、node.jsをいれるとnpmも使えるようになるとのこと。

C:\Users\takeda
λ nodist + v8.9.4

C:\Users\takeda
λ nodist v8.9.4
v8.9.4
Default global pacakge update dsuccessful.

C:\Users\takeda
λ node -v
v8.9.4

C:\Users\takeda
λ npm -v
4.0.5

おー、すばらしい。

node-sassをインストール

npmでnode-sassを入れます。

C:\Users\takeda
λ npm i -g node-sass

C:\Users\takeda
λ node-sass -v
node-sass       4.7.2   (Wrapper)       [JavaScript]
libsass         3.5.0.beta.2    (Sass Compiler) [C/C++]

ログを見る限り、C:\Program Files (x86)\Nodist\binの下にインストールされるみたいね。

Sass書いてみよう編

適当なディレクトリを作る。

C:\Users\takeda
λ mkdir mysass

んで、実際に書いてみましょう。
(ここまでが長すぎる)

$base-color: #666;

body {
  color: $base-color;
}

こんな感じで色とかの値を定義できる。
テーマカラーとかをこれで定義して使えば、今までよりは書き直しやすくなるだろう。

.shop-list {
  font-size: 18px;
  
  a {
    font-size: 14px;
    color: $link-color;
  }
}

こんな感じで、入れ子で一つのスタイルを定義できる。
これで一つの部品に対するスタイルは一か所にまとまるだろう。

コンパイルしてみよう

C:\Users\takeda\mysass
λ node-sass style.scss style.css
Rendering Complete, saving .css file...
Wrote CSS to C:\Users\takeda\mysass\style.css

node-sass scssファイル名 cssファイル名 と指定して、コンパイルする。

出来たCSSを見に行こう。

んー、閉じかっこの位置が気に食わない。
でも、これが仕様らしい、まぁ確かにコンパイル後のコードって気にしないからどうでもいいか。
ちゃんと定義した値で置き換わってるし、入れ子にしたところは展開されている。
素晴らしい。

最後に

変更検知

実際に使うとなると、sassを変更して、いちいちコンパイルのコマンド打つのって大変。
このへんもちゃんと考えてあって変更検知用の設定もあるようだ。
node-sass style.scss style.css -w

僕にMacを買ってください

Windowsでnode.jsやろうとすると一工夫が必要。
多分ほかのツールにおいても、そうなのではないだろうか…
みんながMac使ってる理由がよくわかりました。

自分コインで採掘ごっこをしよう

やりたいこと

暗号通貨の採掘をしたい!!!
でも、今更採掘しても報酬が少ないらしい。
ゴールドラッシュを体験したい!!!
よし、自分でコインを作って、ザックザック掘ってやるぞ。

f:id:takeda_san:20180102224957p:plain

コードはここ。
github.com

あそびかた

注意事項

  • 採掘して得たコインは使い道がありません(!)
  • 採掘中はハッシュ探索の処理をしているのでCPUに負荷がかかります(!!)
  • アカウント管理をしていないのでリフレッシュすると残高がなくなります(!!!)
  • ほぼテストしてないので、バグがあるかもしれないです(!!!!)

遊び方(シングルプレイ)

Java 8以上で動かしてください。

  1. Jarファイルを落としてくる
    ↓からtsuramichain-0.0.1-SNAPSHOT.jarをダウンロードする。
    Release 0.0.1 · takedasan/tsuramichain · GitHub

  2. 起動する
    tsuramichain-0.0.1-SNAPSHOT.jarがおいてあるディレクトリまで移動して、↓のコマンドを実行する。
    java -jar tsuramichain-0.0.1-SNAPSHOT.jar

  3. Webページを開く
    http://localhost:HOGE/で開きます。
    HOGE→ログの中にポートがあるので、それを入れる。
    2018-01-02 22:47:02.186 INFO 7496 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 51095 (http)
    ↑こんなの、このログ場合はhttp://localhost:51095/で開く。

  4. 採掘開始!
    赤枠のスイッチをonにすると採掘開始で、コインがザックザックです。
    f:id:takeda_san:20180102225538p:plain

遊び方(マルチプレイ)

(本来、こっちがブロックチェーン的には正しい遊び方よね)

  1. サービスを複数起動する
    シングルプレイと同じようにJarから起動する。
    マルチプレイなので2つ以上やっておく。
    (ポートはランダムで振られるので多分衝突しないはず…)

  2. Webページをそれぞれひらいて、ノードを登録する
    一方のページでもう一方のサービスのホスト:ポートを入れて、Registボタンを押す。
    f:id:takeda_san:20180102230012p:plain もう一方のほうも同じくノードを登録しておく。

  3. 採掘開始!
    スイッチonで採掘開始。
    掘りまくってライバルに差を付けろ。

使ったもの

今回、この記事を参考にKotlinで作っています。
個人的には、実際に作るって本を読むよりもはるかに勉強になるので、こういうシンプルで、わかりやすいプログラム例があるのはほんとありがたい。
https://hackernoon.com/learn-blockchains-by-building-one-117428612f46

ワタクシ英語が苦手なので実際はこちらの翻訳版記事を読んでおりました。
ありがたや。
動作の中身はここを見たほうが早いと思うので割愛…

qiita.com

  • Spring Boot/Spring MVC/Vue.js
    だんだん、使い慣れてきて実家のような安心感。
    REST APIでクライアントとやりとりします。
    あと参考にしたプログラムに加えて、使いやすいようにWeb上で使えるGUIを付けました。

  • Kotlin
    今回、Kotlinのお勉強も兼ねております。
    まずは、Javaっぽく書いて→Kotlinっぽく書き直せるところは直すって感じでやっておりました。
    初めからガチガチにKotlinっぽいコードとは何か!!とやってると、いつまでたっても機能ができあがらんのでこっちのほうが性にあってます。

苦労したところ

KotlinでSpring MVCのコードを書いていてハマったのが、これ。
qiita.com

同じところでまる一日悩んでいました。
あとは、おもったよりスイスイ書けて、動いてしまってびっくり。