読者です 読者をやめる 読者になる 読者になる

神様は有給消化中です。

技術ネタを書こうかな。時事ネタとか私生活ネタはうけないし。

【Unity】【uGUI】リストビューに、セルが画面外から差し込まれるアニメーションをつける

uGUIで作ったリストビューに、セルが画面外から差し込まれるようなアニメーションを追加する方法を共有。
最終的にこんな感じになります。
f:id:appleorbit:20160402223716g:plain

続きを読む

【Unity】カメラからどれだけ離れても、最低1ピクセルは表示されるように保障する

通常3Dオブジェクトがカメラから離れすぎると、レンダリングサイズが1ピクセルを下回った時点で画面に描画されなくなり、カメラとの位置関係によって描画が切れたり出たりしてチカチカと表示されることがあります。今回はこの問題の解決方法(レンダリングの最低ピクセル保障)を共有します。

続きを読む

【Unity】マテリアルの描画がシェーダーのQueue順に処理されない原因と対策

自作シェーダーなどを使用してレンダリングを行う場合、レンダリング順序をTagsのQueueで指定しますが、特定の条件でこのレンダリング順序が無視される現象が発生したので共有。

簡潔にまとめだけ

まとめると
現象  :シェーダーで指定したレンダリングキューが無視されることがある
原因  :MaterialのCustom Render Queueに不正値が入っているため
発生条件:自作シェーダーを使用 & 自作シェーダー設定前に、他のシェーダーを割り当てていた場合
対策  :Custom Render Queueに-1を設定すればOK

続きを読む

【Unity】Graphicを継承したクラスでMissingReferenceExceptionが発生する

Unity UGUI

先日、Graphicを継承したクラスで何故かMissingReferenceExceptionが発生することがあったので共有。
結論から言うと、OnDisableをオーバーライドすると発生する様子。

テスト用にこんなクラスをすると、コンパイル時にMissingReferenceExceptionが発生します。

public class HogeUI : Graphic {
    protected override void OnDisable ()
    {
        /* なんらかの処理 */
    }
}

Exceptionの内容はこんな感じ。HogeUIが破棄されたのにアクセスしていますと。

MissingReferenceException: The object of type 'HogeUI' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.UI.Graphic.OnRebuildRequested () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Graphic.cs:396)
UnityEngine.UI.GraphicRebuildTracker.OnRebuildRequested () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/GraphicRebuildTracker.cs:33)
UnityEngine.CanvasRenderer.RequestRefresh ()


おそらくGraphicクラスのOnDisableで何かしら必要な処理を行っていて、オーバーライドによって走らなくなったために起こっているのかと。

対応は以下のようにしました。

public class HogeUI : Graphic {
    protected override void OnDisable ()
    {
        base.OnDisable(); // 追加

        /* なんらかの処理 */
    }
}


Graphicクラスの関数をオーバーライドする場合は、基本的に親クラスの処理を呼び出したほうがいいのかもしれません。

【Unity】AssetBundle化したPrefabのシェーダー参照が壊れる現象

Unity Shader

先日、AssetBundle化したPrefabのシェーダー参照が壊れる現象に遭遇したため解決策を共有。状況としてはこんな感じ。
・自作のUGUIオブジェクトにカスタムシェーダーを適用してPrefab化
・上記Prefabをシーンに追加して実行→正常動作
・上記PrefabをAssetBundleから読みこんで実行→表示が壊れる

FrameDebuggerで確認すると、シェーダー名称は適用したカスタムシェーダーの物になっているが、レンダーステートが明らかにおかしい・・・。

Google先生に聞くと、以下の記事を発見。
NGUIオブジェクトをAssetBundle化すると、シェーダー参照が壊れることがあるらしい。blog.livedoor.jp

古い情報だしNGUIだし、関係ないだろーと思いながらランタイムでシェーダーを再設定するとちゃんと表示できた。何ぞこれ。

private void Awake(){
   Material material = GetComponentInChildren<Material>();
   if(material != null){
      Shader s = Shader.Find("Custom/Hoge");
      if(s){
         material.shader = s;
      }
   }
}

ちなみに、上記のコードを実行した場合、UnitEditorと実機で適用されるシェーダーが変わる。
UnityEditor:/Assets以下に入っているカスタムシェーダー
実機:AssetBundleに入っているカスタムシェーダー
これはShader.Findの検索順に依存していると思われます。

しかし、Shader.Findでシェーダーが見つかるのに参照が壊れる理由が本当に不明。
シェーダーコンパイルやらの関係・・・?うーむ。
何か情報をもっている方がおられたら、コメント欄で教えて下さい。

【Unity】EventSystemsから受け取った座標をRectTransform.localPositionに設定する方法

Unity

uGUIのEventSystems(IBeginDragHandler, IDragHandler, IEndDragHandlerなど)から受け取った座標をそのままRectTransform.localPositionに設定すると、Canvasのscaleによってはぶっ飛んだ位置(描画領域外)に移動してしまうことがあります。
EventSystemsから渡される座標はスクリーン座標のため、scaleが影響してぶっ飛んでしまうわけですが、今回はこのぶっ飛び現象を回避するためにスクリーン座標→ローカル座標へ変換する方法を共有します。

続きを読む

【Unity5】HPゲージを実装する最も簡単な方法!

UnityでHPゲージを実装する簡単レシピを共有。最終的にこんな感じになります。
f:id:appleorbit:20151020232320p:plain

続きを読む