VR、ゲーム制作、プログラミング。Unity とか Oculus Rift とか。

2012年6月24日日曜日

[Unity]NGUIで画面サイズに合わせる

2012/8/24 追記 : 以下、おいそぎの方は [Unity]NGUIで画面サイズに合わせる(その2) の方がおすすめです。


NGUI で複数解像度対応のために、画面サイズに合わせて拡大縮小するスクリプト。

Panel に追加して、インスペクタで Base Object に画面サイズの基準となる GameObject (例えばデフォルト 1280*720 で作っているなら、そのサイズの GameObject) をドラッグ&ドロップすれば使えます。

using UnityEngine;
using System.Collections;

public class ScreenScaler : MonoBehaviour
{
    public GameObject baseObject;
    public bool aspectFit = true;
    
    void Update(){
        Vector3 ratio = new Vector3(
            Screen.width / baseObject.transform.localScale.x,
            Screen.height / baseObject.transform.localScale.y,
            1.0f
        );
        
        if(aspectFit){
            if(ratio.x > ratio.y){ ratio.x = ratio.y; }
            else if(ratio.y > ratio.x){ ratio.y = ratio.x; }
        }
        
        transform.localScale = ratio;
    }
}

起動中に画面サイズの変更がないなら、Update() でなく Start() でやってしまったほうがよいです。

Aspect Fit = true だと異なるアスペクト比のディスプレイで上下か左右が余ります。この部分の塗りつぶし色を変更したい場合は、Camera の Clear Flags を Solid Color にして Background で色を選択すれば OK です。

なお、localScale の setter の内部実装 (INTERNAL_set_localScale()) によっては、もしかすると 21 行目を

if(transform.localScale != ratio){ transform.localScale = ratio; }

と書いたほうが効率がよいかもしれませんが、小さなプロジェクトで試した範囲では違いは見られませんでした。

また、あくまで拡大縮小ですので、絵がつぶれたり粗くなったりしてしまいます。これはミップマップや HD 用画像を用意するなどして別途対処する必要があるかもしれません。


画面を引き伸ばさずに、UIAnchor + UIStretch で対応する場合の説明は NGUI 公式のドキュメント ( NGUI Example: UIAnchor » Tasharen Entertainment ) にあります。

参考:
Unity Script Reference - Transform


2012/8/24 追記 : [Unity]NGUIで画面サイズに合わせる(その2) を書きました。

2012年6月19日火曜日

[Unity]NGUIのDepth設定

Unity&NGUIはじめました

これまで、フルスクラッチでマルチプラットフォーム対応の2Dゲームエンジンを作ろう!と細々やってきたりしたのですが、多少は動くけどまだまだ時間かかるな、というところで 3D ゲームエンジン Unity とその 2D 用プラグインの一つ NGUI に出会ってしまったのでした。
  • マルチプラットフォーム対応
  • スクリプト言語利用可
  • ネイティブコードも利用可
  • 必要に応じて拡張可
  • 開発するゲームのジャンルにとらわれない
 と、自分で作ろうとしていたものがほぼカバーされてしまっているようだったので、名残惜しい気持もありつつも  Unity&NGUI に乗り換えてみることにしました。

NGUI の Depth 設定

さて、NGUI でスプライト同士の前後関係は通常 UIWidget の Depth で決まるのですが(大きいほど手前)、この順序関係が適用されるのは同一の Atlas を利用したスプライト間だけで、異なる Atlas を利用したスプライト同士では Depth 通りの順序になりません。

異なる Atlas を利用したスプライト同士の順序を決めるためには、Depth ではなく Z 座標を使います(小さいほど手前)。(2012/7/4 追記 : Z 座標の平均値依存という妙な挙動でした。詳細は [Unity]NGUIのDepth設定その2(複数Atlas) に書きました。)

…というのは公式の NGUI Tutorial: Step 2 に普通に書いてあるのですが、NGUI をいじってみる前に流し読みして分かったつもりになっていたので見逃してしまっていました。

ただ、Z 座標を操作すれば異なる Atlas を利用したスプライトを混在させられるものの、Atlas を増やすとその分だけ DrawCall が増える -> モバイルでの動作が厳しくなるようなので、なるべく一つにまとめたほうがよさそうです。

DrawCall を増やさずにリソースを分割したりできるか、逆に何も考えずにひたすら一つにまとめていいのか、などはまだ調査中です。

ちなみに、Atlas 用画像の生成にはテラシュールウェアさんで紹介されていた TexturePacker が便利でした。


2012/7/4 追記 : [Unity]NGUIのDepth設定その2(複数Atlas) を書きました。
2012/7/6 追記 : 体裁など微修正。

2012年6月12日火曜日

Hello, World!

Android の Blogger アプリから初投稿。

Blogger - GooglePlay Store

Android の標準ブラウザや Sleipnir ではブログ本文が入力できなかったので導入テスト中。