Google

2011年11月25日金曜日

オライリーオンラインストア

過去に紹介したオライリーのストアですが。
ログインして過去の履歴からダウンロードできるようになったとの通知が。

http://www.oreilly.co.jp/ebook/


今まで買ったことがないなら普通に登録すればおk。
買ったことがある人はその際のメアドで登録すると過去の履歴がでます。
ってんで早速やってみたのですが、、、。


あれ、過去に買ったはずのTomcatハンドブック第2版がない、、、。
E-Bookストアからもリンクが消えてる。
ま、手元にはpdfあるからいいんだけど。

ということで多少は便利になったみたいです。

2011年11月24日木曜日

新作ゼルダは

ええ。このざまですよ、、、、、、。


11時過ぎてから発送開始メールが届く有様。
忙しいからあんまやる時間も無いんですけどね、、、。

2011年11月16日水曜日

PrefabをC#のみで生成

GUIで指定したPrefabの生成方法は以前行いました。
しかしこの方法、100個必要なら100個のメンバ変数と紐付けが待ってるという事です。
これではとてもではありませんが実用に耐えるものではありません。

そこで今回はGUI指定不要なプレハブ生成です。
これなら何個あろうが命名規則でまとめるだけですみますね。

では実験の手順です。
  1. プレハブを作成します。
  2. Projectヒエラルキー上にResoucesという名称のディレクトリを作成します。
  3. 作成したプレハブをその下に入れます。
  4. 生成ソースを空GameObjectに紐付け
今回もプレハブにはCubeを使用します。
1.の手順は以前の記事と全く同じなので割愛。
プレハブにしたらヒエラルキー(シーン)からCubeを削除しておきましょう。
2.と3.は以下のように行います。

Projectの下にあるCreateを押して
メニューからフォルダを選択
できたフォルダをResorcesに変名しましょう。
ここまで来たらCubeのプレハブをフォルダにドロップして3.まで完了です。
続いて今回のソースコード。

さっくりとstart関数の中を解説。
1行目はprefabという変数はCubeという名前のプレハブから作成してます。
プレハブの名称はCubeなので、このまま引数に渡し、戻りがObjectなのでGameObjectにキャストします。
このprefabという変数をひな形として、GameObjectを生成しているのが2行目です。

このResouces.Loadはクラスメソッドなのでいつでも呼び出せます。
リファレンス原文はこちらを御覧ください。
http://unity3d.com/support/documentation/ScriptReference/Resources.Load.html

ここから4.の作業に入ります。
以前と同様にUnityGUI上でC#のソースコードを生成し、上記ソースを書きこんで、空っぽのGameObjectにドラッグ&ドロップで紐付けしてください。

実行前にはシーンにカメラとこのソースのGameObjectがあるのみで、目に見える物体が何もない状態であれば準備完了です。
では実行してみましょう。

実行前。カメラとソースが入ったGameObjectだけです。
実行後。シーンになかったCubeプレハブができています。
出来上がった動的GameObjectの名称はCube(Clone)となっています。
(Clone)はUnityが勝手に付けるので、名称管理などをしてて気になるのなら、nameプロパティで動的に名称を変更すればよいでしょう。



ちなみに、今回わざわざフォルダを作成した理由ですが、、、、

・Resource以下で無いと生成元データを見つけられない。

という制約があるためです。
実際にディレクトリ無しでやってみると、ひな形がnullとなってうまく動いてくれません。

なんでこんなルールかというと、、、。
Unity3dはGUI型ツールなので、エディタ等特殊なサポートツールを追加可能です。
しかしサポートツールのコードを、最終的なゲームのバイナリに出力したくない場合もあります。
(例えばEzGUIの設定画面とか)
Unityではその区分けをディレクトリの表記名で行なっているため、こういったルールとなっているようですね。
ResoucesはGameObject等を動的に読み出すために予約された名称で、この下ならある程度のディレクトリ構成名称は自由なようです。

原文を読みたい方は以下からどうぞ。

2011年11月14日月曜日

IT手袋2011年版

今年はやけに暖かいですが、さすがに夜は寒くなって来ました。
去年は人差しと親指だけ静電伝達してスマホを触れる手袋をしてましたが、どうにも滑って危ないので買い替えしようかと考えていた矢先。
近所のコンビニでこんなのが売ってたので即買いしてしまいました。

指全部が通電してくれる新型。1000円。
ま、指全部バージョンは去年からあるっちゃあるんですが。
フリーサイズってのも昔からよく見ますし。
しかし一番のポイントはここでした。

滑り止めがついてるー

軍手のダサさを一瞬想像してしまいましたが。
ヘキサグラム状に黒い樹脂を配置してあるのでデザ上問題ありません。
手のひらにしかついてないので指だけでは滑るという点には注意。

今のところ、つるつるするiPhoneでも全く問題なし。
なかなかお勧めです。

2011年11月11日金曜日

iOS5.0.1

アップデートしてみました。
今までは母艦に接続しなければ不可能だったものが単体でできるっていいですね。

サイズは44.6MB
大体10分程度で終わりました。
再起動後も特に問題なく動いてます。
どれぐらい持つようになったのかはこれからなんで。

あ、手順はあちこちで書かれていますが一応書いときます。

「設定」→「一般」→「ソフトウェア・アップデート」に入って、5.0.1の項目を押すだけ。

アップデート前に「AC電源に繋げばバッテリーを節約できる」とかなんとか、当たり前すぎてあんまし意味のない事を言われた気が。
むしろ電源につながないとアップデートできない某ゲーム機より全然おkです。

2011年11月10日木曜日

プリミティブを動的生成

GUI指定で動的生成は簡単でした。
あまり使う機会は無いかも知れませんが、こんな生成の方法もあります。

 static function CreatePrimitive (type : PrimitiveType) : GameObject

GameObjectに付随するクラスメソッドです。
プリミティブは直訳すれは「原始的」ですが、3Dでは球体や板等の純粋な部品を指します。
Unityが素で作れるGameObjectを作れるという事ですね。

指定できるのはPrimitiveTypeという列挙型。
定義されているタイプは5つ。


  • Sphere
  • Capsule
  • Cylinder
  • Cube
  • Plane


C#で表現する場合、例えばCubeなら以下のような表記になります。

 PrimitiveType.Cube

C++での列挙体では列挙体名は不要でしたが、こちらでは必要です。

ちなみにこの5つの項目。
これはメニューの「GameObject」→「Create Other」の中にある3枠目の項目群と一致します。

先程の関数での使い方も至って簡単。


void Start()
{
    GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Plane);
}


こんな感じで書けばPlaneが生成されます。
位置やスケールの指定が引数に何も無いのでお気づきかと思いますが、位置は全部0,スケールは1のままで生成されます。

ゲームとしては使い物になりませんが一応。

2011年11月8日火曜日

PrefabGUI指定で生成

前回の続き。
最も簡単な方法であるプレハブ指定の方法です。

といいながら、以前書いたように、プレハブのクラスは存在しません。
なので、ここでもまたUnity特有の手法が存在します。

今まで何度も出ましたが、GUI上でドラッグ&ドロップですね。

以下が今回のサンプルソースコード。

using UnityEngine;
public class SampleScript : MonoBehaviour {
 public GameObject prefab;
 public void Start() {
    GameObject aaa =
        (GameObject)Instantiate(
            prefab,
            transform.position,
            transform.rotation);
 }
}

メンバにprefabという名前のGameObjectがあります。
publicにすると紐付けしたGameObjectをクリックした際、インスペクタにメンバが表示されるという点は以前書きました。
そしてドラッグ&ドロップで実行前にインスタンスを指定という方法も書きました。
これをそのままここに応用することができます。

では具体的な手順。

まずは上記コードをC#として作成し保存。



適当な元プレハブを準備しましょう。今回は分かりやすくCubeを作ります。
メニューから「GameObject」→「Create Other」→「Cube」で生成。



そのままProjectビューにドラッグしてプレハブ化。
空色キューブ型アイコンがプレハブの印です。



空っぽのGameObjectを作成してこのSampleScriptをドラッグ&ドロップで紐付け。


インスペクタにprefabというメンバ変数が出るので、Cubeをドラッグ&ドロップ。
赤丸の部分を左上から右下に入れるだけです。


何もない状態から生成される事を分かりやすくするために、シーン上にあるCudeは削除しておきましょう。(プレハブではなく、ヒエラルキー上のCubeです)
これで準備完了です。

実行するとGameObjectと同じ位置にCubeが生成されます。

ビフォー

アフター
なかったはずのキューブが出てきましたね。
要は一旦ゲームオブジェクトとして確定したプレハブは、この方式でいつでも実体化できるということです。

2011年11月7日月曜日

Unityでのオブジェクト生成


Unity3dでGameObjectを生成する方法です。
まずはさらっと概要をば。

実行中に生成するということは、それまで画面上になかったものをインスタンスとして表示させるということです。
開発側からすると、「どれ」をシーンに出すのか?という事を認識する必要があります。
普通はクラスをnewしてインスタンス化しますが、UnityではプレハブやGameObjectを元にします。

インスタンス化のメソッドがこちら。

static function Instantiate
(original : Object,
position : Vector3,
rotation : Quaternion) : Object

これはObjectクラスのクラスメソッドなので、MonoBehaviour派生クラスならいつでも呼び出せます。
クラスメソッドはC++で言えばstaticメンバ関数ですね。

さてこの関数、呼び出しているクラスをコピーするとかではありません。
第1引数にoriginalとあるように、元を入れるとそのコピーをインスタンス化するという機能です。
つまり、既になんかしらの形で存在しているObject又はその派生クラスであるGameObject等を準備しなければなりません。

何が対象になるのかというと、ざっとこんな感じ。

・Project内にあるプレハブ
・シーンに既にあるGameObject
・Project内にあるFBX等のインポートデータ
・アセットバンドルファイル

ゲームを作るには十分なバリエーションではないかと。
FBX等のインポートデータも、取り込んだ時点でプレハブになるので、同じという事になります。

一番簡単なのはプレハブですが、それはまた次回。

2011年11月3日木曜日

別のメソッド呼び出し方法

Unityには通常と違うメンバ関数(メソッド)の呼び方があります。
HogeというクラスにFuncという引数付きメソッドがある場合、通常はこう。

public class Hoge : MonoBehaviour{
void Func(int val);
}
Hoge hoge = new Hoge();
hoge.Func(100);

これをSendMessageで行うとこうなります。


Hoge hoge = new Hoge();
hoge.SendMessage("Func", 100);


リファレンスはこちら。
Component::SendMessage

見ての通りComponentなので、GameObjectでもMonoBehaviourでも使えます。
しかしこのSendMessage、引数取得等には使えません。
一方的に呼び出すプロシージャ的な扱いです。
こんな呼び出し、果たして何のためにあるかという話ですが、、、。

実際には言語の壁を超える場合に最も有効なようです。
C#とJSを混在させた場合、互いのクラスが参照できないといった現象に度々出くわします。
しかしSendMessageは弱い型付けとして動作するため、クラス定義が見つからない状態でもエラーとならず呼び出すことができます。

これはUnityをブラゲーとして動作する場合にも有効です。
HTML上で動作するJsからUnityへ値を受け渡しする際にもこれを使用したりします。
サーバ側でセッション情報等を生成しHTMLに埋め込んで、Unityが受け取って通信したい場合等は必須とも言えますね。

2011年11月1日火曜日

Buzzが終了でGoogleReaderがTwitterに

いい加減な表題に見えますが、風が吹けば桶屋が儲かる話ではありません。
私以外にはどうでもいいのかも知れませんが、人気が無くて終了したGoogleBuzzの影響がGooleReaderとTwitterに来ています。

それは以前書いた この機能 に関する話。
要はGoogleReaderのニュースをツイートしたいだけなんですが。

昨日までは普通に動いていたこの機能だったのに。
今日PCを立ち上げたら、GoogleReaderが新しいデザインになってました。


ぐはっ、どこにも共有のボタンがねぇ。
代わりに転送先指定プルダウンだけのこっていやがるー。

ここからツイートしろとのお達し

これだと別ウィンドウがでるからめんどくさいのに。
さーて、別の手を考えねばならんです。


11/2 追記:
Google+で共有すれば良いらしいという情報があったのですが、ニュースだらけでちからるのでそれもやりたくない、、、、。

2011年10月31日月曜日

プレハブの弱点


今回もUnity3dのプレハブ話です。

これはあちこちで万能っぽく言われてますが、結構制限もあるので注意が必要です。
簡単に言うと、プレハブ本体とインスタンスでの違いが顕著です。
まず共通としてあるのは、プレハブ化した後に子をくっつけることができない事。
というと語弊があるので詳細を言うと、、、

プレハブ本体:
もともとProjectツリー側では実行時の親子は関係ないのでできません。
プレハブ化する前に親子付けしていた他のオブジェクトの関係は見えません。
ここで追加削除したコンポーネントは何事も無くインスタンスへ反映させることができます。

インスタンス側:
ヒエラルキー上で無理やり親子関係を変更すると、インスタンスがPrefabではなくなります。
プレハブでなくても別に構わないのですが、せっかくまとめて変更を適用できるといった利点が勿体ないですね。
Ctrl+Zも効きますが、確定してしまえばそのオブジェクトは二度と仲間には戻れません。
位置や回転なら特に問題はありません。(むしろできないと困る)
Component周りの変更も問題なく反映されます。

一番困ると思われるのはこんなケースじゃないでしょうか。
 ・木のプレハブを作成してマップに100本配置
 ・配置完了後に子オブジェクトとして木の実を追加したいと言われる。
 ・木の実はマテリアルでは実現できない仕様だった

無理やり元のプレハブへぐりっとやっても解決しないのでご注意を。
つまりは、コンポーネント周りでの変更ぐらいしかダイナミックな変更ができないってことです。
計画的に配置しないといけないってことですね。

2011年10月27日木曜日

Unity 3.4.2f2にバージョンアップ

今日、Unityのマイナーバージョンアップがありました。

3.4.1f5
から
3.4.2f2
です。

詳細とダウンロードはこちら。
http://unity3d.com/unity/whats-new/unity-3.4.2

今回はほんの少しで、スマホ周りのクラッシュやAppleガイドライン絡みのようです。
ざっとみた感じ特にバージョンアップしても問題なさげ。
安心してアップデートしてください。

しかしスマホの作業をしてるとよく落ちるのが困りもの。
ひどいと1日に数回は再起動とかざら。

次回3.5で大きな改変が待っているようなので、安定化するといいですね。

2011年10月26日水曜日

エンジニア視点のプレハブ

Unityのプレハブ機能、ゲーム開発界隈で結構有名です。
雛形からコピーが作れるのと、生成済の仲間に対してまとめて変更部分を適用できる機能等があるため、製作時の効率化を図れるってのがウリ。
クラスからインスタンスを生成するのが生業のエンジニアから見れば、プレハブが凄いと言われてもそこまで大したことでは無いような気もするのですがそれは置いといて。
GUIからの操作が簡易になるという点では良い機能です。

一番簡単な作り方はこちら。

Prefab化したいGameObjectをヒエラルキーから選択
そのままぐぐっとProjectへ、、、、
はい完了!こっから逆にドラッグすればインスタンス化です。
一旦ProjectにPrefab作るとかいう手段もありますが、これが単純です。
実行前の作業であるため、スクリプトを使用したプレハブ化はできません。
プレハブからインスタンスを生成するのはスクリプトからもできます。
また、プレハブ自身のクラスも存在しません。

こういった便利なツールにおいて、コードだけで書き上げることは困難ですね。
GUIの便利さとトレードオフになってしまうでしょう。

実はこのプレハブ、開発作業時にエンジニアとかUI担当とかで考慮しなければならないことがあるのですが、それはまた次回。

2011年10月25日火曜日

refで渡す引数が見当たらず

横道にそれますが、気になっていた点をひとつ。

今更ですがUnity公式リファレンスのリンクはここです。

http://unity3d.com/support/documentation/ScriptReference/

で、使用可能なクラスや構造体等の一覧は1つ下がってここ。

http://unity3d.com/support/documentation/ScriptReference/20_class_hierarchy.html

これらを見て気になっていたこととは、

「引数が全て実体渡しになっている、、、、」

です。

もともとC#には実体型と参照型があるため、生成時にそれらの違いが出ます。
組み込み型的なint等は当然実体ですが、構造体やクラスは参照です。

これが問題となるのは関数への引渡しの時。
型の振る舞いが決まるのは生成時だけとは限りません。
C/C++屋なら常識ですが、馬鹿でかいオブジェクトを単純に渡せば、関数の中で新たにメモリが生成され、生成時の負荷でも無駄コストになってしまい、場合によっては思った通りの動作になりません。
C++等の詳細仕様を見れば型そのものの概念と、引数になる際の振る舞いは厳密に分けられており、その動きは明確です。

C#では関数の引数として扱う際は基本実体渡しです。
アドレスのみを渡すならrefを、戻すならoutを付随させなければなりません。
これも言語仕様として決められているようです。
フォーラムでたまにそのへんの質問が出ているのを見ますが、回答者すらよくわかってないのか、クラスは生成時に参照なんだから決まってるだろ的なリプライがあったりして本当に困るところ。

しかしUnityのリファレンスには参照が有りません、、、。
例えば以下のコード。

Vector3 vec = transform.localScale;
print(Vector3.Scale(vec, new Vector3(2, 2, 2)));

自分のスケールを取り出して2倍にしてそれを表示という内容です。
このScaleはクラスメソッドで、以下がそのリファレンス。

http://unity3d.com/support/documentation/ScriptReference/Vector3.Scale.html

やっぱりrefはどこにもない、、、。
実際、上の2行目のvecをref vecとかするとエラーが出ます。
じゃあUnityはそんなに無駄な事をしてるのかというと、全てがそうかはまだ疑問。

勝手にref扱いしてるものがないかどうかは現在検証中。

2011年10月24日月曜日

子GameObjectに順次アクセス

以前の回では、他のGameObjectにアクセスする方法を色々書きました。
その関係でちょっと追記というか補足。

ゲームを作っていくと、GameObjectはバラバラに存在するというケースはさほど多く有りません。
実際は階層構造になっていて、それをまとめる大きなものが何個かあるはずです。
別にでかいケースだけではなく、簡単な場合でもよくあります。
例えば、動きまわるキャラを作ったとして、そいつが武器や装備を持ってパワーアップするとします。
銃を撃つときにその銃が光ったり反動を表現したりリロードしたりとか、いろいろあるはず。
それが自分じゃなくていっぱい居る敵だとしたら、GUIから指定するにも結構たいへんです。

そう考えると、必ず入れ子のGameObjectがあって、自分の子にアクセスするというケースが出てくるでしょう。
そんな時にはどうするかというと、、、、。

以前書いたGUIからの指定やFind、これはもう説明しました。
今回はTransformを使った入れ子へのアクセスです。
これがサンプル。

Transformはparentメンバを持っているのですが、さらに子供も持つという二重アクセス構造。
それを利用し取り出すことができます。
foreachができるのは、IEnumerableを実装しているため。
イテレータとして順次取り出せるので、後はタグ付なり名称付なり、取り決めを自分で行うことで、判断させることが可能です。

しかしforeachを毎回させれば遅くなるのは当然。
動的に生成破棄するゲームであっても、こういう事をしなくていいように、予めメンバ変数に設定しておいてその分のコストを減らすようにするのが普通かと。

2011年10月21日金曜日

GameObjectに複数のMonoBehaviour

GetComponentの使い方でもう一つ。

以前、GameObjectには複数のスクリプトを追加可能と書きました。
じゃあそれがなんの役に立つかという一例を紹介します。
例えばファクトリーやマネージャクラスなど、全体に絡むクラスが何個がある場合を想定しましょう。
ゲーム内部で目に見えなくても仕事をする必要があるクラスですね。
実際、現場ではこういったクラスの方が重要です。

この時にあの書き方が生きてきます。

これらを一個ずつ丁寧に別々のGameObjectに追加するのもいいですが、せっかくまとめられるのならばそうしたいところです。
ということでサンプルがこちら。

上記のコードは2つ分くっついてますが、上記の2つをそれぞれC#で生成し、一つのGameObjectに紐付けしてください。
やってることは単純、Test1及びTest2で互いの関数をコールしているだけです。
結果は書くまでもないほど簡単ですな。

ここでのポイントですが、自分以外のスクリプトを取り出すのに、自分自身に対してGetComponentしている部分です。
いちいちpublicにしてGUIで紐付けしたり、Findしたりという手間が省けますね。

これなら一つのGameObjectをスクリプトホルダーとして機能させられます。
構造的も簡潔になるので言うことなし。

また、スクリプトを取得する際、GetComponent<クラス名>()でテンプレート変換している点も注目。
ソースコード上でもすっきりと書けます。

2011年10月20日木曜日

他のMonoBehaviour派生クラスへアクセス

オブジェクトの探し方ができたところでプロパティの続き。
以前の回で書いたGetComponent()を使うとスクリプトにもアクセスできます。

そこで今回は自作スクリプトのメソッドを呼び出してみましょう。
要はMonoBehaviour派生クラス同士のメンバアクセスです。
これは開発を始めると常に行うことになるはずで、今回は実行時に生成破棄等の変更がない場合の方法を書いてみます。

では以前使用したC#スクリプト2個を再利用して実験です。
以下が再利用クラス。

  • BaseScript
  • InheritScript

これに仮想関数Func()を追加し、派生側でオーバーライドしときます。
ついでに以前のStart()を外します。
以下のコードは2つ分がくっついてるので、分けて実装してください。
 

余談ですが、StartやUpdate等はあくまでUnityFWが制御するものなので、自前での呼び出しは自己責任で。
逆にクラスに書かなければ何も起きません。

さらに呼び出しテスト用C#スクリプトを1つ作成します。
こちらはTargetScriptとしました。

このクラスの役目はbaseObjとinheritanceのFunc関数を呼び出すだけです。
が、それでは説明にならないのでコードを簡単に解説。

まず、自作スクリプトがProjectビューの中にあるのなら、上記のようにそのままスクリプトクラスの変数を宣言可能です。
自作スクリプトは基本的にMonoBehaviour継承。
MonoBehaviour派生クラスは、GUIの操作によってGameObjectに紐付けされます。
従って、スクリプトにアクセスする場合は、GameObjectを検索等で見つけ出し、紐付けされたスクリプトインスタンスを取り出して関数呼び出し、という形になります。
なお、GetComponent("")の形式はComponent型を返すので、上記コードではダウンキャストして型変換を行なっています。


で、作成したら、UnityGUI上でメニューから「GameObject」→「Create Empty」を選び、3つオブジェクトを作成してください。
それぞれ以下のように命名と紐付けをしましょう。
  • GameObjet1 (BaseScriptに紐付け)
  • GameObjet2 (inheritanceScriptに紐付け)
  • GameObjet3 (TargetScriptに紐付け)
こんな状態にしましょう
しかし上記の紐付け状態だと、コンソールに赤い文字でエラーが出てしまいます。
すぐにはでなくても実行時にはエラーになります。
これはTargetScriptのメンバ変数x2の中身が無いのにメソッド呼び出しをしようとしているために出ている訳です。
そこでGameObject3を選択し、前回の記事で書いたドラッグ&ドロップで以下の紐付けをしてください。
  • baseObj (GameObject1)
  • inheritance (GameObject2)
これで実行前にメンバが確定され、エラーが消えます。
さて、実行するとどうなるでしょうか。


はい、アクセスできていました。
継承構造にも注目しておいてください。
基底クラスを紐付けした方はちゃんと基底クラスのメソッドが呼ばれています。

2011年10月19日水曜日

別のGameObjectにアクセス

Component詳細の前にGameObject検索に横道。
今までの例では、スクリプトに割り当てられたGameObjectを触っていました。
そして紐付けはUnityのGUIからドラッグ&ドロップだったため、実行前に決められていました。

じゃあ実行時に別のGameObjectを、、、という場合はどうでしょう。
複数方法がありますが、代表的なものがこちら。
  • 実行時にFindで検索
  • publicメンバにして実行前に紐付け
前者は速度的には厳しいですが、動的な生成破棄をするなら必須です。
後者はオブジェクト指向的に問題なのと、GUI操作必須ですが高速です。

まずは前者から。
GameObjectのstatic関数、Findで検索が可能です。
宣言はこんなかんじ。

static function Find (name : String) : GameObject

ヒエラルキー上で表示されている名前を入れると検索し、該当すればインスタンスが戻るという仕組みです。
しかしこの名前、GameObjectの最基底クラスであるObjectのnameメンバなのですが、シーン上でユニークな訳ではありません。
実際、シーン上には同じ名前のGameObjectがいっぱい作成できてしまいますし。
プレハブでもそうですが、名称を自力で固有に変更しなければ欲しいインスタンスにアクセスできないのでご注意を。

以下は具体例です。 (公式から抜粋)
このようにヒエラルキー構造を指定して検索を掛けることも可能です。
スラッシュから始まる検索の結果は、「ルートに存在するオブジェクトである可能性がある」と公式には書いてありますが、実際にはルートにあっても階層下にあっても検索できてしまいます。
/Monster/Armのように階層が深くユニークなら実質問題ないようです。

他にも手はあって、タグを利用した名前付けで検索することも可能です。

static function FindWithTag (tag : String) : GameObject

これもまたユニークというわけではないので自力で設定しましょう。
なお、遅いと言いましたが、Update()で書いたりすると恐ろしく遅くなります。
Awake等で検索し、自前メンバに保持しておくのが一般的です。


長くなりましたが続いて後者。
上記のコードでGameObjectのhandがpublicになっています。
オブジェクト指向の世界で、何も考えずにメンバをpublicにすることは通常ありません。
が、こうしておくと、Unityのインスペクタにそのメンバが表示されるようになります。
以前この値をGUIから変更可能と書きましたが、クラスメンバの場合はここから静的にインスタンスを指定することが可能です。
要は、Findでやることを実行前に確定させるだけの事。
反則感はありますが、これも推奨のようです。

そしてそのやり方は簡単。
publicなクラスメンバを持ったスクリプトをGameObjectに紐付けます。
そのGameObjectを選択すると、インスペクタのスクリプト欄にそのメンバが出ます。
ヒエラルキーからドラッグ&ドロップで終了。

未設定ならNoneに、入ってれば名称がでます。上書きもおk

なお、マテリアル等ならプロジェクトビューからでも紐付けできます。

2011年10月17日月曜日

GetComponentでプロパティ

前回はTransformを取得して位置移動を行いました。
位置以外にも様々なComponent派生クラスを保持可能になっています。
また、Componentは必要に応じて脱着できるため、存在していない場合それらのメンバ変数はnullとなります。
(TransFormだけは外すことができませんが)

プロパティの形で保持しているこれらを別の方法で取得することも可能です。
以下の例を見てみましょう。
これも今まで同様にC#コードとして生成したものです。

Transformインスタンスが4個取得されていますが、これはどれも同一のインスタンスが取得されることになります。

一番上はMonoBehaviourのメンバ変数ですが、これはアタッチされたGameObjectのTransformが自動的にバインドされます。
2番目はアタッチされたGameObjectのインスタンスであるgameObjectメンバ変数(頭文字の大小に注意)から同様に取り出してます。
つまりはこれも1番目と同様です。

3番目はGetComponent関数を使用して取得しています。
<>の間にはTypeが入りますが、Unityで準備されたComponent派生クラスなら""成しで指定するものと考えてください。
実行速度的にはプロパティ呼び出しの方が上なのは当たり前ですが、1回2回の呼び出しなら差は微々たるものです。

で、4番目ですがこれはエラーとなります。
JavaScriptでは""(ダブルクォーテーション)抜きで指定できていましたが、この方法では呼び出せません。
3番目はテンプレートとして型変換まで行なってくれるのですが、この方法では単にComponent型のインスタンスポインタが戻ってくるため、Transform型へのキャストでエラーとなる訳です。

ではどうするかというと、以下のようにしてください。
VBライクなas 型名か、Cライクな(型名)どちらでもお好みでどうぞ。
ただ、上記コードでは両方あると二重定義エラーとなるのでご注意を。

実はGetComponent()ではインスタンス的にはきっちりTransformが帰ってきていますが、Componentクラス型のままなので、派生クラスであるTransform型にダウンキャストしなければなりません。
それが上記の記述方法です。
本来ダウンキャストは望ましく有りませんが、型が完全に確定している場合は問題ありません。 
前回の位置変更サンプルの取得方法をこれにしても動作します。

この呼び方は一見無駄に見えますが、実はこの呼び方にも意味があります。
それはまた次回以降で。

2011年10月14日金曜日

UnityのComponent操作

Unityでゲームらしいことをする場合、コード側では何をすればいいか、という話をしてみます。
本やブログで色々説明はありますが、自分なりの表現で噛み砕いて見ました。

普通、ゲーム製作者やユーザ観点では、キャラがいて弾撃って移動して、ボスがいて、当たったらどうこう、、、とかいう話になると思います。
しかしそれは仕様とか画面上の話。
システム的な観点で抽象的に言えば、オブジェクトの「プロパティ」が変化するということです。
ざっと言えば以下のような感じ。

 ・生成、消滅
 ・位置移動、回転
 ・3Dアニメーション
 ・テクスチャの変化
 ・etc...

Unityにおける画面上のオブジェはGameObjectです。
以前、GameObjectをスクリプトで操るにはMonoBehaviour派生クラスを作成という話をしました。
が、このMonoBehaviourそのものが機能盛りだくさんという訳ではありません。
以下のリファレンスを見てみましょう。

MonoBehaviour Class Reference
  http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.html

大半の関数はイベントハンドラで、他の動作面では空っぽに近い感じすらあります。
実はこのクラスを成り立たせてるのは、Component派生メンバ変数群。
重要な機能はほぼ移譲する形で構成されています。
例えばGameObjectは入れ子に出来ますが、それさえも自力ではやっていません。
Transformクラスがコンポジットパターンとして実装することで実現してます。

つまりは、オブジェクトの変化を制御したいなら、基本はGameObjectが保持しているComponent派生クラスをいじる、ということになるわけです。
まずは簡単な位置移動をやってみましょう。

GameObjectをひとつ生成し、C#スクリプトを割り当て、インスペクタウィンドウで位置を0,0,0にしてください。

解りづらいですが、0,0,0の位置にGameObjectが存在しています。

位置の管理はTransformクラスが担当し、この中には位置と回転等が入ってます。
ここからVector3というx,y,z情報を持つ構造体を抜き出し、それを変更すると位置が変わります。
以下がサンプルコード。

では解説。

Start関数の開始直後、Vector3変数posをtransform.positionからとっていますね。
(transformはTransformのインスタンスでMonoBehaviourのメンバです)
GameObjectの位置なのに、MonoBeheviourのメンバを取り出すって、、、、と思うかもしれません。
が、実はアタッチされたGameObjectのTransformメンバが自動的に反映されるため、いきなりこういう書き方でいいという訳です。

そしてx:10 y:20 z:30の位置を指定し、positionに戻しています。
できればメンバを直接変更したいところですが、C#ではpositionの内部メンバは個別変更ができません。
取り出して変更して戻すのが基本です。
これを実行すれば以下のようになっているはずです。

位置が変化しました。見た目は変わりませんが。

このように、移譲している関係から、移動に関するメソッドがMonoBehaviourに存在するわけではありません。
メンバを直にいじって変化させるのが基本的な方法です。

2011年10月13日木曜日

Unityのエディタを選ぶ

エンジニアはエディタの好みが別れる人種。
Unityでも快適に実装したいけど、標準でついてくるものはどうにもちょっと具合が悪うございます。
以下は個人的な感想。

MonoDevelop
  機能が多いが重い。メニューの文字化けを直したりとか面倒。
UniSciTE
軽いが機能が少なめ。今一つ使いづらい。

MacだとUnitronが軽めなのですが、それもそこそこな感じ。
窓の秀丸エディタは関連付けが失敗してしまうし。
で、結果落ち着いたのはNotePad++。

NotePad++
http://sourceforge.jp/projects/notepad-plus/

Macな方には残念ですがWindows用です。
実行した感じは以下の様になります。


プラグインも使えるし、細かい色分け等もできるので使い勝手は良さげです。
なにより軽めなのがとてもありがたいですね。

まず上記のアドレスに行くとこんな画面になります。


丸枠をクリックしてください。
次の画面でも丸枠部分をクリック。
あとは自動でダウンロードが始まります。

インスコが完了したら、以下の手順で登録しましょう。

メニューから「Edit」→[Preferences..」で設定ウィンドウ表示。
「Generate」タブで「External Script Editor」をクリックし、BrowseボタンでNotePad++のインスコ先を選択。

これでUnityでも快適にコーディングできます。
なおC#の場合、コメントに日本語が入るソースでは、文字コードをUTF-8(BOM付き)にしないとトラブルが多発します。
jsと混在した日にはさらに大変になるでしょう。
Unityからのバグ通知時の行数すらおかしくなります。

NotePad++のメニューから「フォーマット」→「UTF8エンコード」で指定してください。

2011年10月12日水曜日

MonoBehaviour継承

Unityでは事実上基底クラスがMonoBehaviourみたいなことになっているので、実戦環境では多段継承で実装していくケースもあるかと思われます。
じゃあ自分で作ったメンバはいいけど、MonoBehaviourのメンバはどうやればいいか?を実験してみましょう。

まずはC#スクリプトを2つ作成してください。
メニューから「Assets」→「Create」→「C# Script」です。


基底クラスとなるBaseScript、そこから派生するinheritanceScriptです。

UnityのinheritanceScriptリファレンスを見ても、StartやUpdateが仮想関数だとは書いてません。
JsやBooと共用なので書きづらい部分もあるのでしょうが。
基本FWのソースコードは見れないのでまずは実験です。

出来上がったらメニューの「GameObject」→「Create Empty」で空っぽのオブジェクトを作成してください。
inheritanceScriptだけをそいつにドラッグし、ヒモ付します。


くっついたのを確認したらおもむろに実行してみましょう。


このSSのようになったら成功です。
基底クラスのStartと派生クラスのStartが呼び出されていることが解りました。
なお、他のメンバも同様に仮想関数として扱えます。

2011年10月11日火曜日

MacBookのAC異常

休日にMacBookProで作業中、ふとあることに気づきました。

「あれ、ACアダプタのランプが、、、、、付いてない」

ちなみにMacBookの電源は以下の写真のようなやつ。
Macの電源はこんなかんじ

機種はMacBookPro 13inch 2011でLion化済。

コネクタ部分にはLEDがついてて、未ならオレンジに、満充電なら緑になります。
が、このランプが付く気配がない、、、。
OSのインジケータもバッテリ駆動の状態のまんま。(残量は58%)

こ、これはアダプタ買い直し?
と思ってAppleストアをみたら7,800円。ちょっと高いんじゃ、、、、。

いやいや、まだ故障とは限らないかも、、、と思ってぐぐったら結構困ってる人が多いようで。
で、以下のような公式情報を発見しました。

Intel-based Macs:SMC (システム管理コントローラ) のリセット

なんでも、応答してないアプリ殺してスリープして解除して再起動して終了だそうでw
凄い手順ですねこれ。
一応この手続きを踏んでもダメだったので、本体AC共に30分ほど放置。
そして改めてコンセント入れたらなんと復活!しました。

うーん、なんか微妙。

2011年10月7日金曜日

Unityのインスペクタ

Unityならではの機能として、インスペクタでの変数修正というものがあります。
これはユーザが定義した変数をUI上で調整が可能というもの。
では実際にやってみましょう。



以前のSampleBehaviourScriptにメンバを1個付けてみました。
本来メンバを単純にpublicにするというのはオブジェクト指向ではご法度です。
が、これがUnityでは意味を持ってきます。

これを以前のように空っぽのGameObjectを作成し、ソースを割り当ててみましょう。


すると上の画像の右下、スクリプトの名称の下に新しい項目ができています。
値はコードの初期値として設定した10が入ってますね。

ここからが重要。
この10の部分をクリックすると、なんとそのまま値が変更できてしまいます。
intなら整数に、stringなら文字列を、boolなら真偽を、そのまま変更できます。

この方法の素晴らしい点はただひとつ。
いちいちコードに戻らずとも、移動速度や見え方、その他がこの場で変えられるということ。
つまり、今までエンジニアがコード上でいちいち微調整していたものが、ゲームデザイナやCG屋等、他のメンバに微調整をお願いできるという利点になるわけです。
手戻りに関する点では非常に素晴らしい機能でしょう。

しかし便利なことには必ずデメリットが付いて回ります。
なんとこの修正機能、ソースコードの中身を直接変更するわけではありません。
幾らGUIからいじっても、ソース上の値は先ほどの10.0fのまんまです。
そうなると問題となるのが、規模が大きくなったときと多人数開発の時。

 「これ、何やっても思ったとおりに変更できないんだけど、、、」
 「あれー、いつのまにこんな値になったんだっけ」
 「やべ、前の値忘れちまった」

等々、恐ろしいケースは山ほど出てくるでしょう。
一旦ソースをヒモ付から外して再度付け直せば、値はリセットされます。
が、開発時のルールを厳密化しないと混乱は必至でしょう。

うまくつかってこその機能ではないかと。

2011年10月4日火曜日

Unity本2冊追加

和訳本追加。

Unityマスターブック―3Dゲームエンジンを使いこなす
http://booklog.jp/asin/4877832750

Unity入門 ~高機能ゲームエンジンによるマルチプラットフォーム開発~
http://booklog.jp/asin/4797365331


前者は個人的に新しい情報が少ないような。
しかし代わりにTerrain(地形)に関する情報が多めに載っていました。
後者はスマホ考察やゲームを作る上での実践的な例が多く記載されています。

ということでエンジニア向けという話なら後者の方がややお勧め、、でしょうか。

2011年10月3日月曜日

C#でモノビヘイビア

前々回の記事の続き。
C#でGameObjectの振る舞いを記述するクラスのひな形はこうなります。
名前は前々回作成したSampleScriptにしてあります。

JavaScriptの場合、いきなり地べたにStartとUpdateが書かれるのですが、こちらはクラスの様相を呈してます。
Js版のサンプルではpublic,private等のアクセスコントロールが結構いい加減なものが多いのですが、C#では当然きっちり書かないといけません。

1.Startメソッド

まずStart()から解説。
これはUpdateの前に1回だけ呼び出されることが保証されています。
実は、Unity3Dではコンストラクタ・デストラクタは推奨されていません。
書けることは書けますがタイミングや順序等に保証は一切ありません。
従って、普通に書くならこれがコンストラクタ扱いと考えて良いでしょう。

しかしさらにUnityにはAwake()という関数もあります。
これはシーンとその配下のGameObjectが初期化完了する前に呼び出され、順番の保証も有りません。
変数のみの初期化ならAwake、他のオブジェクトを取得したり情報を見たり設定するならStartと考えればおkかと。
何も考えずStartに全部書くのも簡単です。

2.Updateメソッド

続いてUpdate()。
これは実行中に毎フレーム呼ばれる関数です。
普通に使うならこの中に判断と動きを書くことになるでしょう。

が、UnityにはFixedUpdateという関数も存在します。
こちらは厳密に毎フレーム呼ばれるもので、解説書には重力等の制御用機能である「RigidBody」を使用するならこちらを使ったほうが良い、と書かれています。
常に一定の力を与えるケースに使われます。

っていうか、3Dで重力計算を期待してわざわざUnityを使うのだから、FixedUpdate一択?と思うかもしれません。
が、実際はそうでもないのです。
時間を表すTimeには前回のフレームからの経過秒数を示すdeltaTimeというメンバがあります。
負荷軽減にもフレームレート非依存コードの記述のためにも、UpdateとTime.deltaTimeはよく使うことになるはずです。
派生先における特化処理の記述等、普通のC#ライクに使用出来ます。

今回はここまで。


2011年10月2日日曜日

LionでChromeが応答なしになる件

Unityを使う傍ら、Chromeは常用しております。
会社と自宅等で複数PCとのブックマーク同期、速度、拡張機能、その他もろもろ。
しかしこいつが調子悪くなってしまいました。
環境はMacOSのLion。バージョンは14.x。

最初は同期に手間取ってるのかと思いきや、起動直後から必ずマウスが虹色の回転モード。
Option+Command+Escで見ると必ず「応答なし」。工エエェェ(´д`)ェェエエ工
窓ならCtrl+Alt+Deleteで見ても同じってことになるのかと。
Macの場合はユーティリティのアクティビティモニタで見れば、タスクマネージャライクな詳細が見れるのですが、これも同じ。

Macのタスクマネージャはこんなの
安定版を使用していたので、じゃあベータ版ならどうだろうって上書きインストールしてみたけど全然ダメ。
プロセスの1つ、Chrome HelperはCPU食いだって話も聞くし、うーん。

めんどくさいので今回はまるごと削除することにしましょ。
ってなことで「App Cleaner」を落としてきました。
バックアップ機能とかはないので、同期ができるChrome向けです。

完全にChromeが死んでる状態(出来ればOS起動直後)で、これを実行し、左上の「アプリケーション」をクリックしましょう。
すると一覧がでるので、Chromeを探し「検索」をクリック。
これでChrome本体だけでなく、悪さをする可能性があると思われる関連ディレクトリ、ファイル群を根こそぎ探してくれます。
窓ならレジストリまで検索してくれるクリーナってところですね。

これが検索で出てきた一覧。
全部綺麗さっぱり削除して、再度Chromeを入れなおして完了。
これで無事Chromeが起動してくれるようになりました。
同期とかはやり直しですが、クッキーも含め全部同期ができるChromeならではの対処方法かと。

調子がわるい方は一度お試しあれ。

2011年9月30日金曜日

モノビヘイビア

昨日の記事の続き。

エンジニア側からすれば、昨日紹介したクラス制御が仕事のメイン。
つまりMonoBehaviour派生クラスの実装が作業の中心となります。

しかしGUI型ツールの宿命というべきか、要所要所でGUIを触るという作業が必ず入ります。
スクリプトオンリーでFWと対話し、ゲームを作るのは困難なように思えます。
共同作業が当たり前のこの世界ならなおさらでしょう。

ということで、Unityはまだまだ発展途上。
ぐちってもしょうがないのでMonoBehaviour派生クラスの作り方からいってみましょー。
昨日いきなりクラス図を出した反省を込めてw、スクショ付きです。

あ、レイアウトは好みによっていろいろ変えられます。
これはあくまで一例なので、読者さんの環境と相違する場合もあります。

Step1. ソースの生成

Unity上にProjectというタブがついたエリアがあります。
そこをクリックするとメニューが出るので、「C# Script」を選択。
あちこちでJavaScriptの例ばっかなので、このブログではC#オンリーとします。
ちなみにこれ、メニューのAssets->Create以下の構成と同一です。

Step2. 名称変更中

Step1を行うと、名称が変更できる状態で「NewBehaviourScript」という項目が出ます。
このまま確定するとこの名称のクラスができますが、実はこの状態で名称変更をすると、クラス名まで一緒に変更してくれます。
大抵の言語では当たり前ですが、ファイル名とクラス名は一致しなければなりません。
間違えてNewBehebiourScriptで確定してから変更しようとすると二度手間。
なのでこの時点で変更すると楽ですな。

Step.3 名称確定


今回は「SampleScript」としてみました。
本来なら名が体を表すように付けるのが基本ですがサンプルなので。

ここで注意点がひとつ。
実はUnityのProjectツリーはOS上のディレクトリ構成を表示しているだけです。
言い換えるとファイルエクスプローラ or Finder or ファイラー。
各シーンで使用する可能性がある、単なるリソース格納庫のビューアです。
Ctrl-Zを何度押そうが、Undoは効きません
代わりに、ファイルエクスプローラ等でこのディレクトリにファイルを入れたり削除しても、そのままUnity上に反映されます。

Step.4 GameObject生成

Unityは常になんかしらシーンが存在というか表示される状態になってます。
空っぽのプロジェクト作っても同様です。
ではこのシーン上に空っぽのGameObjectを生成してみましょう。
SampleScriptが振る舞うための宿主が必要ですからね。


メニューのGameObject->Create Emptyを選択。
これで「Gameobject」という名のGameObjectが生成されました。
これだけだと、こいつにはTransformコンポーネントしかついていません。

Unityの概念はFlashに結構似ていて、シーンにあるものは実行時にインスタンスになるべきものを予め配置しておく形になります。
したがってこの手順で生成すればそのまま実体が確定というわけです。
有名なプレハブという概念もありますが、エンジニア向けの解説はまた今度。

Step5. 紐付け


昨日の記事で、GameObjectとの関連付けを手動でと書きましたが、ここがそれです。


スクショには写ってませんが、SampleScriptをHierarchy上のGameObjectにドラッグ&ドロップしてください。
行なってもダイアログも何も出ませんけど。
結果がこちら。


右端に見えるインスペクタが変化しています。
紐付けされた証に、SampleScriptの文字が見えますね。
これでGameObjectはSampleScriptで振る舞いを表現するようになりました。
この順番は、実装してからでも、先でもどっちでも構いません。
要はヒモ付してからもガリガリ変更を記述できるということです。
変数に注意点がありますが、それはまた今度。

注意点としては、1つのスクリプトに同じものでも別のものでも、複数個紐付けできてしまうという点。
ダイアログも何もでないのが不親切ですね。
ちなみに紐付けを外すなら、この変化した部分にある歯車をクリックして「Remove Component」で削除できます。

これで紐付けができました。
この組み合わせで使っていくのが基本になります。

2011年9月29日木曜日

最低限把握すべきクラス

Unityのゲーム制作は非常に簡易です。

実行時画面をシーンという概念で扱い、その中で動くのはGameObjectインスタンス。
GameObjectにはプロパティライクなComponent群が存在。
コンポジットパターンでルートからツリー構造を形成。
エンジニアならこれだけでも想像できるのではないでしょうか。

巷の紹介では、UI操作手順のスクショ付き解説が殆ど。
しかし同じでは詰まんないので、いきなり簡易クラス図を出してみましょうw

MystliveがCacooで描いた簡易クラス図です

一応Unity公式にはリファレンスがあります。
しかしFWのソースはユーザが取り出して見ることはできません。
UMLも見当たらないので、重要な部分のみを自力でざざっと描いたのがこれです。
結構省略&いい加減なので細かいところは突っ込まないでください。

んでは、ざっくりと解説。
普段使っていく上で、黄色のクラスが肝です。

先ほどの解説通り、シーン上で実行時に動くのはGameObject。
これ単体では描画機能すら有りません。(位置情報のTransformだけは最低でも付きますが)
で、テクスチャやコリジョンやメッシュ描画やら色々付けることが可能で、それらの組み合わせでオブジェとしての表現を成します。
GameObject自身は親子機能が無く、Transformがコンポジットになって親子付け。
位置情報がくっつくので、パーツをまとめたりアイテム持ったり等の表現ができます。

GameObjectの振る舞いを書くならMonoBehaviourを継承し実装。
基本的には書いたらGUI上で紐付けしなければなりませんが。
実装にはJavaScript、C#、Booどれでも使用可能で混在もできますが、混在してトラブルに何度もあっているので、速度面も兼ねてC#統一がお勧めです。
(しかしUnity謹製サンプルは全てJsという罠)

長いのでとりあえず今日はここまで。

2011年9月28日水曜日

Unity使用中でござる

実は最近仕事でUnity使ってます。
Unityとは一言で言えばゲーム制作ツール。
基本無料で3Dバリバリで凄いレベルのゲームが作れるっていうシロモノです。
金出すとスマホやコンシューマにも吐き出せます。
FWが吸収するので移植も簡単。

今まで英語資料か人様のブログしかなかったのですが、やっと和書も出てきました。
開発にあたって私が読んでみたのは以下の本。
リンク先はブクログです。アフェじゃないのでご安心を。

Creating 3D Game Art for the iPhone with Unity
http://booklog.jp/asin/0240815637

Beginning 3D Game Development with Unity
http://booklog.jp/asin/1430234229


Game Development With Unity(10月に和訳が出る予定)

Unityによる3Dゲーム開発入門
http://booklog.jp/asin/487311506X

上記は入門用としてはどれもなかなかでした。
なお、普通の記事は結構あるので、ここではエンジニア向けの内容を書く予定。
C#でのTips中心になるかと思います。