2013年5月26日日曜日

Unity TIps #48 - インスペクタのリフレッシュ

前回に引き続いて Unify Community からインスペクタのリフレッシュに関する Tips の翻訳を紹介する:



http://wiki.unity3d.com/index.php/Tip_of_the_day
Jan 2013


Tip #48 Refresh Inspector


インスペクタのリフレッシュ


最近、Editor クラスの外からインスペクタを強制的に再描画するスクリプトを書く必要があった。考え付いたソリューションは全ての選択されたオブジェクトで SetDirty をコールすることだった。インスペクタは次に変更を拾って、自身をただちにリフレッシュした。
このコードは Unity 4 で動作するとはいえ、ハックの一種なのでもっとより良い方法でインスペクタを再描画させる方法はあるかもしれない。

var objects = Selection.GetFiltered(typeof(GridMap), SelectionMode.TopLevel);
foreach (var o in objects)
{
    EditorUtility.SetDirty(o);
}
-----

今回もシンプル!意外と単純な解決策はあるもんだ・・・

Unity Tips #49 - レンダリング境界の表示


前回に引き続いて Unify Community からレンダリング境界の表示に関する Tips の翻訳を紹介する:



http://wiki.unity3d.com/index.php/Tip_of_the_day
Jan 2013

Tip #49 Visualizing Render Bounds

レンダリング境界の表示

次の C# スクリプトによりレンダリング境界を表示します。ゲームオブジェクトにアタッチすれば、そのゲームオブジェクトおよびその子オブジェクトのレンダリング境界を表示します。デバッグに便利です!



  public class RendererBoundsGizmo : MonoBehaviour
    {
        public bool ShowCenter;
 
        public Color Color = Color.white;
 
        public bool DrawCube = true;
 
        public bool DrawSphere = false;
 
        /// <summary>
        /// When the game object is selected this will draw the gizmos
        /// </summary>
        /// <remarks>Only called when in the Unity editor.</remarks>
        private void OnDrawGizmosSelected()
        {
            Gizmos.color = this.Color;
 
            // get renderer bonding box
            var bounds = new Bounds();  
            var initBound = false;
            if (CBX.Utilities.Helpers.GetBoundWithChildren(this.transform, ref bounds, ref initBound))
            {
                if (this.DrawCube)
                {
                    Gizmos.DrawWireCube(bounds.center, bounds.size);
                }
                if (this.DrawSphere)
                {
                    Gizmos.DrawWireSphere(bounds.center, Mathf.Max(Mathf.Max(bounds.extents.x, bounds.extents.y), bounds.extents.z));
                }
            }
 
            if (this.ShowCenter)
            {
                Gizmos.DrawLine(new Vector3(bounds.min.x, bounds.center.y, bounds.center.z), new Vector3(bounds.max.x, bounds.center.y, bounds.center.z));
                Gizmos.DrawLine(new Vector3(bounds.center.x, bounds.min.y, bounds.center.z), new Vector3(bounds.center.x, bounds.max.y, bounds.center.z));
                Gizmos.DrawLine(new Vector3(bounds.center.x, bounds.center.y, bounds.min.z), new Vector3(bounds.center.x, bounds.center.y, bounds.max.z));
            }
 
            Handles.BeginGUI();
            var view = SceneView.currentDrawingSceneView;
            var pos = view.camera.WorldToScreenPoint(bounds.center);
            var size = GUI.skin.label.CalcSize(new GUIContent(bounds.ToString()));
            GUI.Label(new Rect(pos.x - (size.x / 2), -pos.y + view.position.height + 4, size.x, size.y), bounds.ToString());
            Handles.EndGUI();
        }
    }

さらに GetBoundsWithChildren メソッドのスクリプトです:

  /// <summary>
        /// Gets the rendering bounds of the transform.
        /// </summary>
        /// <param name="transform">The game object to get the bounding box for.</param>
        /// <param name="pBound">The bounding box reference that will </param>
        /// <param name="encapsulate">Used to determine if the first bounding box to be calculated should be encapsulated into the  argument.</param>
        /// <returns>Returns true if at least one bounding box was calculated.</returns>
        public static bool GetBoundWithChildren(Transform transform, ref Bounds pBound, ref bool encapsulate)
        {
            var bound = new Bounds();
            var didOne = false;
 
            // get 'this' bound
            if (transform.gameObject.renderer != null)
            {
                bound = transform.gameObject.renderer.bounds;
                if (encapsulate)
                {
                    pBound.Encapsulate(bound.min);
                    pBound.Encapsulate(bound.max);
                }
                else
                {
                    pBound.min = bound.min; 
                    pBound.max = bound.max; 
                    encapsulate = true;
                }
 
                didOne = true;
            }
 
            // union with bound(s) of any/all children
            foreach (Transform child in transform)
            {
                if (GetBoundWithChildren(child, ref pBound, ref encapsulate))
                {
                    didOne = true;
                }
            }
 
            return didOne;
        }
-----

ん?Unityエディタのワイヤフレームに似ているとおもったけど少し発展的な用途に使うことが多いだろうか。

これも覚えておこうぜ!

2013年5月22日水曜日

Unity Tips #50 - コンパイル記号があることの確認

前回に引き続いて Unify Community からコンパイル記号に関する Tips の翻訳を紹介する:



http://wiki.unity3d.com/index.php/Tip_of_the_day
Feb 2013

Tip #50 Ensure conditional compilation symbols are present

コンパイル記号があることの確認


もし Unity のコードで条件付きコンパイル記号が必要な場合、このコードが便利かもしれない。Unity が自身のスクリプトをコンパイルした後、InitializeOnLoad 属性のあるクラスを実行します。 コード スニペットに含まれる SetupConditionalCompilation メソッドをコールすることで条件付きコンパイル記号が Unity プロジェクトで永続することを保証できます。もし記号がなくて追加された場合、Unity コンソールに通知を書き出します。


[InitializeOnLoad]
public class GridMappingSetup
{
    static GridMappingSetup()
    {
        var types = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WebPlayer };
        var toInclude = new[] { "CBXControls", "GridMapping", "QuickTools", "ToolService", "TileMaterialCreation" };
 
        SetupConditionalCompilation(types, toInclude);
    }
}
 
  public static void SetupConditionalCompilation(BuildTargetGroup[] platformTargets, string[] symbolsToInclude)
        {
            foreach (var type in platformTargets)
            {
                var hasEntry = new bool[symbolsToInclude.Length];
                var conditionals = PlayerSettings.GetScriptingDefineSymbolsForGroup(type).Trim();
                var parts = conditionals.Split(';');
                var changed = false;
 
                foreach (var part in parts)
                {
                    for (int i = 0; i < symbolsToInclude.Length; i++)
                    {
                        if (part.Trim() == symbolsToInclude[i].Trim())
                        {
                            hasEntry[i] = true;
                            break;
                        }
                    }
                }
 
                for (int i = 0; i < hasEntry.Length; i++)
                {
                    if (!hasEntry[i])
                    {
                        conditionals += (String.IsNullOrEmpty(conditionals) ? String.Empty : ";") + symbolsToInclude[i];
                        changed = true;
                    }
                }
 
                PlayerSettings.SetScriptingDefineSymbolsForGroup(type, conditionals);
 
                if (changed)
                {
                    Debug.Log(String.Format("Updated player conditional compilation symbols for {0}: {1}", type, conditionals));
                }
            }
        }
---------

地味なTipsでも積み重ねて力にしていこうぜ!

2013年5月19日日曜日

Unity Tips #52 バージョン変更で正しいリンク


前回に引き続いて Unify Community からバージョン変更で正しいリンクに関する Tips の翻訳を紹介する:



http://wiki.unity3d.com/index.php/Tip_of_the_day
Feb 2013


Tip #52 Providing proper links in version changes

バージョン変更で正しいリンク


もしアセットストアにパッケージを提出していて、HTMLリンクを伴うバージョン変更を含む場合、リンク属性の中で target="_blank" を指定するのを忘れないようにして下さい。そうしなければ、アセットストア ウィンドウがもともとリンクしていたウェブページにより置き換えられる結果となります。場合によっては Unity がクラッシュします。
-------------

正しいリンクね~。Unity のクラッシュは良くあるけど、原因のひとつづつ覚えて解決していくしかないね!

2013年5月12日日曜日

Unity Tips #54 Scale Transformとレンダラ


Unify Community にScale Transformとレンダラに関する Tips があったので紹介したい。

http://wiki.unity3d.com/index.php/Tip_of_the_day
Feb 2013

Unity Tips #54 Scale Transform

Scale Transformとレンダラ


次のコードによりゲームオブジェクトの Transform を x, z 軸に沿って特定のサイズに拡大する際にゲームオブジェクトにレンダラ (Renderer) コンポーネントがアタッチされていれば、そのレンダラの境界線もあわせて調整する。

/// 
/// Transform を x, z 軸に沿って特定のサイズに拡大する。
/// </summary>
/// <param name="transform" />
/// スケールする Transform への参照
/// 
/// <param name="width" />ターゲット サイズを表す x 軸に沿った幅
/// <param name="height" />ターゲット サイズを表す z 軸に沿った高さ
public static void ScaleTransform(Transform transform, float width, float height)
{
    // プレハブ境界を取得
    var bounds = new Bounds();
    var encapsulate = false;
    if (!Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate))
    {
        return;
    }
 
    // サイズの軸のうち最小の大きさを取得
    var min = Mathf.Min(width, height);
 
    // Transformの x または z 軸のうち最大の大きさを取得
    var max = Mathf.Max(bounds.size.x, bounds.size.z);
 
    // スケール係数を計算
    var scaleFactor = min / max;
 
    // Transform にスケールを適用
    transform.localScale *= scaleFactor;
}
 
/// <summary>
/// Transform のレンダラ境界を取得
/// </summary>
/// <param name="transform" />境界ボックスを取得するゲームオブジェクト
/// <param name="pBound" />境界ボックスへの参照
/// <param name="encapsulate" />最初の境界ボックスとして
/// 計算されたものが <see cref="pBound"> 引数にカプセル化すべきか判断する
/// <returns>最低でもひとつの境界ボックスが計算されていれば true を戻す。</returns>
public static bool GetBoundWithChildren(Transform transform, ref Bounds pBound, ref bool encapsulate)
{
    var didOne = false;
 
    // 'this' の境界を取得
    if (transform.gameObject.renderer != null)
    {
        var bound = transform.gameObject.renderer.bounds;
        if (encapsulate)
        {
            pBound.Encapsulate(bound.min);
            pBound.Encapsulate(bound.max);
        }
        else
        {
            pBound.min = bound.min;
            pBound.max = bound.max;
            encapsulate = true;
        }
 
        didOne = true;
    }
 
    // 子オブジェクトのすべての境界と結合
    foreach (Transform child in transform)
    {
        if (GetBoundWithChildren(child, ref pBound, ref encapsulate))
        {
            didOne = true;
        }
    }
 
    return didOne;
}
--------
Unityデフォルトだとレンダラのサイズは調整されないので便利だぜ!

Unity Tips #55 InitializeOnLoadなどの良くある間違い


Unify Community に InitializeOnLoadなどの良くある間違いに関する Tips があったので紹介したい:


http://wiki.unity3d.com/index.php/Tip_of_the_day
Feb 2013

Tip #55 InitializeOnLoad & Resources.Load gotcha’s

InitializeOnLoadおよびResources.Loadの良くある間違い


最近、 Unity 4 エディタで初めはバグだとおもった内容に遭遇した。 InitializeOnLoad からの Resources.Load メソッドの使用が絡んでいる。

例えば次のサンプルコードをみてみる:
namespace CBX.CoreProjectCode
{
    using UnityEditor;
 
    using UnityEngine;
 
    [InitializeOnLoad]
    public class EditorInitialization
    {
        static EditorInitialization()
        {
            LoadData(); // Resourceフォルダのtest.txt ファイルを参照することに失敗する
        }     
 
        private static void LoadData()
        {
            // データのロードを試みる
            var data = Resources.Load("test", typeof(TextAsset)) as TextAsset;
            if (data == null)
            {
                Debug.LogWarning("データは見つかりませんでした");
                return;
            }
 
            Debug.Log(data.text);
        }
    }
}

Unity がスクリプトをコンパイルした後、InitializeOnLoad によりマークされたクラスの static なコンストラクタを実行する。しかし、この時点で私は Unity がまだ Resources フォルダの中にあるアセットについては識別できていないとみている。クラスのコンストラクタが Resources.Load メソッドをコールしたとき、 text.txt リソースファイルを呼ぶことに失敗し、コンソールに警告メッセージを表示する。

この時点でやることが可能であることのひとつはプロジェクトウィンドウの Assets フォルダを右クリックして Reimport を選択することだ。 Unity は Assets を再インポートして、 InitializeOnLoad によりマークされたクラスをコールする。しかし、今回は Resources.Load は正しく test.txt の読み込みを行い、内容を Unity コンソールウィンドウに表示する。

この問題の回避方法のひとつは、 EditorApplication.Update コールバックをフックしてそこから LoadData メソッドへのコールを行うことだ。以下にそのサンプルを示す:

namespace CBX.CoreProjectCode
{
    using UnityEditor;
 
    using UnityEngine;
 
    [InitializeOnLoad]
    public class EditorInitialization
    {
        private static bool ranOnce;
 
        static EditorInitialization()
        {
            EditorApplication.update += RunCallbacks;
        }
 
        private static void RunCallbacks()
        {
            if (!ranOnce)
            {
                // Resource フォルダの test.txt がみつかり内容が
                // 表示される
                LoadData();
                ranOnce = true;
 
                // returnするかはあなた次第
                return;
            }
 
            // 必要な処理があれば記述
        }
 
        private static void LoadData()
        {
            var data = Resources.Load("test", typeof(TextAsset)) as TextAsset;
            if (data == null)
            {
                Debug.LogWarning("データはみつかりませんでした");
                return;
            }
 
            Debug.Log(data.text);
        }
    }
}
これがバグであるかどうかは認識していないが、Unity にバグレポートの提出は行っている。リンクは次のとおりだ。
-----------------

先人の知恵は重要。Unity プログラミングに活かそうぜ!

Unity Tips #56 プロジェクトフォルダおよびカレントディレクトリの取得



今回は Unify Community で紹介されている Tips からカレントディレクトリの変更に関する Tips を紹介したい:

http://wiki.unity3d.com/index.php/Tip_of_the_day
Feb 2013

Tip #56 Get project folder & current directory

プロジェクトフォルダおよびカレントディレクトリの取得


Unity にプロジェクトフォルダ取得の API はないが、System.IO.Directory.GetCurrentDirectory を活用できる。Unity エディタはつねにカレントディレクトリがプロジェクトフォルダにセットされていることを前提にしている。

もしエディタスクリプトの中でカレントディレクトリを System.IO.Directory.SetCurrentDirectory により変更する場合、処理が完了した後に必ずディレクトリをプロジェクトフォルダにリストアしておく必要がある。そうしないと Unity でコンパイルする次の機会にダイアログボックスのプロンプト表示がなされてカレントディレクトリをプロジェクトディレクトリにリストアする必要が出てきて、 「Quit」ボタンにより Unity を終了せざるを得なくなる。

// プロジェクトフォルダを保存
var projectFolder = System.IO.Directory.GetCurrentDirectory();
 
// 指定のフォルダに カレントディレクトリをセットする
System.IO.Directory.SetCurrentDirectory("c:\\some folder name");

// 必要な処理を行う
// ...
 
// カレントディレクトリをプロジェクトディレクトリにリストアする
System.IO.Directory.SetCurrentDirectory(projectFolder);
---------

小さなテクニックでも積み上げていけば大きいぜ!

Unity Tips #58 擬似コントロール、インスペクタ

Unify Community で毎月配信されている Unityに関するTips集があることを知った。

便利そうなのでリンクを示したうえで翻訳を紹介しようとおもう:



http://wiki.unity3d.com/index.php/Tip_of_the_day
Mar 2013


Tip #58 LookLikeControls & LookLikeInspector


擬似コントロール、インスペクタ


フォーカスをあてるまではラベルとして動作するコントロールやインスペクタに関するメソッド。


public class LookLikeControlsInspector : EditorWindow
{
    private int integer1;
    float float1 = 5.5f;
 
    [MenuItem("Examples/Look Like Controls - Inspector")]
    static void Init()
    {
        var window = GetWindow<looklikecontrolsinspector>();
        window.Show();
    }
 
    void OnGUI()
    {
        EditorGUIUtility.LookLikeInspector();
        EditorGUILayout.TextField("Text Field:", "Hello There");
        EditorGUILayout.IntField("Int Field:", integer1);
        EditorGUILayout.FloatField("Float Field:", float1);
        EditorGUILayout.Space();
        EditorGUIUtility.LookLikeControls();
        EditorGUILayout.TextField("Text Field", "Hello There");
        EditorGUILayout.IntField("Int Field:", integer1);
        EditorGUILayout.FloatField("Float Field:", float1);
    }
}
-------

Tipsで少しづつ知識を積み上げていこうぜ!

2013年5月7日火曜日

NGUI 2.6.1 - 通常リリース版でダイナミックフォント対応!



NGUIバージョンアップ情報です:

http://www.tasharen.com/forum/index.php?topic=11.25
May 05, 2013, 08:58:41 PM


2.6.1
- 修正: ダイナミックフォント関連の修正
- 修正: デプス パスは パネルがクリッピングされるときは強制的に無効化される
- 修正: UICamera の Sticky press オプションにより OnDrop イベントが壊れる不具合を修正
- 修正: UIInput の useLabelTextAtStart が正しく動作しない不具合を修正
- 修正: UICamera.touchCount should now be accurate.
- 修正: Image Button インスペクタでの誤記を修正
- 修正: UIWidget.UpdateGeometry がオブジェクトの塗りつぶし(Fill)する前にオブジェクトの disabled 状態をチェックするように修正。
---------------

いよいよNGUI通常リリース版でダイナミックフォント対応されました!

ちなみにまだリリースして数日と経てないのにダイナミックフォントについて不具合?ユーザの使用方法のミス?なのかいくつか報告はあがっているようなので、うまく動作しないようなら掲示板の確認をオススメする!

2013年5月6日月曜日

UnityのOrthographicモードでzソートが暴れるときのメモ



最近にカメラの描画順でハマッったことがあり、Unity Answersに助けてもらったのでメモとして残してみることにした:

---------

http://answers.unity3d.com/questions/302803/orthographic-camera-rendering-order-not-always-wor.html
Aug 16, 2012 at 12:01 PM

質問

Unityで画面上のゲームオブジェクトのレンダリング順序を毎フレーム設定している。そして z ソートの順序を決めるようにしている。オブジェクトはただの4頂点の平面だ。ときどき z ソートが暴れて順序がおかしくなる様子なのだが原因が分からない。
カメラは Orthographic にしていて、もとは iPhoneゲームから移行したもので、次に書かれるオブジェクトの z デプスを格納するグローバル変数を増加させて対応しているのだけれども何が原因か分かる?

回答

1. はじめに、カメラのSortModeを確認する:



Camera.transparencySortMode
var  transparencySortMode : TransparencySortMode 
説明 
透明オブジェクトでのソート モード
 デフォルトでは Perspective カメラはオブジェクトをカメラ位置からの距離にもとづいてオブジェクトをソートする。そして Orthographic カメラは ビュー方向の距離にもとづいてソートする。
2D ゲームで Perspective カメラを使用している場合は TransparencySortMode を使用したほうが良い場合があり、オブジェクトがカメラのビューに沿った距離の順でソートした方が良い場合がある。
2.次に、シェーダを確認する。

  • シェーダでもレンダリング キュー値があり、z 値よりも優先されるので注意だ。低い値のキュー値の方が先にレンダリングされる。

3.最後に、ピボットの順序を確認する。

  • 透明オブジェクトについてはピボットを用いてソートされる。この場合は頂点ではなくピボットが正しい順序でソートされているか確認する。

----------

Unity の知恵を貯めこんでいこうぜ!

2013年5月3日金曜日

Oculus Riftでバーチャル世界に没入する

バーチャル世界がまた一歩先に進み始めている。

インディーズ開発者のKelly Weaver氏がOculus RiftとRazer Hydraモーションコントローラを組み合わせた動画を公開しているが、これが実に興味深い!


http://www.youtube.com/watch?feature=player_embedded&v=HWn8Hn-XCds
2013/04/26

興味深い点は:

  • 手の動き、頭の動きが忠実に再現される環境が整った
  • Oculus Riftにより、視界の中で動かしている手がスムーズに追従している

動画では前半では忠実に再現されるところ、後半の1分過ぎから動かしている手が自ら映っているところが出ているが、これを見ているとゲームの幅というのは大いに広がるのではないだろうか。

2013年5月1日水曜日

【動画紹介】Voxel Farmによる空の描画


先日取り上げた Voxel Farmのブログで美麗な空の描画を試行した動画があったので、を紹介したい:

【関連記事】

このグラフィックスがUnityに・・・来る??

-----
http://procworld.blogspot.jp/2013/04/the-sun-rises-in-procworld-again.html

Wednesday, April 10, 2013




プロシージャル世界 (Procedural World) に再び、日が昇る

先週に昼-夜サイクルのスクリーンショットを提供した。まだ粗い段階であり、ブログ読者により様々な解決策を提案いただいた。

もう一回だけチャレンジをして、まだ完璧ではないけれど改善はできた。ビデオ作成をしたので、また意見をもらえると有難い。

前回の大きな課題は空の明るさ(十分でなかった)と、遠くの風景が空にうまく溶け込まなかったことだった。今回は大気圏を十分に大目のスペースをとるようにして地平線との間が目でハッキリと分かるようにした。空への距離を地形のバランスをとり、地形と空の色合いも大分改善された。
-----

うーん、どんどんチャレンジしてほしいぜ!

ブックマークに追加

このエントリーをはてなブックマークに追加

自己紹介

自分の写真
Unity3D公式マニュアル翻訳やってる人がスマホ(iPhone, Android)のゲーム開発しています。気軽に面白く初心者が遊べる内容がモットー。Blogでは開発情報をひたすら、Twitterではゲーム作成の過程で参考にしている情報を中心につぶやきます

ページビューの合計

過去7日間の人気投稿