子供用プリントのエクセルを作った

子供の自習時間とかでドリル的なものが必要だったりするのだけども、
自分で作れるじゃんって感じのものだったので作った。

足し算・引き算のひっ算のエクセル。
VBAが書かれてて、
ボタンで問題が毎回リセットされる。

答えを表示したりする機能をつけても良いかと思ったけど、
けっきょく難しい問題ではないので保留。

引き算2桁.xlsm - Google ドライブ

足し算2桁答えが100以下.xlsm - Google ドライブ

Excel2016 (Office365) で作成したもので、
他の環境でどれくらい動くかは未検証。
一応、シェアする形で残しておく。

ADBTools

Unity のプロジェクトフォルダ以下にあるapkをリストアップし、
インストール/アンインストールを容易にできるようにしたエディタ拡張を作った。
github.com

昔、Processを呼び出してインストールするようなものは作ったけど
AndroidでビルドはもういいRunしたいってとき - kurihara-nの日記
もう少し整えて、
apkをリストアップして、
それぞれにインストール/アンインストール操作ができるようにした。

Windowsでしか確認してないのは引き続き。

Zenjectとマルチシーン

Zenjectを採用したプロジェクトにおいて、
マルチシーンへ対応する場合にはいくつかの方法があります。

Zenjectのベーシックな使い方は、
シーンにSceneContextを配置して、
そのオブジェクトにInstallerを配置していくことで、
シーンごとの構成を用意していくというものです。

そのままだとUnityでシーンの変更をしたときに
関連性が持てず、それぞれ参照できなくなるので、
前のシーンでBindしたオブジェクトを、
次のシーンで参照するということができません。

方法としては、

  1. ProjectContext というグローバルなコンテキストを用意する
  2. Sceneの親子つけを行いマルチシーン構成にする
  3. DecoratorContext

Project Context

https://github.com/modesttree/Zenject#global-bindings-using-project-context

Projectビューの右クリック -> Create -> Zenject -> Project context
でプレハブを作成する。
場所はResourcesフォルダ以下である必要がある。

これをいったんHierarchyに配置し編集してApplyすることで構成していく。
インスペクタの情報としてはSceneContextと大差なく、
MonoInstallerをアタッチしたり、ScriptableObjectInstallerをアタッチしたりできる。

編集がすんだらApplyをしてシーンからは削除しておくのがポイント。
このプレハブをもとにしたオブジェクトは、シーンに配置しておいて動作するのではなく、
いずれかのSceneContextがシーンオブジェクトに配置されていると、
実行時にDontDestroyOnLoadなオブジェクトとしてシーンに生成される。

Scene Parenting

グローバルに存在するProjectContextはプロジェクト全体を範囲としてしまうので、
ときに問題となる。
指定のシーンとシーンを意図したように関連づける手段として
Contract Name を使用したScene Parentingが存在する。
https://github.com/modesttree/Zenject#scene-parenting-using-contract-names
この場合、シーン同士は並列ではなく主従・親子としての関係を持つ。
親となるシーンのScene Contextのインスペクタ、
Contract Namesというフィールドがあるので、ここに親としての名前を指定する。
(このフィールドは配列になっており複数していできる。
子からみた親はひとつだが、親シーンは全く別の子の親としても、みなされることができる)
子シーンのほうは、インスペクタのParent Contract Nameに、
親の名前を指定する。
Contract Nameはシーン名とは関係ない名前で構わない。

まず親シーンを開き、Hierarchyに子シーンをドロップして、複数のシーンがある状態にし、
Ctrl + Shift + V でValidationが通ることを確認してみるとよい。
この状態は、実際には親シーンからAdditiveで子シーンを読み込んだ状態に等しい。
ちなみに子シーンが先に読まれている状況でValidationを行うとエラーとなる。

DecoratorContext

もうひとつのマルチシーン対応としてDecoratorContextを配置したシーンを用意するというもの。
https://github.com/modesttree/Zenject#scene-decorators
まずDecoratorContextを配置するシーンを用意し、
SceneContextの代わりにDecoratorContextを配置。
Decorated ContractにContract nameとする文字列を指定。
もう一つのシーンを用意して、
こちらには通常のSceneContextを配置。
Contract Namesに先ほどのDecorated nameのと同じ文字列を指定。
2つのシーンを読み込んだ状態で、
DecoratorContextで行ったバインディングが、
あとから読み込んだシーンにもInjectできる。



個人的にはParenting での運用が多い。
エントリシーンを用意し、それを親とした状態で、
モードごとに子シーンを読みかえる構成。
親となるシーン、子になるシーンにそれぞれContractNamesを適切に設定する。
ここら辺は、普段のプロジェクト構成に合うもので良いのではないかな。

バイオハザード7 resident evil

CERO Dバージョン

プレイしていたのは先月だけども。

とても素晴らしいゲームだったが、
このゲームの感想として「面白い」が適切なのかというと、
そうではないと思う。
もっといろいろな感情を刺激してくる。

最初は恐怖であり、次に怒りへと感情が誘導される。
どちらかと言うとネガティブな感情だけど、
それによってゲーム作品に引き込まれていく。

ゲームには色々な感情を受け入れられる良さがある。

PSVRを手に入れたらVRでも試してみたい。
ただ今までのシリーズの流れをストーリー・世界観的にあまり引き継いでないので、
これまでのシリーズのファンとしては、
そっちも楽しみにしてます。
ジェイクが主人公のシリーズをまたやってみたい。

人工知能の作り方 ――「おもしろい」ゲームAIはいかにして動くのか

人工知能の作り方 ――「おもしろい」ゲームAIはいかにして動くのか

人工知能の作り方 ――「おもしろい」ゲームAIはいかにして動くのか

kindle版にて。

ゲームAI研究の第一人者で、CEDEC等でも多く講演をされている三宅さんの本。
現在のゲームAIの分野を広く網羅されている。
実装の細かいところをコードも含めて見たい・知りたいと思っているプログラマからすると
やや概念によっているものになるかもしれない。
ただ、資料へのリンクも多く含まれているので
もっとより知りたい人でも大丈夫。
もし、もっと実装についての興味があるのであれば
Game AI proを読んでみるといいだろう。(英語だが)

ゲームAIについて丁寧に、周辺から近づいていく構成になっている。
コアの話の箇所でも、
具体的なコードまでは出てこない。
出てこないが、
技術的な仕様はわかるような説明はされている。

ゲームAIの本というと、
基本的にはプログラマ向けという印象もあるけれども、
ゲームデザイナーや、アーティストが読んでもよいと思う。
というかプログラマ以外が読むほうが良いのかもしれない。
そこまで実際のコーディングなど出てこないので、
そういう意味でも読んでほしい。

三宅さんのCEDECの講演で聞いた話も含まれていたので、
そういった三宅さんのリサーチを集めた本ともいえるだろう。
参考資料へのリンクも充実している。
紙の本だとどうだかわからないが(読んだのはkindle版)
kindleだとリンクから直接アクセスできるので便利。
電子書籍向けに合わせて作られているのはありがたい。

特に8章の集団の知能を表現するテクニックなどは興味のある章で、すばらしいと思う。
8章 集団の知能を表現するテクニック ~群衆AI の技術

ゲームのAIについて話す場合、
まず単体のAIに関する話題が優先されるが、
実際にある規模のゲームAIを作っていくと、
マルチエージェント間の連携や、
チームとしての制御が必要になり、
また 負荷対策が実際の問題として生じてくる。
この章はゲームの開発に基づいた資料として機能するし、参考になると思う。
ここで触れられているということにより、
さらに踏み込んだ議論や話しが、
マルチエージェント、群集の表現において
出来ていけると良いなと思う。

ゲーム分野ゆえの問題でもあり、
そのことに触れられているが、(一部引用)

このような組織のシミュレーションが通常、ゲーム産業でしか必要なく、ゲーム産業自身が先導して研究を推進する必要があるからです。アカデミックでは「 マルチエージェント」と呼ばれる分野ですが、この分野自体が広く、 必ずしもキャラクターの協調シミュレーションだけにフォーカスしているわけではないので、こういった技術を吸収しながらも今後発展が必要とされる分野です。

この章の内容だけでも、
ここをさらにもっと広げて、もっと深めていけるともっと表現の追求ができそう。
まだここはやれることがあるところ。
この章を書いていただいたことを感謝したい。

あと、GDやプログラマ以外の方も
ゲームAIへの理解深めておいたほうがよいのかについての補足をもう少し書いておく。
イマイチに観えるAIの、なんでAIがビミョウに思えるのかの原因は
実装が良くないことによるよりも、
ゲームデザインからくることがしばしばある。
開発していてというよりも、ゲームプレイをしていて感じることがある。

例えば、キャンディクラッシュゼリー、
悪い例で挙げて申し訳ないけど、
充分にヒットしている、とても魅力のあるゲームだという前提で。

このパズルゲームシリーズの中の一つの作品は、
敵のAIと対戦を行うステージが出てくる。
いくつか対戦内容はあり、例えば相手より先に自陣のゼリーの色を全体に広げよう、
などというものである。
ポイントとして、対戦以外の面と共通するルールとして、
手数の制限があり、
これはプレイヤー側にのみ課される制限となっているのである。
まず、この点でAI戦で公平ではない印象をプレイヤーに与えてしまう。
また4つ以上のピースを消したときはボーナスとしてスペシャルピースが生成されたうえ、
引き続きターンが継続するというルールになっている。
理屈でいえばAI側は、スペシャルピースを作れる盤面が続く限り、手数の制限がないため、
デメリットもなくターンを続けることができてしまう。
その対策としておそらく組み込まれている挙動なのだと思うが、
スペシャルピースを2つほど生成したあとは、
AIはなるべくただの3つピース消しを選択し、
ターンをプレイヤーに返す行動を選択するようだ。
スペシャルピースを作ってターンを継続出来る場合だったとしても、それに関わらず。

これはプレイヤーからみたら、AIが不可解な手をとったバカなAIと映るかもしれないし、
人によってはワザと手加減されたと感じるかもしれない。
またそれ以前にアンフェアなルールにモヤモヤしているだろう。
これはゲームAIとゲームデザインがうまく機能してない例だと思う。
もっとフェアなルールを設定出来さえすれば良かったと思う。

他のゲームでも、
いろいろな要素が高いレベルで実装されているにも関わらず、
AIが不可解な行動をとるゲームというのはどうしてもある。
問題の解決方法をどこに着地させて解決していくのかは、それぞれの状況による。
そのため各担当パートの垣根を越えてAIへの理解というのは持っておいて損はないはず。
ゲームの絶対的な仕様による制限でAIがおばかに見えてしまうとしたら、
AIプログラマが実装をどんなに改善しても解消は難しいということはある。
そういったさいにゲームデザイナーやほかのスタッフとの対話で
ベストな解決を見つけていくことになるので、
お互いに共有する知識があることは役に立つと思う。

The Last of Us Remastered

年明けにPlaystationStoreでセールになっていて2500円くらいで買えたので
The Last of Us を買った。

The Last of Us Remastered 【CEROレーティング「Z」】 - PS4

The Last of Us Remastered 【CEROレーティング「Z」】 - PS4


進行型のゲームとして、
様々な面でクオリティが高い。

グラフィック、
アニメーション、
カットシーン、
音楽、
吹き替えだったがセリフの雰囲気まで含めて
なにからなにまで
素晴らしいので、
こんなゲームの開発もあるんだなーと。

バッテリーから伸びてる電源ケーブルなんかも
グニョングニョンしてる。
そんなところも粗さがない。

ストーリーも、プロローグでパンデミックが起こって
主人公の一人、ジョエルに悲劇が起こって、
これが可哀そうでね・・

そのあと、もう一人の主人公の少女エリーと行動をともにするようになって、
あー、まあ、どうせ先々こういう展開になるのかなーなんて予測しつつ、
最後まで、あまりだれずに進められた。
(そして、それほど予測したような安易な展開はそれほど描かれなかった)

バトルは、時々強制的なシューティングパートがあってストレスを感じることもあったけど、(下手だから)
ほとんどのケースは、
上手くステルスしていくスタイルも許容されているので楽しい。
特に弓矢は他の敵に気づかれずに使える飛び道具で、
使った矢も折れなければ回収できるので、
上手いプレイをしているという感覚があって良い。

ただ、ストーリー的に、
終盤からラストまでで、
うーん?っていう展開があり。

エリーを助ける助けるためにジョエルが人を殺しまくるという。
いや、それまでも強盗の類いは散々殺してきたんだけど、
一応人類のために活動してる組織の人たちだし、
ほぼ無防備の人なんかも殺しちゃって、
オイオイ…っていう。
ま、描写としては、そこに至るまでにも、
エリーに対する執着が変化していくのは描かれていたんだけど。
うーん、なんか最後のほうは感情移入としては微妙だったかなーっていう。
嫌な気分になって、さしてハッピーエンドでもないし、
もうちょい別の終わらせかた無かったのかねーなんて、
思ってしまった。

が、そんなことをぼんやり考えていたのだが。
1、2日ぼんやり考えていて、
ふと、あれって敢えてそうなんじゃないかって気がしてきた。
いや、敢えてなのは、敢えてなんだろうけど、
ストーリーのために、ああいうジョエルの行動になっていたのではなくて、
ゲームの、プレイヤーの気持ちを、
ジョエルから引き離すのが、
意図的だったのではなかろうか。

ジョエルとプレイヤーのリンクをブチ切って、
どこへプレイヤーを投影させるのか、
気持ちのリンク先を、
最後にエリーに持っていったのでは・・。

ラストシーンで、エリーはジョエルの話を疑って、
そしておそらく嘘を見破って、
言葉にはしないが、失望したようなそんな様子を見せる。
それと、ジョエルないわーっていう、
プレイヤー側の気持ちとが重なることを意図してるのでは。

もうちょい言うと、
ラストシーンの直前、
最後のプレイアブルシーンで、2人で山道を歩くのだけど、
このときの操作対象がエリーになっているのだよね。
それまで、2人が分かれている場面でエリーを操作することはあったけど、
2人一緒のときは、
ジョエルを操作することになっていた。
(おかげでこのシーンが始まったとき、あれ?ってなった)
これも意図的に設計されたことなのではないかな。

これ、ストーリーの流れと、
プレイ対象のスイッチというシステムとしての効果を、
重ね合わせるという、高度な、ゲームでしかできないことを表現しようと
トライしているのじゃないだろうか。
すごい。

うーん、どうだろ。
ちょっと好意的に深読みしているかもしれない。
2も作ってるようだし。(ジョエルも続投なようだし)

Zenjectに含まれてるサンプル その1

kurihara-n.hatenablog.com

Zenjectについて前に書いたが、
アセットのパッケージ自体にサンプルが含まれているので、
それを見ていこうと思う。

サンプルは2種類あり、アセットをインポートしたままの状態であれば
Assets/Zenject/OptionalExtras
の下に
SampleGame1 (Beginner)
SampleGame2 (Advanced)
というフォルダがそれぞれある。

まず、SampleGame1(Beginner)から見ていく。
フォルダの中に、Asteroidsというシーンがあるので
このシーンを開く。

Runするとゲームが動きタイトル画面でクリックでゲームが始まる。
マウスで自機を動かし隕石を避けるゲーム。
f:id:kurihara-n:20170104223309p:plain

シーン構成

シーンの構成を見ていくと、
SceneContextがあり、ここにGameInstallerというInstallerスクリプトがあり、
Installersのリストに追加されている。
また、このSceneContextはScriptableObjectInstallerとして、
ゲームの設定が定義されているGameSettingsInstallerも設定してある。

Guiというオブジェクトからは、
GuiHandlerというコンポーネントがZenjectBindingsでBindされている。

Sceneというオブジェクトは、
背景と、ライト、カメラを持っている。特に触れることはない。

Shipというオブジェクトからは、
ShipというコンポーネントがBindされている。

Scriptable Object Installer

まず、
SceneContextのScriptable Object Installersに設定されているGameSettingsInstallerは、
ゲームの各種設定や、プレハブを持っているScriptableObjectになっている。
GameSettingsInstaller.csを見てみると
InstallBindings()にてそれぞれのインスタンスをBindingしている。
Container.BindInstance(****)というとこ。
これにより他の参照をしたいクラスで使うことができる。

Scriptable Object Installerのドキュメント
https://github.com/modesttree/Zenject#scriptableobject-installer

MonoInstaller

Bindingを行っているMonoInstallerであるGameInstaller.csを見ていく。
最初に、

        [Inject]
        Settings _settings = null;

という箇所があるが、
これがさっきのScriptableObjectInstallerでBindingした設定のインスタンスをとれるようにしているところ。
GameInstallerのSettingsはプレハブを持っている。

プレハブはBindFactoryでファクトリをBnidしており、よそでインスタンスを生成できるようにしている。

InstallAsteroids

            Container.Bind<ITickable>().To<AsteroidManager>().AsSingle();
            Container.Bind<IFixedTickable>().To<AsteroidManager>().AsSingle();
            Container.Bind<AsteroidManager>().AsSingle();

はAsteroidManagerをBindしている。
コメントにもあるが、

Container.BindAllInterfacesAndSelf<AsteroidManager>().To<AsteroidManager>();

と書くのとも一緒になる。

BindFactoryはScriptableObjectからプレハブを受けて、
Asteroidを生成できるようにわたしている。
WithGameObjectNameをつけると生成されるオブジェクトの名前を設定できる。
UnderTransformGroupは設定された名前のオブジェクトの子に設定していく。

InstallShip

最初に自機がクラッシュした時のSignalをバインドしている。

            Container.BindSignal<Signals.ShipCrashed>();

Signalはイベントと同じように使える。
https://github.com/modesttree/Zenject/blob/master/Documentation/CommandsAndSignals.md#signals

ちなみに、SignalのListenを残している状態でSignal自体のDisposeが走ると
Assertになってしまう。
Assertが書いてあるSignal1.csからSignal6.csというファイルに、
要らないならコメントアウトしてね、って書いてあるので気になるならコメントアウトしよう。

他にはStateFactoryと、各ステートのfactoryがBindFactoryされてる。
ステートは
ShipStateWaitingToStart
ShipStateDead
ShipStateMoving
Stateを使っているのはShipオブジェクトだが、
これはシーンに配置されていて、ZenjectBindingによってBindingされている。

InstallMisc

GameControllerをはじめ、
もろもろのクラスのバインディングを行っている。
爆発などのプレハブもBindFactoryしていて、
Ship死亡時のステートからcreateが呼ばれている。

InitExecutionOrder

処理順の制御を行っている。
これはUnityのExecution Orderと同じように使えるものと思っておけばいい。
https://github.com/modesttree/Zenject#update--initialization-order