DECLARE_DYNAMIC_MULTICAST_DELEGATEとC++

ちょっとしたお話

みんな大好き動的マルチキャストデリゲート

マルチキャスト デリゲート | Unreal Engine ドキュメント

動的デリゲート | Unreal Engine ドキュメント

個人的な主観では、C++でグイッと処理したあとにBPに結果を渡すときによく使うんですけど、C++とBP両方にイベントを発行したい時もあります。
BPであればBindノードを使うことでイベントを登録できます。
C++であれば、動的デリゲートの説明にあるようにAddDynamicを使って関数を登録します。

でも、VisualStudioのIntellisenseにはAddAddUniqueくらいしか出てきません。

なんでやろなぁ

動的デリゲートの説明をよく見たらヘルパーマクロって書いてありました。
そうです、マクロなんです。
Delegate.h#define AddDynamic(....となってました。

というわけで備忘録

週刊IM@Study Vol.4 と アイマスハッカソン2019の続き

こちらはアイドルマスター Advent Calendar 2019の10日目の記事です。


12/5のアイマスハッカソン2019にご参加いただいたみなさんありがとうございました。
そして、関東・関西のスタッフさん、お疲れ様でした!

10時から行われていた本イベントですが、18時からの成果発表・プロデューサーLT大会の様子はこちらでご確認いただけます。


アイマスハッカソン2019 in 東京&関西 成果発表・プロデューサーLT

そこでは週刊IM@Studyの寄稿内容の概要について発表しました。僕が発表してる部分はこちら↓

https://youtu.be/SMEKvULOnvc?t=4055

発表している対象についてはこちらを見てもらったほうが早いかもしれません。

UE4アイマス楽曲をさらに盛り上げてけ☆」と題しまして、UE4で楽曲のビジュアライズ的なことをしています。
こんな感じでUE4の簡単な説明をし、操作方法を学びつつ詳しく編集を説明しています。

f:id:crssnky:20191209232153p:plain

今回はUE4のエディタ機能のみを使用しているため、C++を1字も書きません。その代わりにBlueprintを引いてもらいます。世の中の評価としても、エンジニア以外にも簡単に使えるというものということで普及しており、フローチャートとだいたい同じと考えても良いと思います。

f:id:crssnky:20191209232929p:plain

もちろん、C++に慣れた方には少し煩雑かもしれませんし、C++と比べて関数呼び出しが死ぬほど遅いといったデメリットもあります。しかし、小さなプロジェクトであったり、大きなプロジェクトでも用法を正しく使えば開発イテレーションを大幅に上げることのできる素晴らしいツールです。

そんなUE4のハンズオンや他3本の記事、ミニコラム3本が詰まった100ページに及ぶ週刊IM@Study Vol.4は、第2回技術書同人誌博覧会で頒布されるので、ぜひお手にとってみてください。Vol.3の時にあった電子決済に引き続き対応している他、電子版も頒布されるので、100ページの本は...という方もぜひどうぞ!

f:id:crssnky:20191208214932p:plain

gishohaku.dev


さてお話は変わり。
Youtubeコメでもありましたが、今回はスライドソフトにUE4を使用しています。
UE4上でスライドを表示することで、シームレスにデモへ移行することができました。
スライド自体は前日に作っており、当日はそのシステムを作ってたので今回はそれについてもお話しようかと思います。

Step 0 スライドを作る

なんの変哲もないです。僕はPowerPointで作りました。

アイマスハッカソン2019in関西 - Speaker Deck

作り終えたら、各ページを画像出力してください。パワポにはそういう機能あるし、Webサービス使わなくて良き。

f:id:crssnky:20191210001222p:plain

Step 1 UE4に取り込む

テクスチャとして取り込みます。なんとなくそんな気分なので、Mipmapは作りません。 f:id:crssnky:20191210230824p:plain

Step 2 Materialを作る

テクスチャパラメータのノードを一つ持つMaterialを一つ作ります。
ハッキリ見えてほしいので、Unlitです。 f:id:crssnky:20191210231117p:plain

Step 3 スライドBPを作る

ConstructionScriptで全部仕上げます。
InstanceEditableなInt型変数からどのTextureObjectを使うかを分岐し、Step2で作ったMaterialからMaterialInstanceDynamics(MID)を作ってそこにTextureObjectを投入します。

f:id:crssnky:20191210231502p:plain

f:id:crssnky:20191210231534p:plain

ConstructionScriptで済ますことで、Levelに配置した後でもぐりぐり~って変えられます。

Step 4 スライドLevelを作る

逆に言えばConstructionScriptで作っちゃったので、Levelが開始してしまったら変更ができません。せっかくなので、LevelStreamingを試してみたいし、良い感じにしましょう。
まず、テキトーにスライドBPが一つだけあるレベルを量産します。各BPは順番に四角の各辺をなぞるように配置します。

  • Slide1はx,y,z=1000,0,0・Pitch,Yaw,Roll=0, 0, 0
  • Slide2はx,y,z=0,1000,0・Pitch,Yaw,Roll=0, 90, 0
  • Slide3はx,y,z=-1000,0,0・Pitch,Yaw,Roll=0, 180, 0
  • Slide4はx,y,z=0,-1000,0・Pitch,Yaw,Roll=0, 270, 0

みたいな感じ

f:id:crssnky:20191210233303p:plain

スライドの数だけ...スライドの数だけ....多い....

f:id:crssnky:20191210233133p:plain

Step 5 LevelStreamingを整える

"HackathonPersistant"的な名前のパーシスタントレベルを作り、Levelsウィンドウで下にぶら下げます。
今回は、スライド以外にもデモ用のレベル(Test)もぶら下げています。

f:id:crssnky:20191210234320p:plain

Step 6 LevelBPを書く

次へキー・戻るキーを設定し、それのイベントに紐づけて次のスライドを持つレベルをその場で読み込むBPを記述します。Timelineノードを使えば、良い感じにカメラを回すことも出来ます。

f:id:crssnky:20191210234605p:plain

f:id:crssnky:20191210234705p:plain

Step 7 試す

LevelStreamingによって、必要なスライドのみが違和感なく読み込まれてることが確認できます。とってもメモリに優しいですね!!


こんな感じでアイマスハッカソン2019ではスライドを流していました。これを使い回せば、UE4で作ったものを簡単に見せられますね!

お詫び

WebRemoteControlの発表を書きたかったのですが、本日公開されたUE4.24でも難しいみたいです...

UE4とRTTI ~MSVC(Windows) V.S. clang(Mac, Linux)~

RTTIとMSVC, clangの環境の違いには気をつけろの情報共有である。

背景

im@sparqlをUE4で触りたいなと思ったら、JSONが使えるようにしたかった。
そこで、ちょうどよいものを見つけたので導入した。

usagi.hatenablog.jp

こいつ(cereal)は最高だ、JSONを構造体のように扱える。
いや、実際に構造体を定義して、そこにJSONを流し込んでるから当たり前だ。

これに関しては、技術書典で頒布した週刊IM@Studyの2019/04号に記載している。
当然リポジトリもある。

github.com

問題

昨年末のpaypay祭りの時に思い切って、ノートPCをWin機からMac機に切り替えた。
当然開発環境は変わり、Xcodeなのでclangとなる。
これが問題。
おうちのデスクトップPCはWin機なため、VS2019のMSVCで作業している。
こいつで動作確認をしているのだが、clangではどうもビルドが通らない。

具体的には、RTTI関連でエラーが出る。
MSVCはRTTIはデフォルトでONなので気にすることは無かったが、cerealではtypeinfoを用いる。
clangではデフォルトでRTTIはOFFなので、エラー文で叱られてしまった。
コンパイラに従いBuild.csでbUseRTTI=true;を指定してビルドすると見知らぬリンカエラーに遭遇した。
似た人↓
https://answers.unrealengine.com/questions/745636/undefined-symbols-for-architecture-arm64-1.html

理由

理由↓
https://answers.unrealengine.com/questions/871773/view.html

意訳すると

  • LinuxではRTTIと非RTTIを混ぜちゃダメ
  • モジュールごとにRTTIの有無は分けられるから、必要な部分に切り出して
  • その時に、Engineのクラスを混ぜちゃダメ
  • それを"ブリッジ"するラッパーを書くのが良い
  • "OpenEXRWrapper"プラグインを参考にしてね

質問者も「Windowsでは動くから、変に気を取られたよ」(意訳)と、自分と同じ心境を語ってる。

現在

モジュール分割をしている。
でも上手くいかない。
C++なんもわからん
何がわからないのか分からない

RTTIとMSVC, clangの環境の違いには気をつけろの情報共有でした。

IM@Study合同本@C96 4日目(月曜日)南地区"リ"01a

f:id:crssnky:20190810021237p:plain
imasbook03
なんとぉ!
週刊IM@Studyの3冊目が今夏のコミケで頒布されます。
場所はC96 4日目(月曜日)南地区"リ"01aです。
https://webcatalog-free.circle.ms/Circle/14514591

表紙絵はお馴染みになってきた文月きょうさんにお描きいただきました。
前回分はこのブログで宣伝していませんが、未来ちゃんが持っています!再帰!!(再帰ではない)

表紙構成は、Uske_Sさんです。
本業はPかつ副業で印刷系ITエンジニアらしく、レイアウトが華やかになりました!
強力な協力者です。

中身

  1. im@sparql応用 〜HTMLでさっと表示編〜
    著者:croMisa
    概要:im@sparqlを利用する、簡単なAjaxのWebページを作るハンズオンです。
  2. スコアを用いたライブの予習セットリスト自動生成の試み
    THE IDOLM@STER CINDERELLA GIRLS 7thLIVE編〜
    著者:遠山 賢寿
    概要:創刊号で紹介されたデレマスのセットリスト自動生成、これを7thライブに対して動かし、セットリストを予想していきます。
  3. pLaTeXを用いた小説系同人誌作成入門
    著者:MH35
    概要:小説などの文章がメインとなる同人誌において、pLaTeXで作成する時の方法や入稿の注意点が紹介されます。
  4. 小鳥さんと一緒に100%Kotlinのサイト製作〜Backend編〜
    著者:にしこりさぶろ〜
    概要:Kotolin製Webアプリフレームワーク"Ktor"を、Kotlin初心者の小鳥さんと学ぶ前半とルーティングやJSONシリアライズ、GETクエリの取得を解説する後半で紹介していきます。
  5. 青羽美咲が業務効率化を目指してAlexaスキルを作る話
    著者:きりだるま
    概要:美咲ちゃんと一緒にAlexaのスキルを学び、Pの日頃のプロデュース業務(ミリシタ)を効率化するまでを描くハンズオン的ストーリです。
  6. プレイリスト自動生成でアイマスをより楽しむ
    著者:Wakuwaku
    概要:アイマス楽曲が増えてきても、いつも聴く楽曲は固定化してしまう悩みを解決するべく、NAS内に日替わりでプレイリストを自動生成する方法を紹介します。

特定のRDFの変更に合わせて、それを基にクエリを実行させて別のRDFを作るCircleCI

「特定のRDFの変更に合わせて、それを基にクエリを実行させて別のRDFを作るCircleCI」

タイトルの通り
実際のPRはこちら
まぁ、訳あって(後述)マージせずに閉じましたが。

背景

im@sparqlでは自動生成系のRDFがある。

この2つは、Clothes.rdfUnit.rdfの逆方向の述語のトリプルが定義されている。
つまり、

  • Unit.rdf
    エターナルハーモニー --メンバー--> 千早
  • Unit_memberOf.rdf
    千早 --所属--> エターナルハーモニー

みたいな感じ。

なので、Clothes.rdfUnit.rdfが編集されたらそちらも編集する必要がある。
とはいえ編集するのは面倒なので、Node.jsを用意して適度に回している。

github.com

(一応公開してるが完全に自分専用って感じのゴミコード.....)

問題点

XML構文解析はど素人だし興味もないので、Node.jsでやっているのはキャラごとにまとめたSPARQLクエリをGETで叩いて、XMLっぽく排出している。
そう、SPARQLを叩いている
ということは、一旦変更をSPARQL鯖に反映しなくてはならない。
つまり作業としては,

  1. Unit.rdf || Clothes.rdfを編集してPullReq出す
  2. GitHubでマージする
  3. SPARQL鯖の更新
  4. 自動生成スクリプトを走らせる
  5. PullReqを出す
  6. GitHubでマージする
  7. SPARQL鯖の更新

というわけ。慣れればそんなに苦でもない
とはいえ傍から見ればアホ丸出しなので、苦手意識のあるCircleCI克服も兼ねて自動化しました。

結果

CircleCIでやっていることの流れ

  1. DockerImagestain/jenaでCircleCI上でSPARQLを動かせる環境を作り、自動生成で使っているのと同じクエリを撃つ
  2. 結果をJSONファイルに保存する
  3. DockerImageをcircleci/nodeに切り替える
  4. 結果を保存したJSONファイルを読み込み、自動生成で使っているのと同じ処理でXMLを作る
  5. node.jsのconsole.logはUTF-16っぽいので、エンコードを変換する
  6. GitHubbotアカウントでPullReqに対して追加コミットをする

botでの追加コミットはこちらを参考にした

www.ncaq.net

実際の動作

github.com

試行錯誤の末の結果なので、ゴミみたいなコミットは無視して欲しい

おわりに

まぁ結局、botでやる方式だとPullReqする人全員がbotのアクセスを許可しないといけなかったり、CIの発火のタイミング調整がブランチかタグしかなくてコミット時に統一しないといけなかったりと他の編集者の負担を増やしそうだったのでマージせず、別の方法をすることにした。 某所での助言より、自動生成物かつ、逆方向の述語という性質上GitHubで変更を記録するほどでも無いので、Jenkinsでどうにかしようとしている。
それはまたの機会に。

RDFまたはSPARQLの問題点・疑問に関するポエム

背景

先日のアイマスハッカソンで某氏から、im@sparqlに関するある要望を受けた

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

ハッカソン当時のアイドルのインスタンスには、アイドル名がschema:nameにxml:lang="ja"として格納されていた。(今は英語名xml:lang="en"が追加されている)

<schema:name xml:lang="ja">如月千早</schema:name>

この言語タグを付けたプロパティはよくある文字列型(xsd:String)ではなく、言語タグ付き文字列型(rdf:langString)として認識される。(datatype()関数使えば分かるよ)
つまり、

select * 
where{
  ?s ?p "如月千早".
}

では検索できない。("如月千早"はxsd:Stringなため)
検索するためには、

select * 
where{
  ?s ?p "如月千早"@ja.
}

といった具合に、言語を指定してあげる必要がある。
その際、

「この@jaって、"如月千早"が日本語タグで書かれてると知ってないと書けないよね」

と言う話になった。たしかに、実は"如月千早"が中国語として登録されていれば、日本語だと思って@jaを付ける人は「検索にヒットしねぇ...」と呟くことになる。

そこで冒頭の

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

に繋がる。

select * 
where{
  ?s ?p "如月千早"@ANY_LANGUAGE.
}

のような(上記の書き方はできない)感じで検索したいということだ。

ちなみに、

select * 
where{
  ?s ?p ?o.
  filter(str(?o)="如月千早")
}

といった感じで、str()関数でrdf:langStringをxsd:stringに型変換してフィルタリングすると実現できる。
スマートじゃないよねって結論だけど。

疑問

SPARQL触ったことある方は、上の背景を読んだだけで「言語タグ付き文字型リテラルで検索すれば良いじゃん」と思うでしょう。
SPARQLはリテラル^^を付けて後ろに型を書くと、その型リテラルになる。

"hoge"^^xsd:string
"--04-27"^^xsd:gMonthDay
"162"^^xsd:int
"162"^^xsd:float

つまり、

select * 
where{
  ?s ?p "如月千早"^^rdf:langString.
}

しかし、なぜか検索できない

調整

<schema:name xml:lang="ja">如月千早</schema:name>
↓
<schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name>

といった具合に、RDF側を調整してみることにした。言語タグ付き文字型を明示的に宣言した。
すると、

select * 
where{
  ?s ?p "如月千早"^^rdf:langString.
}

で見事、検索にヒットさせることができた。
しかし、

select * 
where{
  ?s ?p "如月千早"@ja.
}

で検索することができなくなってしまった。言語タグの情報が死んでしまった。

何故じゃ

現状(2019/4/30)

冒頭で書いたとおり、現在は

<schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name>
<schema:name xml:lang="en" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">Kisaragi Chihaya</schema:name>

のように、英語名も並んでいる。
言語タグ情報が死んでいるので、完全に並列な情報として並んでしまってる。

たぶんrdf:langStringを消すと思うけど、結局

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

はどうすりゃいいんでしょうね。

追記

なんか分かる所にメモりたかったもの

「近未来アウトサイダー」のカタカナ語

こちらはアイドルマスターアドベントカレンダー25日目の記事です。前日は、ろころこさんのクリスマスイブにロコについて語る(脈絡がない)です。


12/25にもなればおそらく、だいたいのPはミリシタをプレイしていなくてもTCという単語を見たことあるのではないのでしょうか?

TCとは

TC : THE@TER CHALLENGE

「THE@TER CHALLENGE!!」とは?
去年実施されたシアターブースト企画の第2弾!
ミリシタのゲームをプレイすることで手に入る投票券をつかって、 発表されたテーマと配役にあったキャストをプロデューサーの皆さんが投票していただくキャスティング投票企画です!

アイマスブログより
隣のお城の事務所の総選挙やパッション爆裂な事務所の大作戦のように、私たちの投票によってCDの内容を決める765MillionTheaterの一大イベントとなっています。上記の通り、テーマと配役にあったキャストを投票で決めます。

で、

過去2回(TA, TB)では、765TheaterAllstarsが投票の対象となっていたのですが、今回から765ASの13人も加えて過去最多の52人で3作×5役=15枠を争う形となりました。
私たち千早Pを含む、765AS勢のPとしては待望のイベントとなりました。LTF、MS、MGシリーズとミリオンへの楽曲参加がここ数年無かったので大きなチャンスです。逃したくないですね。

投票が始まって1週間近く経ちましたが、毎日のように企画や流行語による得票数ドラマが繰り広げられています。それはもちろん765ASアイドルも例外ではなく、765ASのPの積もり溜まった何かが破裂するように配役争いを続けています。
昨日の12/24は萩原雪歩の誕生日でもあり、日替わりとともに数多の表を獲得して、キャラ別総得票数1位に大差で躍り出ました。

千早P 陣営

千早P陣営は、本人には内緒でとてもアレなタグを生み出してしまいました。それは...
#ダスくっ千早
TC発表当日にはすでにタグとして流れていたことから、多くの千早Pが賛同、拡散してスタートダッシュを狙ったのでしょう。
僕はTBで風花さんに水着を着せるために奮闘したので、またお前は仕事のために担当を悲しませる営業をさせてるのか...という状態ですが、歌の仕事のためにクチバシ付けて頑張ってください。

本題

ぶっちゃっけ「近未来アウトサイダー」って何?カタカナゴワカラナイってなってしまっているので自分の勉強も兼ねて、千早P陣営の現在の矛先である「近未来アウトサイダー」をお勉強したいと思います。
f:id:crssnky:20181218232757j:plain

アウトサイダー

インサイダーの方は耳馴染みがあると思います。法律的な意味で。
英語で書けば"outsider"。いわゆる部外者・よそ者の意ですが、常識や社会という枠の外の人という意味もあり、異端者という含みのある捉え方をすることもできます。

ダスク

心と鍵が重要なゲームのエネミーしか思いつきませんでしたが、"dusk"は夕闇や夕暮れ時自体を指します。
世界が闇に包まれないようにギリギリで保つ、正義側の登場人物でしょうか。

バスターブレイド

狩猟生活のゲームではお馴染みの武器名ですね。"Buster Blade"はそのままだと破壊する刀と訳します。
"Buster"は物理的な破壊が主な意味ですが、犯罪撲滅などの撲滅させる人を指したり、ストレス解消法の"解消法"を指す時に使えたりと、悪いものを退治する意味も込められていそうです。

アウトレイジ

某映画シリーズの印象通りでしょうか。"outrage"は激しい怒りや暴力、暴動を指します。"rage"自体も怒りなどの激しい感情を指し、それらが外に出た結果=行動を指します。
アウトレイジ軍、本物の軍であればクーデター、義勇軍だとしても暴動を起こす危ない存在だと言えますね。

マリリス2

"Amaryllis"はヒガンバナ科にあるヒッペアストルム属の植物の総称みたいです。主に園芸用途で生産され、球根を持ち、(目"モク"から違うが)百合に似たラッパ型の花が特徴です。
アウトレイジ軍に捕らわれている、不思議な力を持つ少女ということもあり、ヒロイン枠となっています。

ベルベット

ローマ帝国かどこかの昔の強い指導者の名前かと思えば、織物の名前でした。"velvet"はパイル織物の一種です。このパイル織物というのは、下地から片面か両面に繊維が飛び出ている(←パイル)織り方をするものです。身近なものはタオル地がそれです。ベルベットはタオル地と違い、パイルをカットしてフシャーとするみたいですがイメージと違い、絹やレーヨンがベルベットに属します。絹などの手触りが良いのも、タオル地のようにフワフワ感を出しつつ引き締まった見た目に仕上げる高度な技術があるからなんでしょうね。
紹介文では、

アウトレイジ軍の特攻隊長。圧倒的な強さを誇る。

とありますが、繊細な生地を冠するキャラクターでもあるので、力任せに戦場を制圧するパワープレイヤーではなくて、高貴な頭脳派プレイヤーなのかもしれませんね。

ファイナルデイ

アウトレイジ軍を率い、混沌とした世界を手中に収めようとする(たぶん)悪いやつ。
"荒廃"や"混沌"はおそらくアウトレイジ軍、もといファイナルデイの企みによるものでしょう。
サイゴの日を意味しますが、果たして"最後"なのか"最期"なのか...どのような目的で世界を手に入れようとしているのか気になりますね。

以上です

あの1枚のスライドの単語たちから読み取れそうなものはこれくらいだと思います。
ミリシタの開発プロデューサーであるわかちこPでさえ、"スタッフ陣が分からない"と話した「近未来アウトサイダー」、キャスティングがお話にどれほどの影響を与えるのかは、考えるまでもないですね。

追伸

アイマスハッカソン2018でのim@sparqlのご利用ありがとうございました。