2012年9月27日木曜日

映画 コクリコ坂から

 何故か最初の映画論評がコクリコ坂である。ブログを初めてから「カウボーイ&エイリアン」と「猿の惑星 ジェネシス」も観ていたのだが。ともかく最初なのでちょっと前置きを。

 断っておくと、論評するような柄ではない。最近一番のお気に入りが「世界侵略 ロサンゼルス決戦」なのだから言わずもがなだ。
 方針としては、多少覚えておきたい映画、もしくは最初の感想を覚えておきたい映画について取り上げる。必要ならばネタバレも辞さない。画像は作法が分からないし、現状の閲覧数では不要だろう。
 多くの映画には原作があるが、当然こちらまでフォローはしない。あくまで映画、そして映画脚本に対する感想というスタンスで行くことにしよう。

 では「コクリコ坂から」について感想をまとめてしまう。最近のジブリ映画は、手放しに誉めた評判は聞かないという印象がある。したがって、結構身構えて見るわけだが、今回気になったのは2点。

 まず1点目から、舞台、背景の雰囲気が結構良かった。斜面に広がる住宅地から、曲がった坂道で港まで繋がっており、海岸線と平行する通りに商店が並んでいる。橙色の電灯を灯して賑わう商店街の雰囲気が良い。またそれとは対照的に、朝霧に霞む住宅地も涼やかで良い。
 確かに千と千尋などと比べると、いくらか絵が味気ないようだが、いい塩梅といったところなのではと感じた。

ここからネタバレ含む

 2点目、なにやら全てがハッピーエンドになっていないだろうか。主人公メルと風間は兄妹だと思ったら、兄妹ではなく、カルチェラタンの取り壊しは、これもまた土壇場でひっくり返る。
 せめてカルチェラタンは取り壊されて欲しかった。頑張ったけどどうにもなからなかった、というようなストーリーを一個踏まえておけば、兄妹じゃなくて良かったねと、共感することもできるのだ。ストーリーも引き締まるのではないだろうか、大団円から大団円へと、まさしく駆け足で移動するというのは如何なものだろう。

 タグボートから商船のタラップに乗り移るシーン、シータとパズーかよ、という描写だったが、少し重点を置いているのだろうか。たしかに普通の高校生だと考えれば結構なアクションシーンだ。こんな事までして聞きに行かなくてもいいよとちょっと迷っても良かったのではないか。もっとも、ハッピーエンドラッシュで気が大きくなっているメルの思考には、そんな逡巡が入り込む余地は無さそうである。

 まとまりが無いが、こんなところで。ジブリ作品であるので、これからテレビで幾度と無く見ることになるだろう。ゲド戦記は滅多に見ない気がするが。


2012年9月24日月曜日

Haskell GHC 導入メモ

 C++erはHaskellでコメントを書く、などと言われるHaskellだ。Real World Haskellのまえがきを読んだところ、面白そうだったので、ちょっと迷ったが買ってしまった。

 環境を整えるのは非常に簡単だったが、いつまでも覚えられるという事もない。後々別のPCに40秒でHaskellを入れたいという事もあるかもしれないので、導入メモを載せておこう。

 HaskellのコンパイラはGHCだ。念のため、もう一つあるということだけは記載しておく。..もう一つある。
 さて、執筆時の最新版は7.6.1だが、導入時は7.4.2であった。ちょっと違和感を覚えたので軽く調べたところ、7.6.1は一般用ではなく、一般ユーザーは11月にリリースされるHaskell Platformを待つようにとの記載があった。 Haskell Platformというものを初めて知ったが、ライブラリやツール等も付属した開発環境らしい、期待大である。
 勉強用には7.4.2を使えばよいのではないだろうか。ちなみにReal World Haskellでは6.8.2以上を対象としている。

 ダウンロードしたらwin版はインストーラーになっているので、後は勝手にやってくれる。場所はパスに日本語を含まないフォルダがいいだろう。
 これだけでGHCiを起動してHaskellをいじることが可能だ。

 Haskellのソースファイルは「.hs」ファイルだ。コメントとコードがひっくり返る「.lhs」ファイルもあるが、何時役立つのだろうか。このソースファイルを書くために、別途エディタが必要だ。

 GHCiの「:e」というコマンドで、エディタが立ち上がるのだが、デフォルトではシステムで設定されたエディタが呼び出される。特にいじっていなければメモ帳が開くだろう。システム設定を変えずにエディタを変更するには、GHCiが起動時に実行する設定ファイルで指定する必要がある。

 HOMEディレクトリと、GHCiの実行ファイルがあるディレクトリ上に存在する「.ghci」ファイルがコマンドとして実行されるが、デフォルトではこのようなファイルは用意されていないため、勝手に作ってやればいい。今回は実行ファイルのあるディレクトリに設定ファイルを置いた。例としては次のような配置である。

C:\ghc\ghc-7.4.2\bin\.ghci

 中身は次の通り。一行目で作業ディレクトリを変更している。「/」がCを指すので注意。そして2行目でエディタの設定を変更している。実行ファイルを指定してやればよい。またgvim.exeにはパスが通っているので、そのまま呼び出すことができており、パスはシステム環境変数に追加している。

:cd /ghc/work

:set editor gvim.exe

 さて、これで一応完了であるが、エディタを閉じなければGHCiが動かないという状態になっている。少々都合が悪いので、runvimを導入すると良いだろう。http://wlog.flatlib.jp/archive/1/2009-08/category/15から入手することができる。
 runvimを使うには、ダウンロード、解凍し、gvim.exeと同じフォルダに入れればよい。そしてrunvimを通してgvimを起動するには、設定ファイルを次のように書き換える。

:set editor /vim73_kaoriya_win32/runvim.exe -e/vim73_kaoriya_win32/gvim.exe

コマンドオプションとの兼ね合いで絶対パスで指定している。上記の例ではVim関連の実行ファイルは次のような位置にあることを、念のため記載する。

C:\vim73_kaoriya_win32

 以上で導入完了だ。GHCiとVimでHaskellがいじれる。

 元々香り屋Vimにはvimrun.exeという実行ファイルが含まれている。名前が似ていてややこしいのだが、vimrunの方は、ちょっといじってみたがrunvimのような動作はせず、本来の用途も不明だ。

2012年9月19日水曜日

Unity&C#ではインターフェースが使えない?

 次のような状況を考える。
  • Aという動作を行えるオブジェクトと、Bという動作を行えるオブジェクトがある 
  • 重複したオブジェクトもある。
  • Bの動作の可否に関わらず、Aの動作が可能なオブジェクトを1カ所に格納し、それらに適宜、動作を呼び出す
  • Bも同様に格納し動作を呼び出す
Unityではコンポーネントの型による検索機能があるので、AとBをコンポーネント(MonoBeheaviorを継承したclass)とすることで、こういった要求に応えることができる。重複する場合には両方をゲームオブジェクトにアタッチすることで、分かりやすい解決となる。

 しかし、両方の動作を行える性質を持ちながら、それぞれ派生した動作を定義したいという要求が発生した場合どうするのだろうか。
 恐らくUnityの作法としては、Aの派生クラス、Bの派生クラスを定義し、2つをアタッチするのが正解なのだが、これではスクリプトファイルが一気に2つ増えてしまう。また性質を統合しているという意味を明確に示すためにも、1つのスクリプトとしてまとめたい。

 ところが、C#では多重継承が使えない。これは厄介なダイヤモンド継承と、それを回避するための複雑な手順を省きたいという考えからなのだろう。実際上記の例をそのまま多重継承できてしまうと、MonoBehaviorをA、Bそれぞれから2つ継承することになってしまう。

 今回はこういった経緯で...
C#の仕様である、インターフェースを使用して多重継承を行う方法を模索してみた。

 さて、前提条件としてA、Bというコンポーネントが存在した。コードとしては次のようになる。

// script file : ComponentA ------------------------
public class ComponentA : MonoBehavior
{
        public void funcA()
        {
                // do something
        }
}

// script file : ComponentB ------------------------
public class ComponentB : MonoBehavior
{
        public void funcB()
        {
                // do something
        }
}

 C#では多重継承が使えないが、インターフェースは多重継承が可能だ。しかも、1つのクラスと、複数のインターフェースを継承したクラスを定義することが許されている。

 まずA、Bそれぞれに対応するインターフェースを用意する。これはファイルを分ける必要はないので、それぞれのファイルにでも書き足せばいいだろう。

// script file : ComponentA ------------------------
        :
        :
public interface InterfaceA
{
        public void callA();
}

// script file : ComponentB ------------------------
        :
        :
public interface InterfaceB
{
        public void callB();
}

 インターフェースに定義されたメソッド宣言は、テンプレートでいうインターフェースのようなもの(謎)で、これを継承したクラスは同型、同名のメソッドを定義する必要がある。

 そしてUnity&C#で多重継承を模擬したクラスは以下のようなものだ。

// script file : DeriveAB ---------------------------
public class DeriveAB : MonoBehavior, InterfaceA, InterfaceB
{
        ComponentA implA;
        ComponentB implB;

        public void callA()
        {
                implA.funcA();
        }

        public void callB()
        {
                implB.funcB();
        }

        void Start()
        {
                implA = new ComponentA();
                implB = new ComponentB();
        }
}

 果てしなく、ださい。かつ幾つか致命的なトレードオフがあることを説明しなければならない。
  • このようにComponentA、ComponentBの実体をスクリプト内で生成した場合、2つのコンポーネントはUnityの検索対象に入らない。検索したい場合、スタート関数内でgameObjectにコンポーネントとしてアタッチしてやる必要がある。
  • Unityエディタはインターフェース型をインスペクターに表示しない。従って手動で参照を設定することができない。
  • スクリプト内ではインターフェース型を扱うことができるが、検索して得られるComponentAはDeriveABの基底クラスというわけではなく、ただの実体。多態性が存在しない。したがって、DeriveABを検索し、インターフェース型に変換した参照をとらなえれば、派生した動作を行うことはできない。
絶望的である。だが、それぞれのインターフェースの生成時に、別途用意した静的クラスの配列などに参照を格納することはできる。あるオブジェクトの子供のコンポーネントを検索、といった事をするには、相応の前準備が必要となるが、全検索だけなら許容範囲内の手間だろう。

 無い物ねだりだが、Unityにインターフェース型の検索機能がつけば万々歳である。もしくは、せめてインスペクターで表示してくれれば、細かな関連性の設定に使えるのではないだろうか。

 そのようなことがなければ、セオリー通りおとなしく派生クラスを2つ作り、お互いの参照を持たせるのが得策であるようだ。

2012年9月9日日曜日

Unity 複数のレイヤーマスク

 Unityでは全てのオブジェクトに対して、必ず1つレイヤーが指定されている。Unityでゲームを作るなら必ず使用することになるレイヤーの用途は、カメラのカリングマスクとしての使用だ。
 カリングというと「間引く」といった意味なので、名称に混乱するかもしれないが、カリングマスクに指定することで、カメラはそのレイヤーのオブジェクトを描画するようになる。

 カメラのセッティングをいじったことがあれば気付かれたろうが、カリングマスクには複数のレイヤーを指定することが可能だ。そしてこのカリングマスクの情報は全て1つのint値に保存される。
 レイヤーは31個まで追加することができるが、これらも全てintであり、ビットシフトによって生成される。順に
1 << 0
1 << 1
    :
    :
1 << 31
という具合である。10進数でみれば複雑に混ざり合った値に見えるが、2進数では全て異なる桁に1が入った値であるため、これらの足しあわせは全て固有の値を取ることが分かる。したがってint値1つから、31のレイヤーのうち、選択されたレイヤー全てを割り出すことが可能なのだ。

 例えばカメラが映し出すレイヤーから、スクリプトによって動的にレイヤーを追加、除外するには、以下のようにすることができる。

void Start()
{
    // push No.8 Layer & pop No.9 Layer
    camera.cullingMask += 1 << 8 - 1 << 9;
}

2012年9月3日月曜日

Vim導入

 前回までで、無事C++11を使うことが出来た。ラムダ式や可変長テンプレート、そして何やら怪しげなconstexprといった所が目的で導入しているので、それらを試してみなければならないわけではあるが...
 まぁしかし、次はminttyと組み合わせて使うエディタを変えたい。メモ帳では寂しい。Meadowが既に入っていたのだが、これは動作が重く、この上にC++の補完機能などつけるなどということは考えられない。そこでVimを使ってみようと思い立った。

 Vimはこちら から頂いた。ダウンロードして展開すればすぐ使える。すぐ使えるがまともには使えない。メモ帳とはわけが違うようだ。
 :Tutorialというコマンドを打ち込むとチュートリアルが始まる。チュートリアルといっても、回答欄の付いたマニュアルといったもので、変更すると元データが書き変わってしまうようだ。そのためバックアップを取るように指示されるのだが、最初にアンドゥ(ノーマルモードで u )だけは覚えることで最初の状態に保てる。誤って :w などと打ってしまっても、ちゃんと戻ることが出来る。今のところキャッシュの限界に達したこともないので、大概大丈夫だろう。(デフォルトで1000回との情報)

 今後vimrcをいじったり、neocomplcacheをいれたりと、やることがあるが、素の状態でも予約語は色が付くし、インデントはそれなりに期待通りについてくれる。滑り出しは悪くない。