Blender2.63で少しスクリプトをいじってみた。
Blenderには組み込みのテキストエディターがあり、そのまま実行もできるのだが、カーソルがエディタのウィンドウ上にある時だけ入力が可能というような使用なので、ちょっと使いづらかったりする。
それにどうやら入力補完には対応していないらしい。となれば外部エディタを使うという選択肢もあるだろう。
Blenderではスクリプトの書かれたテキストファイルも、内部データとして保存している。そのため外部のエディタから編集するためには「Save as」で保存する必要がある。このとき拡張子を付けなければテキストファイルになってしまう。使用する外部エディタにPython編集モードがあるのならば、この段階で「.py」を付加する方が便利だ。
(追記)それなりにスクリプトを記述したが、内部データに保存するなら組み込みのテキストエディターで我慢できるが、どうせ外部に保存するならVim等でいじりたい。微妙なラインである。
2012年12月5日水曜日
2012年11月21日水曜日
Blender Pythonスクリプト挑戦
Blenderに関しては極力C++でいじりたかったので、先にコードを丸ごとTortoiseSVNで落としてきたのだが、早急に作らなければならないモデルが出てきたので、急遽Pythonスクリプトを利用することになった。
色々なブログで入門編を見ていた限り、blender&pythonは夢のような世界だろうなと想像していたのだが、踏み込んでみて少々面食らうことになる。
良いのか悪いのか、まだそんな判断を下せるほど習熟していないので、詳しい言及は避けるが..
今回記しておきたいのは、再びPythonスクリプトを組む羽目になったときのための、アタック方法だ。
まず、いつのバージョンからかは定かではないが、少なくともBlender2.63以降にはPythonコンソールのReportボタンが無く、同様の情報はInfoウィンドウに羅列される。
bpy.ops以下のオペレーターはアクティブなオブジェクト、もしくは頂点に対して適用される。
bpy.contextはアクティブなオブジェクトやオペレーターを格納している。
ちなみにbpy.context.objectの書き換えは不可能。
スクリプトからアクティブなオブジェクトを切り替える方法は未だ不明。
選択に関してはオブジェクトのselect変数で切り替えられるが、新たに選択してもアクティブなオブジェクトにはならない。
@todo:vertex_group
@todo:モード切替
bpy.dataはデータ一般を格納している。
bpy.context.object.data.verticesとbpy.data.['該当名'].meshes.verticesは同一の模様
基本的には、まず3DViewで手動で操作し、Infoに現れたレポートをコピーすることで目的のコードを得られるが、特にbpy.context.transform内の操作についてはコンソール(Pythonコンソールではなく)に「convertViewVec: called in an invalid context」と表示される。意味は謎
bpy.context.transform.rotateによって回転をかけることができるが、OBJECTモードではオブジェクトの中心点、EDITモードでは頂点の中心(Pivot Point)周りでしか回転できない。
Pythonの変数はみんなポインタのようなものだ。という説明を見たが、容易にblender自体をクラッシュさせられることから考えても、Pythonの変数はみんなvoid*だと言ってしまっていいのだと思う。
結局目的の操作がcontribというものに含まれるmesh_extra_toolsで解決できてしまいそうなので、今回は挫折することになりそうだ。そのツールの中ではbpy.opsなどは使わずに頂点情報を直接いじっているような気がする。(ちらっと見ただけ)
ここから落とせる https://svn.blender.org/svnroot/bf-extensions/
色々なブログで入門編を見ていた限り、blender&pythonは夢のような世界だろうなと想像していたのだが、踏み込んでみて少々面食らうことになる。
良いのか悪いのか、まだそんな判断を下せるほど習熟していないので、詳しい言及は避けるが..
今回記しておきたいのは、再びPythonスクリプトを組む羽目になったときのための、アタック方法だ。
まず、いつのバージョンからかは定かではないが、少なくともBlender2.63以降にはPythonコンソールのReportボタンが無く、同様の情報はInfoウィンドウに羅列される。
bpy.ops以下のオペレーターはアクティブなオブジェクト、もしくは頂点に対して適用される。
bpy.contextはアクティブなオブジェクトやオペレーターを格納している。
ちなみにbpy.context.objectの書き換えは不可能。
スクリプトからアクティブなオブジェクトを切り替える方法は未だ不明。
選択に関してはオブジェクトのselect変数で切り替えられるが、新たに選択してもアクティブなオブジェクトにはならない。
@todo:vertex_group
@todo:モード切替
bpy.dataはデータ一般を格納している。
bpy.context.object.data.verticesとbpy.data.['該当名'].meshes.verticesは同一の模様
基本的には、まず3DViewで手動で操作し、Infoに現れたレポートをコピーすることで目的のコードを得られるが、特にbpy.context.transform内の操作についてはコンソール(Pythonコンソールではなく)に「convertViewVec: called in an invalid context」と表示される。意味は謎
bpy.context.transform.rotateによって回転をかけることができるが、OBJECTモードではオブジェクトの中心点、EDITモードでは頂点の中心(Pivot Point)周りでしか回転できない。
Pythonの変数はみんなポインタのようなものだ。という説明を見たが、容易にblender自体をクラッシュさせられることから考えても、Pythonの変数はみんなvoid*だと言ってしまっていいのだと思う。
結局目的の操作がcontribというものに含まれるmesh_extra_toolsで解決できてしまいそうなので、今回は挫折することになりそうだ。そのツールの中ではbpy.opsなどは使わずに頂点情報を直接いじっているような気がする。(ちらっと見ただけ)
ここから落とせる https://svn.blender.org/svnroot/bf-extensions/
2012年10月19日金曜日
映画 ロボジー
矢口史靖監督作品 ロボジーを鑑賞。
この手の映画は恐らく映画館に行っても声を出して笑ってしまうので、自宅で見る他ない。ニュー潮風が自分の手でレンズを調整したシーンは爆笑であった。まぁ、アトムも自分のお腹を手で開閉するわけで、そうおかしい話では無いのかもしれないのだが。
しかし、やはりSEが重要なのだなと実感。人々がどんどんと騙されていく展開にリアリティがあったのは、観客もそれがロボだと感じられたからなのだろう。そしてそう感じられたのは、やはり歩き出した時のSEに、おおっと思わせられたからだ。(私の場合は
この手の映画は恐らく映画館に行っても声を出して笑ってしまうので、自宅で見る他ない。ニュー潮風が自分の手でレンズを調整したシーンは爆笑であった。まぁ、アトムも自分のお腹を手で開閉するわけで、そうおかしい話では無いのかもしれないのだが。
しかし、やはりSEが重要なのだなと実感。人々がどんどんと騙されていく展開にリアリティがあったのは、観客もそれがロボだと感じられたからなのだろう。そしてそう感じられたのは、やはり歩き出した時のSEに、おおっと思わせられたからだ。(私の場合は
2012年10月8日月曜日
Blender Bmesh Introduction
Blenderは動画チュートリアルがたくさんある。どんな機能があるかを知るにはとてもいいのだが、どう使うのか思い出したいときには少し不便だ。ということでメモを取っておく。
とりあえずBmeshについて主要な操作を抑えておきたいので、初回はBmesh Introductionだ。
BmeshとはN-gonをサポートするモデリングシステムで、N-gonとは4つ以上の頂点を持つポリゴンのことだ。
とりあえずBmeshについて主要な操作を抑えておきたいので、初回はBmesh Introductionだ。
BmeshとはN-gonをサポートするモデリングシステムで、N-gonとは4つ以上の頂点を持つポリゴンのことだ。
- ナイフ機能が強化された。「k」を押すとナイフモードに変わる。(今までは押下している時だけナイフモードになっていた。)頂点とエッジにスナップされるようになった。決定はスペースか、エンターで行う。
- 頂点を2つ以上選択して「j」を押すと、面が分割されてエッジが引かれる。(「f」では面に重なる形でエッジが引かれるだけ)
- Vertex Slide 「Ctrl + v」のVertex Menuから選択できる。もしくは「Shift + v」。カーソルでエッジを選択すると、頂点をエッジに沿って移動できる。
- Insert Faces 「Ctrl + f」のFace Menuから選択できる。もしくは「w」のメニューからも。選択された面の厚みと高さを設定して押し出せる。「e」とは違い法線方向に押し出す。
- 面を選択した上で「Shift + k」でナイフモードにした場合、選択面だけが切られる。通常のナイフモードでは視点から見て、表になっている面しか切れないが、このシフトのモードでは選択されていれば裏の面も切ることができる。
- ナイフモードで「Ctrl」を押していると、エッジの中点にスナップされる。
- Dissolve 隣り合った面を選択して、「x」メニューから選択できる。選択面が結合される。
- Bevel 一時的な機能後退なのだろうか、よく聞き取れなかったが、複数の面を追加して滑らかにベベルすることはできないらしい。「Ctrl + f」のFace Menuから選択できる。
- Bridge Two Edge Loop 同じ頂点数のエッジのループの間に面をはる。面と面の間でもいいが、選択面は削除されずに残る。「Ctrl + e」のEdge Menuから選択できる。
- MeshLint アドオン。選択中のメッシュにどのような面があるか情報を得ることができる。プロパティ画面のmeshの欄に追加される。3角メッシュの数、N-gonの数、nonmanifold Elementsの数(一つのエッジに3つ以上の面が接続している場所)、Interior Faceの数(内側に入り込んで見えない面)、さらに6+-edge polesもカウントしてくれる(これは謎)。「Select Lint」ボタンを押すと問題のある面を選択する。 nonmanifold Elementsがあると、Subdivision Surfaceモディファイアで丸めた際に不適切な形状に丸められる。
2012年10月4日木曜日
Visual C++ インクルードディレクトリを相対パスで
Visual C++ 2008では、追加のインクルードディレクトリを設定する方法には2通りある。
1つは全てのプロジェクトに対して設定する方法で、「ツール→オプション」から「プロジェクト及びソリューション→VC++ディレクトリ」、そして右上のプルダウンメニューから「インクルード ファイル」を選択し、リストにパスを追加する。
2つ目は個々のプロジェクトに対して設定する方法で、プロジェクト→(プロジェクト名)のプロパティ」から「構成プロパティ→C/C++→全般」にある「追加のインクルードディレクトリ」に設定するものだ。
さて、ここからがメモなのだが、2つ目の「追加のインクルードディレクトリ」は相対パスが設定可能らしい。「.」で「VC++ Project」ファイルのあるディレクトリを指すので、そこからの相対パスを設定してやる。
プロジェクトを複数台のPCに同期していたため、PCごとに絶対パスが異なるという状況にあり、今までは「VC++ディレクトリ」の方の設定でパスをはることで対応していた。しかし同名のヘッダが存在すると優先順位の高いもの(リストの昇順)が呼ばれてしまうため問題となる。開発中などで唯一性が保証できないヘッダにパスをはる際にはプロジェクトのプロパティで相対パスをはる方法が良さそうだ。
1つは全てのプロジェクトに対して設定する方法で、「ツール→オプション」から「プロジェクト及びソリューション→VC++ディレクトリ」、そして右上のプルダウンメニューから「インクルード ファイル」を選択し、リストにパスを追加する。
2つ目は個々のプロジェクトに対して設定する方法で、プロジェクト→(プロジェクト名)のプロパティ」から「構成プロパティ→C/C++→全般」にある「追加のインクルードディレクトリ」に設定するものだ。
さて、ここからがメモなのだが、2つ目の「追加のインクルードディレクトリ」は相対パスが設定可能らしい。「.」で「VC++ Project」ファイルのあるディレクトリを指すので、そこからの相対パスを設定してやる。
プロジェクトを複数台のPCに同期していたため、PCごとに絶対パスが異なるという状況にあり、今までは「VC++ディレクトリ」の方の設定でパスをはることで対応していた。しかし同名のヘッダが存在すると優先順位の高いもの(リストの昇順)が呼ばれてしまうため問題となる。開発中などで唯一性が保証できないヘッダにパスをはる際にはプロジェクトのプロパティで相対パスをはる方法が良さそうだ。
2012年9月27日木曜日
映画 コクリコ坂から
何故か最初の映画論評がコクリコ坂である。ブログを初めてから「カウボーイ&エイリアン」と「猿の惑星 ジェネシス」も観ていたのだが。ともかく最初なのでちょっと前置きを。
断っておくと、論評するような柄ではない。最近一番のお気に入りが「世界侵略 ロサンゼルス決戦」なのだから言わずもがなだ。
方針としては、多少覚えておきたい映画、もしくは最初の感想を覚えておきたい映画について取り上げる。必要ならばネタバレも辞さない。画像は作法が分からないし、現状の閲覧数では不要だろう。
多くの映画には原作があるが、当然こちらまでフォローはしない。あくまで映画、そして映画脚本に対する感想というスタンスで行くことにしよう。
では「コクリコ坂から」について感想をまとめてしまう。最近のジブリ映画は、手放しに誉めた評判は聞かないという印象がある。したがって、結構身構えて見るわけだが、今回気になったのは2点。
まず1点目から、舞台、背景の雰囲気が結構良かった。斜面に広がる住宅地から、曲がった坂道で港まで繋がっており、海岸線と平行する通りに商店が並んでいる。橙色の電灯を灯して賑わう商店街の雰囲気が良い。またそれとは対照的に、朝霧に霞む住宅地も涼やかで良い。
確かに千と千尋などと比べると、いくらか絵が味気ないようだが、いい塩梅といったところなのではと感じた。
ここからネタバレ含む
2点目、なにやら全てがハッピーエンドになっていないだろうか。主人公メルと風間は兄妹だと思ったら、兄妹ではなく、カルチェラタンの取り壊しは、これもまた土壇場でひっくり返る。
せめてカルチェラタンは取り壊されて欲しかった。頑張ったけどどうにもなからなかった、というようなストーリーを一個踏まえておけば、兄妹じゃなくて良かったねと、共感することもできるのだ。ストーリーも引き締まるのではないだろうか、大団円から大団円へと、まさしく駆け足で移動するというのは如何なものだろう。
タグボートから商船のタラップに乗り移るシーン、シータとパズーかよ、という描写だったが、少し重点を置いているのだろうか。たしかに普通の高校生だと考えれば結構なアクションシーンだ。こんな事までして聞きに行かなくてもいいよとちょっと迷っても良かったのではないか。もっとも、ハッピーエンドラッシュで気が大きくなっているメルの思考には、そんな逡巡が入り込む余地は無さそうである。
まとまりが無いが、こんなところで。ジブリ作品であるので、これからテレビで幾度と無く見ることになるだろう。ゲド戦記は滅多に見ない気がするが。
断っておくと、論評するような柄ではない。最近一番のお気に入りが「世界侵略 ロサンゼルス決戦」なのだから言わずもがなだ。
方針としては、多少覚えておきたい映画、もしくは最初の感想を覚えておきたい映画について取り上げる。必要ならばネタバレも辞さない。画像は作法が分からないし、現状の閲覧数では不要だろう。
多くの映画には原作があるが、当然こちらまでフォローはしない。あくまで映画、そして映画脚本に対する感想というスタンスで行くことにしよう。
では「コクリコ坂から」について感想をまとめてしまう。最近のジブリ映画は、手放しに誉めた評判は聞かないという印象がある。したがって、結構身構えて見るわけだが、今回気になったのは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のような動作はせず、本来の用途も不明だ。
環境を整えるのは非常に簡単だったが、いつまでも覚えられるという事もない。後々別の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#ではインターフェースが使えない?
次のような状況を考える。
しかし、両方の動作を行える性質を持ちながら、それぞれ派生した動作を定義したいという要求が発生した場合どうするのだろうか。
恐らくUnityの作法としては、Aの派生クラス、Bの派生クラスを定義し、2つをアタッチするのが正解なのだが、これではスクリプトファイルが一気に2つ増えてしまう。また性質を統合しているという意味を明確に示すためにも、1つのスクリプトとしてまとめたい。
ところが、C#では多重継承が使えない。これは厄介なダイヤモンド継承と、それを回避するための複雑な手順を省きたいという考えからなのだろう。実際上記の例をそのまま多重継承できてしまうと、MonoBehaviorをA、Bそれぞれから2つ継承することになってしまう。
今回はこういった経緯で...
C#の仕様である、インターフェースを使用して多重継承を行う方法を模索してみた。
さて、前提条件としてA、Bというコンポーネントが存在した。コードとしては次のようになる。
C#では多重継承が使えないが、インターフェースは多重継承が可能だ。しかも、1つのクラスと、複数のインターフェースを継承したクラスを定義することが許されている。
まずA、Bそれぞれに対応するインターフェースを用意する。これはファイルを分ける必要はないので、それぞれのファイルにでも書き足せばいいだろう。
インターフェースに定義されたメソッド宣言は、テンプレートでいうインターフェースのようなもの(謎)で、これを継承したクラスは同型、同名のメソッドを定義する必要がある。
そしてUnity&C#で多重継承を模擬したクラスは以下のようなものだ。
果てしなく、ださい。かつ幾つか致命的なトレードオフがあることを説明しなければならない。
無い物ねだりだが、Unityにインターフェース型の検索機能がつけば万々歳である。もしくは、せめてインスペクターで表示してくれれば、細かな関連性の設定に使えるのではないだろうか。
そのようなことがなければ、セオリー通りおとなしく派生クラスを2つ作り、お互いの参照を持たせるのが得策であるようだ。
- Aという動作を行えるオブジェクトと、Bという動作を行えるオブジェクトがある
- 重複したオブジェクトもある。
- Bの動作の可否に関わらず、Aの動作が可能なオブジェクトを1カ所に格納し、それらに適宜、動作を呼び出す
- Bも同様に格納し動作を呼び出す
しかし、両方の動作を行える性質を持ちながら、それぞれ派生した動作を定義したいという要求が発生した場合どうするのだろうか。
恐らく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のレイヤーのうち、選択されたレイヤー全てを割り出すことが可能なのだ。
例えばカメラが映し出すレイヤーから、スクリプトによって動的にレイヤーを追加、除外するには、以下のようにすることができる。
カリングというと「間引く」といった意味なので、名称に混乱するかもしれないが、カリングマスクに指定することで、カメラはそのレイヤーのオブジェクトを描画するようになる。
カメラのセッティングをいじったことがあれば気付かれたろうが、カリングマスクには複数のレイヤーを指定することが可能だ。そしてこのカリングマスクの情報は全て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をいれたりと、やることがあるが、素の状態でも予約語は色が付くし、インデントはそれなりに期待通りについてくれる。滑り出しは悪くない。
まぁしかし、次はminttyと組み合わせて使うエディタを変えたい。メモ帳では寂しい。Meadowが既に入っていたのだが、これは動作が重く、この上にC++の補完機能などつけるなどということは考えられない。そこでVimを使ってみようと思い立った。
Vimはこちら から頂いた。ダウンロードして展開すればすぐ使える。すぐ使えるがまともには使えない。メモ帳とはわけが違うようだ。
:Tutorialというコマンドを打ち込むとチュートリアルが始まる。チュートリアルといっても、回答欄の付いたマニュアルといったもので、変更すると元データが書き変わってしまうようだ。そのためバックアップを取るように指示されるのだが、最初にアンドゥ(ノーマルモードで u )だけは覚えることで最初の状態に保てる。誤って :w などと打ってしまっても、ちゃんと戻ることが出来る。今のところキャッシュの限界に達したこともないので、大概大丈夫だろう。(デフォルトで1000回との情報)
今後vimrcをいじったり、neocomplcacheをいれたりと、やることがあるが、素の状態でも予約語は色が付くし、インデントはそれなりに期待通りについてくれる。滑り出しは悪くない。
2012年8月31日金曜日
C++11が使いたい "その2"
Clang3.1 Hello auto
実はHelloWorldのコンパイルもすんなりとは通らなかった。
clangもC++のコンパイルはclang++で行うこと、後はlibgcc_s_dw2-1.dllにパスが通っていないなかった、などということで手間取った。
libgcc_s_dw2-1.dllはMinGW/binに入っていたが、MSYSを通して色々なものが動作していたらしく、パスが通っていなかったのだ。副作用でEclipseで作った実行ファイルが動くようになった。今までGCCでコンパイルしたファイルは動いていたのだから、分からない話だ。
そうして遂にC++11のコンパイルが可能となった。最も簡単な機能はなんだろう。最初に思いついたのは auto であった。null_ptr の方が簡単だったが、思いつかなかった。HelloWorldプログラムに追加して、もはや何がハローなのか分からないプログラムにしてみる。
さて、重要なのはこれをメモしておくことだ。clangでC++11の機能を有効化してコンパイルするには、次のコンパイルオプションを指定する必要ある。
-std=c++11 もしくは -std=gnu++11
ついでに、実行ファイルを作るには
clang++ -std=c++11 HelloWorld.cpp -o HelloWorld
このままじゃC++11は使えないからオプション指定してね、というようなエラーメッセージは出るのだが、どうしてか、そのものズバリは教えてくれない。
実はHelloWorldのコンパイルもすんなりとは通らなかった。
clangもC++のコンパイルはclang++で行うこと、後はlibgcc_s_dw2-1.dllにパスが通っていないなかった、などということで手間取った。
libgcc_s_dw2-1.dllはMinGW/binに入っていたが、MSYSを通して色々なものが動作していたらしく、パスが通っていなかったのだ。副作用でEclipseで作った実行ファイルが動くようになった。今までGCCでコンパイルしたファイルは動いていたのだから、分からない話だ。
そうして遂にC++11のコンパイルが可能となった。最も簡単な機能はなんだろう。最初に思いついたのは auto であった。null_ptr の方が簡単だったが、思いつかなかった。HelloWorldプログラムに追加して、もはや何がハローなのか分からないプログラムにしてみる。
#include <iostream> #include <string> #include <vector> int main(int argc, char* argv[]) { std::vector<std::string> str_list; for(int i=0; i<2 i++) { std::string temp; std::cin >> temp; str_list.push_back(temp); } std::cout << "Hello " << std::endl; for(auto iter=str_list.begin(); iter!=str_list.end(); ++iter) { std::cout << *iter << std::endl; } return 0; }
さて、重要なのはこれをメモしておくことだ。clangでC++11の機能を有効化してコンパイルするには、次のコンパイルオプションを指定する必要ある。
-std=c++11 もしくは -std=gnu++11
ついでに、実行ファイルを作るには
clang++ -std=c++11 HelloWorld.cpp -o HelloWorld
このままじゃC++11は使えないからオプション指定してね、というようなエラーメッセージは出るのだが、どうしてか、そのものズバリは教えてくれない。
2012年8月30日木曜日
C++11が使いたい "その1"
Clang 3.1
Eclipseに挫折した経緯、MinGW、MSYSの導入なども記録しておくべきであるが、とりあえずはすっ飛ばしてClang3.1の導入について記す。
私のPCにはMinGW、MSYS、minttyが入っていて、CUIを使おうと思ったらminttyを使っている。minttyというのはCygwinのターミナルエミュレータだ。Cygwinなんて入れた覚えないな、と思っていたのだが、Cygwinを入れなくても使えるようで、どうやらMinGWからインストールしたもののようだ。かなり高機能なターミナルエミュレータだそうで、コピー&ペーストもできるのでお気に入りである。
さて、C++標準への準拠度はClang3.1の方が高いが、gccの方が吐き出すプログラムは高速な場合が多いらしい。どちらでもいいのだが、gccはMinGWと混ざってしまっていて、よく分からない状態になっていて、下手に触りたくない。先にClangの導入を行うことにした。
調べるとgccでClangをビルドしたという記事が多いが、バイナリでもらうのが好きである。ダウンロード時間がかかったり、もしかしたらビルドした方がパフォーマンスが良くなるのかもしれないが、人のコードをビルドするということに少なからずストレスを感じるのだ。
ということで、参考のブログを見つつClangのバイナリをダウンロード。ダウンロードした圧縮ファイルを解凍する。ただしLhaplusで解凍すると、@LongLinkというファイルができてしまう。これも詳しくは分からないが、解凍は完了するものの失敗している。
成功した方法はminttyで
tar jxf clang+llvm-3.1-i386-mingw32-EXPERIMENTAL.tar.bz2
と打つものだ。Windowsで最初から使えるコマンドなのか分からなかったので、少し圧縮、解凍のテストを試みたのだが、結局よく分からないため、確証を得るのは次の何かの機会に持ち越しである。
次の手順は展開したファイルをMinGWのインストール先のフォルダに入れるそうだが、パスの関係を考えると、MinGW/binの中にフォルダごと入れても無駄なのだろう。binの中身をそっくり入れる必要があるのだろうが、本格的にわけが分からなくなってしまう。システム環境変数 Pathにclangのbinを追加することにした。
これでインストール完了のようだ。minttyからclangを呼び出すと反応してくれる。
Eclipseに挫折した経緯、MinGW、MSYSの導入なども記録しておくべきであるが、とりあえずはすっ飛ばしてClang3.1の導入について記す。
私のPCにはMinGW、MSYS、minttyが入っていて、CUIを使おうと思ったらminttyを使っている。minttyというのはCygwinのターミナルエミュレータだ。Cygwinなんて入れた覚えないな、と思っていたのだが、Cygwinを入れなくても使えるようで、どうやらMinGWからインストールしたもののようだ。かなり高機能なターミナルエミュレータだそうで、コピー&ペーストもできるのでお気に入りである。
さて、C++標準への準拠度はClang3.1の方が高いが、gccの方が吐き出すプログラムは高速な場合が多いらしい。どちらでもいいのだが、gccはMinGWと混ざってしまっていて、よく分からない状態になっていて、下手に触りたくない。先にClangの導入を行うことにした。
調べるとgccでClangをビルドしたという記事が多いが、バイナリでもらうのが好きである。ダウンロード時間がかかったり、もしかしたらビルドした方がパフォーマンスが良くなるのかもしれないが、人のコードをビルドするということに少なからずストレスを感じるのだ。
ということで、参考のブログを見つつClangのバイナリをダウンロード。ダウンロードした圧縮ファイルを解凍する。ただしLhaplusで解凍すると、@LongLinkというファイルができてしまう。これも詳しくは分からないが、解凍は完了するものの失敗している。
成功した方法はminttyで
tar jxf clang+llvm-3.1-i386-mingw32-EXPERIMENTAL.tar.bz2
と打つものだ。Windowsで最初から使えるコマンドなのか分からなかったので、少し圧縮、解凍のテストを試みたのだが、結局よく分からないため、確証を得るのは次の何かの機会に持ち越しである。
次の手順は展開したファイルをMinGWのインストール先のフォルダに入れるそうだが、パスの関係を考えると、MinGW/binの中にフォルダごと入れても無駄なのだろう。binの中身をそっくり入れる必要があるのだろうが、本格的にわけが分からなくなってしまう。システム環境変数 Pathにclangのbinを追加することにした。
これでインストール完了のようだ。minttyからclangを呼び出すと反応してくれる。
2012年8月28日火曜日
C++11が使いたい "その0"
C++11とは、説明するまでもないがC++の最新の標準である。C++0xと呼ばれていたように0年代に承認される見通しだったものが、2011年までずれ込んでいる。その影響で次期標準はC++1xではなく、C++1yと呼ばれるようだ。
Microsoft Visual C++以外の環境でまともにプログラムが作れない身としては、Visual C++ 2012での対応を待つしかなかったのだが、メインPCのWindows Xpが健在で、Win7を使う比率が低く、VCのベータ公開時なども見送ってきた。
一方、このVC++2012であるが、可変長テンプレートをはじめ、どうやら相当数の機能に対応していないらしい。
メインPCをWin7にしたら、なんて暢気なことを言っていてはいけないな、と気が付いた。
C++11に対応したコンパイラであるgcc4.7、もしくはClang3.1を使えばいいわけである。
そのための環境が必要となる。何か他の統合環境、MinGW、もしくはLinux、なんとかしてC++11を触らねばならない。
Microsoft Visual C++以外の環境でまともにプログラムが作れない身としては、Visual C++ 2012での対応を待つしかなかったのだが、メインPCのWindows Xpが健在で、Win7を使う比率が低く、VCのベータ公開時なども見送ってきた。
一方、このVC++2012であるが、可変長テンプレートをはじめ、どうやら相当数の機能に対応していないらしい。
メインPCをWin7にしたら、なんて暢気なことを言っていてはいけないな、と気が付いた。
C++11に対応したコンパイラであるgcc4.7、もしくはClang3.1を使えばいいわけである。
そのための環境が必要となる。何か他の統合環境、MinGW、もしくはLinux、なんとかしてC++11を触らねばならない。
2012年8月27日月曜日
開始宣言
とにかく投稿してみないことには、見た目もなにも分からない。
ブログという形態で文章を書くことは全くもって苦手で、続いた試しがない。
何かしらのその時々にやっていたこと、作っていたものの宣伝に利用してしまうのが落ちで、続けて書くネタに困るというのがパターンである。
そして精々3つ4つの記事が載っているだけのブログに宣伝効果は全くなく、広告にならないといって見切りを付けてしまう。
しかしそれでも見る人は見るもので、年単位で放置したブログの配布物に関してメールが届くということもあって、なかなか面白いとは思っていたし、またブログを始めてみたいと思っていたわけである。
ここ数年はC++やUnityで、ゲームなどの開発を行っていたため、ネット上に文章をあげる意義が生じてきた。
愛読の参考書籍もあるが、殆どネットを師匠に勉強してきたため、ブログがいかに偉大な存在であるかは身にしみている。
ガッチリとまとめたウェブサイトもいいが、やはり情報の新しさと天秤にかけると、ブログに軍配が上がるのではないだろうか。それとも、ウェブサイトと書籍というジャンルに対して、ブログは全く違うジャンルであるという感じだろうか。
ネットに繋がり、開発者を気取る身としては、ハウツー的文章をあげる事に対する憧れと欲求は非常に強かったのである。
さて、その欲求はTwitterをはけ口として解消されてきた。しかしながら数年経ち、吐き出されたものたちを遡って観察すると、あることに気が付いた。これらは全くもって連続性を持った有益な情報になっていないし、自身にとってすら再利用性がないのである。そもそも遡るのもしごく難儀である。
プログラミング上の注意を書き留めたこともあったし、モデラーの操作法をメモしたこともあった。
全く馬鹿げていたと思うが、洋書の和訳をしていたこともあった。そうしたことが、既にTwitterでは忘却の彼方に追いやられている。
時間をかけてスクロールすれば手繰れるというのは、脳細胞に比べて随分と優秀だが..
これぞまさしく期待した我がバーチャル記憶体系!とはならなかったのである。
したがってブログあってのTwitterであるとの結論にいたり、苦手の克服も兼ねて長々と開始宣言をしたためた次第なのだ。
ブログという形態で文章を書くことは全くもって苦手で、続いた試しがない。
何かしらのその時々にやっていたこと、作っていたものの宣伝に利用してしまうのが落ちで、続けて書くネタに困るというのがパターンである。
そして精々3つ4つの記事が載っているだけのブログに宣伝効果は全くなく、広告にならないといって見切りを付けてしまう。
しかしそれでも見る人は見るもので、年単位で放置したブログの配布物に関してメールが届くということもあって、なかなか面白いとは思っていたし、またブログを始めてみたいと思っていたわけである。
ここ数年はC++やUnityで、ゲームなどの開発を行っていたため、ネット上に文章をあげる意義が生じてきた。
愛読の参考書籍もあるが、殆どネットを師匠に勉強してきたため、ブログがいかに偉大な存在であるかは身にしみている。
ガッチリとまとめたウェブサイトもいいが、やはり情報の新しさと天秤にかけると、ブログに軍配が上がるのではないだろうか。それとも、ウェブサイトと書籍というジャンルに対して、ブログは全く違うジャンルであるという感じだろうか。
ネットに繋がり、開発者を気取る身としては、ハウツー的文章をあげる事に対する憧れと欲求は非常に強かったのである。
さて、その欲求はTwitterをはけ口として解消されてきた。しかしながら数年経ち、吐き出されたものたちを遡って観察すると、あることに気が付いた。これらは全くもって連続性を持った有益な情報になっていないし、自身にとってすら再利用性がないのである。そもそも遡るのもしごく難儀である。
プログラミング上の注意を書き留めたこともあったし、モデラーの操作法をメモしたこともあった。
全く馬鹿げていたと思うが、洋書の和訳をしていたこともあった。そうしたことが、既にTwitterでは忘却の彼方に追いやられている。
時間をかけてスクロールすれば手繰れるというのは、脳細胞に比べて随分と優秀だが..
これぞまさしく期待した我がバーチャル記憶体系!とはならなかったのである。
したがってブログあってのTwitterであるとの結論にいたり、苦手の克服も兼ねて長々と開始宣言をしたためた次第なのだ。
登録:
投稿 (Atom)