2018年11月30日金曜日

Zenject MonoBehaviourを継承しているオブジェクトを注入するときの注意点

Zenject MonoBehaviourを継承しているオブジェクトを注入するときの注意点

Zenjectを初めて触って[Inject]を使って注入しようとなんとなく動かしたらAssertが出たのでメモ

//丸写ししたコード
Container
  .Bind<Hoge>()    //Hogeが要求されたら
  .To<ConcreteHoge>();  //ConcreteHogeを注入する


表示されたアサートは以下のもの

ZenjectException: Assert hit! Error occurred while instantiating object of type 'Hoge'. Instantiator should not be used to create new mono behaviours.  Must use InstantiatePrefabForComponent, InstantiatePrefab, or InstantiateComponent

新しくMonoBehaviourを生成する形で注入することはしないでほしい。
代わりに下の関数を使ってねとのこと。

  • InstantiatePrefabForComponent関数
  • InstantiatePrefab関数
  • InstantiateComponent関数

ただ、今回はBind関数を使っているので上の関数は使えない。
公式ドキュメントのDiCOntainer.Bindに'See here'とあってそこを読んでいくと、ConstructionMethodという項目があり、これらの関数を使用すると上のアサートを解決できる。

ConstructionMethodにもいくつかのバリエーションがあり、自分はFromComponentInNewPrefab関数を利用した。引数にはプレハブを渡すようになっている。
これはプレハブに設定してあるコンポーネントを[Inject]指定されたところに注入するものだ。

実際に動かすと実行時に渡したプレハブのインスタンスが自動で生成されていて、無事目的を果たすことができた。

ConstructionMethodには
  • FromNew
  • FromInstance
  • FromMethod
  • FromMethodMultiple
  • FromFactory
  • FromIFactory
  • FromComponentInNewPrefab
  • FromComponentsInNewPrefab
  • FromComponentInNewPrefabResource
  • FromComponentsInNewPrefabResource
  • FromNewComponentOnNewGameObject
  • FromNewComponentOnNewPrefab
  • FromNewComponentOnNewPrefabResource
  • FromNewComponentOn
  • FromNewComponentSibling
  • FromComponentInHierarchy
  • FromComponentsInHierarchy
  • FromComponentSibling
  • FromComponentsSibling
  • FromComponentInParents
  • FromComponentsInParents
  • FromComponentInChildren
  • FromComponentsInChildren
  • FromNewComponentOnRoot
  • FromResource
  • FromResources
  • FromScriptableObjectResource
  • FromNewScriptableObjectResource
  • FromResolve
  • FromResolveAll
  • FromResolveGetter<ObjectType>
  • FromResolveAllGetter<ObjectType>
  • FromSubContainerResolve
  • FromSubContainerResolveAll
と様々な用途に対応している。(2018/11/30 確認) 公式ドキュメントはこちら
列挙している内に今回のケースだとFromNewComponentOnNewGameObject関数が一番いいと気が付いた。(パラメータを指定する必要があったわけではなかったので)
この関数を使うときはTo<>関数で型を指定する必要があるので注意。

Container
    .Bind<Hoge>()    //Hogeが要求されたら
    .To<ConcreteHoge>() //ConcreteHogeを注入する
    .FromNewComponentOnNewGameObject();


以上、深く調べるきっかけを与えた方へお礼申し上げます。
そのままだと気が付かないままでした。

2018年11月28日水曜日

unity-simple-rankingで複数のランキングを扱えるようにした話

unity-simple-rankingで複数のランキングを扱えるようにした話


naichiさんがGitHubで公開しているunity-simple-rankingを使用すると自作ゲームに簡単にランキング機能を付けることができます。

自分も試してあっさりできたので本当に素晴らしいライブラリですのでおすすめです。

で、自作したゲーム3Dアミダクジに組み込んでみたのですが、このゲームには複数のモード(NormalとEndless)がありまして、それぞれにランキング機能をつけたいなと思いました。ただ、unity-simple-rankingはそのままだと単一のランキングしか扱えないので、少し改造してこちらが指定したランキングにアクセスできるようにしました。

使い方
var loader = naichilab.RankingLoader.Instance;
loader.info.Set("使いたいNCMBクラスの名前", "画面に表示する名前");
loader.SendScoreAndShowRanking(1000); //ランキングを表示
naichilab.RankingLoader.Instance.infoが新しく追加したRankingInfoクラスのインスタンスになります。

[Serializable]
public class RankingInfo
{
    ///     /// サーバーとやり取りするときの名前
    ///     public string className = "";

    ///     /// 画面に表示する名前
    ///     public string displayName = "";

    public RankingInfo()
    { }

    public RankingInfo(string className, string displayName)
    {
        this.className = className;
        this.displayName = displayName;
    }

    public void Set(string className, string displayName)
    {
        this.className = className;
        this.displayName = displayName;
    }
}

クラス自体はとても単純なものになります。
あとはRankingSceneManagerクラスの中でNCMBクラスを指定している部分を上のクラスに設定されている値を使うように変更しました。

注意点としてはRankingInfoに何も設定しなかったとき(空文字列を指定したとき)は以前のNCMBクラスを使うようになっています。

既存のunity_simple_rankingを使っているコードは壊さないように(たぶん)作りましたので、一つのゲームに複数のランキングを欲しいなと考えている人はよかったら使ってください。
https://github.com/tositeru/unity-simple-ranking

テンピーポーテンカラー プレイ感想

テンピーポーテンカラー プレイ感想
11/30 追記 ゲーム内容が更新されていたので、書いている内容と微妙に異なるかもしれないのでご注意

ゲームはこちらから

十個の色をした人型(非常扉に書かれている奴)をゴールまで導く2Dゲーム
(レミングスと同じジャンルなのかな?)



何もしないでゴールには到着するわけではなく、阻むように障害物が配置されている。
その障害物を取り除いてゴールまで導くわけだが、その取り除き方がこのゲームの特徴を成している。

左クリックを押しっぱなしにすると円形に色見本のようなものが出てきて、
押しっぱなしのままで各色にカーソルを合わせると背景色がその色になる。
そうするとステージ上にある同じ色をしたものが人型、障害物関係なく消える。
というより同化して認識できない状態になって、これを利用してゴールまで導く感じである。
(左クリック押しっぱなしで色見本が出てくる)












(赤を選択すると赤色の障害物が消えて、人型が下まで落ちるようになる)


















ゲーム自体は物理演算を利用しており、これを利用したステージも存在する。
レベルデザインも大変よく、プレイヤーにこのゲームでできることを一つずつ教えてくれる親切なゲーム。もちろん、パズルゲームのように頭を使わないとクリアーできないものもあるが、
音遊び的なステージもあって、いいアクセントとなっていた。

(障害物を消すのではなく留め具を消すといった発想も必要だった)

テンポよくプレイでき、ステージ数が物足りないかな?と感じ、
もっと遊びたいなと思わせてくれた大変できたゲームでした。

Unityroomによると、UnityAnima2Dというアセットを使用しているようだ。
画像にボーンを付けられ、スキニングとIKまで対応と非常に多機能なAssetなので、今度使ってみたい。