ひさしぶりに うにばな です。 もう毎日暑くてパソコンも機嫌が悪いんですけど 急ピッチでゲーム作成作業しています。
前回お話したDota系ゲームの進捗ですね。といってもまだ機能を実装するとこまではいかなくて 仮のグラフィックデータがはいっただけなんですけど せっかくなので訪問してくれている人にも見ていただこうと思いまして Webサンプルをおいてみます。
マウスでキャラクタを選択して左ボタンで地形をくりっくすると移動します。右ボタンでキャラを選択すると魔法が出ます。 ミニマップ上の白いフレームをマウスでドラッグするとカメラが移動します。カーソルキーでも移動できます。 スペースバーでキャラクタのセンターにカメラが移動。Pキーでショップ画面がひらきます右上の?でウィンドウが閉じます。
完成まではまだまだかかりそうですけど システム的なものはもとになるゲームがあるので とりあえずクローン化して その後にオリジナル要素として展開していこうかなーと考えています。
『Unity3D LOD』で検索された方がいましたのでLOD について解説します。
LOD(Level of Detail)は距離に応じてモデル(メッシュモデル)のポリゴン数を切り替える動作のことを指します
ゲーム中でポリゴン数が少ない場合などはいいのですが モデルが複雑になったり 大量のモデルを表示しなければならない場合に
見えにくい位置のモデルポリゴンは減らしたいわけです。 そうした場合にあらかじめポリゴン数の少ないモデルを用意しておいて
カメラからの距離に応じて切り替えることで レンダラーの描画の負担を減らそうというわけです。
背景の場合Unity3.0から搭載されたオクルージョンカリングなどでカメラに映らない位置のモデルは描画を省略することができます。
またTerrainの場合プロジェクトのグラフィックのクオリティ設定により遠方のモデルは自動的に描画を省略されるなどと処理軽減の
期待はあるのですが、キャラクタモデルに関してはLOD処理をしてやらないと負担軽減になりません。
特にスキンモデルなどはウェイトがはいっているうえにテクスチャも大きめなものが貼られるためポリゴン数を減らすことは
非常に描画処理に効果的です。 背景にももちろん有効ではあるのですが いまどきのハードで背景にLODを仕込む程重いっていうのは ゲームの仕様ミスなんですけどねw
で いちおうリンク先に参考になりそうな簡易的なLODマネージャーがあったのですけど 少々複雑な構造なので
説明のために簡単なスクリプトを書いてみました"LODManager.js"
http://www.unifycommunity.com/wiki/index.php?title=Simple_LOD_Manager
http://m2h.nl/files/resources_LODmanager.html
"LODManager.js"/////////////////////////////////////////////////////////////
var Distances0 : float;
var Distances1 : float;
var LODModels0: GameObject;
var LODModels1: GameObject;
var LODModels2: GameObject;
private var myTransform:Transform;
function Awake(){
myTransform=transform;
}
function Update() {
var dist:float =Vector3.Distance (Camera.main.transform.position,myTransform.position);
if(dist <= Distances0) {
LODModels0.SetActiveRecursively(true);
LODModels1.SetActiveRecursively(false);
LODModels2.SetActiveRecursively(false);
}
else if(dist <= Distances1) {
LODModels0.SetActiveRecursively(false);
LODModels1.SetActiveRecursively(true);
LODModels2.SetActiveRecursively(false);
}
else {
LODModels0.SetActiveRecursively(false);
LODModels1.SetActiveRecursively(false);
LODModels2.SetActiveRecursively(true);
}
}
Camera.main は現在アクティブになっているメインカメラのカメラオブジェクトを指定しています
Awake()文は初期化なのですが、LODモデルの親になるtransformをmytransformというローカルな変数に一度移しています
これはUnityの高速化手法としてこのようにしてやることで実行速度があがるという解説がなされています。
そしてやっていることは難しくなくてメインカメラからの距離に応じてモデルを表示するだけなのですが
wikiのほうの参考例はモデルの格納を配列にして細かいLODに対応できるようにしている拡張版なのですが
基本LODはあまり細かくもつと管理が大変で一定以上離れると見た目的には効果が薄いため3レベルもあれば十分だと思います。
2番目のリンクはMeshFilterを使用してポリゴンメッシュのモデルだけをいれかえるものです。
動作は似た感じなのですが wikiの例に使用されている SetActiveRecursively()はモデルの下の子供まで全てを非表示にする関数なので
たとえば武器を子オブジェクトにもたせたモデルなどを一気にローモデルにすることができるので応用が広いです。
今回の例ではSetActiveRecursively()の方を採用しました。スクリプトはかっこよく好きなように書き換えて使用してください。
ほかにも検索されたものに『Unity3D 絶対表示』なんていうのがあったんですが、なんでしょうね絶対表示って これで検索にひっかかるものなのでしょうかw よくわからないんですけど 常に手前に表示させる方法ならあります。
カメラのインスペクタですけどDepthという項目があります メインカメラのDepthよりちいさな値にしてメインカメラと同じ座標にメインカメラの子にするかまたは空のGameObjectの下の子としてメインカメラと作成したカメラを両方おいてやります。 そしてCullingMaskで表示させたいオブジェクトを除外します。メインカメラの方は手前に表示させたいオブジェクトをカリング対象に含めます。 これを応用するとポリゴンでメーターなどの表示物を作成したときに常に手前に表示することができます。 カリングマスクに使用するのはレイヤーですから気をつけてくださいね。
という感じでいかがだったでしょうか ひさしぶりの ”うにばな”でした
講座みたいなもの4回目 今書いてますので次回更新します。

