【Unity】コルーチンの制御

Unityでコルーチンを使って処理の流れを制御する時の待機方法を調べてみました。 通常はWaitForSecondsを使っている感じなのですが、その他色々な方法があります。

コルーチンの制御

コルーチンについてのドキュメントはこちらです。 コルーチン - Unity

秒数待つ

指定された秒数を待機する時にWaitForSecondsを使います。 [c] private IEnumerator StartAction() { yield return new WaitForSeconds(1.0f); } [/c]

時にはタイムスケールを制御している場合があるときにはWaitForSecondsRealtimeを使います。 タイムスケールに影響されずに待機することができます。 [c] private IEnumerator StartAction() { yield return new WaitForSecondsRealtime(1.0f); } [/c]

WaitUntil

指定した条件を満たすまで待機するのがWaitUntil()です。 [c] private IEnumerator StartAction() { yield return new WaitUntil(()=>_count > 10); } [/c]

WaitWhile

指定した条件から外れたときまで待機するのがWaitWhile()です。 [c] private IEnumerator StartAction() { yield return new WaitUntil(()=> gameObject == null); } [/c]

自作する

CustomYieldInstructionを継承すれば自作の待機処理を作成することができます。 必要なプロパティはkeepWaitingです。 こちらの条件を見てコルーチンを待機させることができます。

[c] public class CustomHoge : CustomYieldInstruction { public bool IsComplete { get; private set; }

public override bool keepWaiting
{
    get { return IsComplete == false; }
}

}

private IEnumerator StartAction() { yield return new CustomHoge(); } [/c]

最後に

コルーチンは今後、「async await」に置き換わっていくと思うのですが、コルーチンはまだまだ健在です。 今回調べて、色々な使い方が見えてきましたので、実際に使える場面で使っていきたい。

「ワンフェス2019冬」に行ってきました【フィギュア】

2月10日に幕張メッセで行われた「ワンフェス2019冬」に行ってきました。 ワンフェスには毎年夏に時間があれば言っていたのですが、今回は初めて冬開催に行ってみました。 ワンダーフェスティバル|Wonder Festival

ワンフェス

ちょうど9時50頃に幕張メッセに着きました。 前回訪れた夏に比べて到着時間は遅いのですが、待機列は比較的前の方でした。 それでも入場までには開場時間(10:00)から30分くらい遅れてになってしまいました。 2019 2 25 01

仮面ライダージオウ

個人的に仮面ライダーが好きなこともあるのですが、メディコム・トイの仮面ライダーシリーズはとても良くできていると思っています。 最新作である仮面ライダージオウが展示されていましたが写真写りもよくとてもかっこよく撮れていたと思います。

艦これ

グッドスマイルカンパニーブースでは過去、艦これだけのブースがあったのですが、今回はその他大勢のように展示されていました。 時代の流れと注目度の影響を感じます。 私自身、艦これをもうやっていないのですが、今回展示されていたフィギュアはギリギリ知っているものでした。

ゴブリンスレイヤー

去年の秋のアニメで結構ハマったのが「ゴブリンスレイヤー」です。 まだ早いかと思っていたのですが、原作絵のフィギュアが並んでいました。 この2人が人気なのかなと思いました。

ゆるキャン△

ゆるキャン△の人気はとても高いなと今回のワンフェスを見て感じました。 複数の企業から出ているのもあるのですが、アマチュアのブースでもたくさんのフィギュアが並んでいました。 主人公のなでしこのフィギュアは前回余りなかったので今回写真撮影ができてよかったです。

ssss.gridman

フィギュア業界が流行に敏感なことがよくわかるのが、「ssss.gridman」の出店の多さだと思いました。 どれも当初から企画されたものではなく、アニメが流行っていることを理由に企画されたものだというのが、着色済みのフィギュアが一体もなかったことから想像できました。 おそらく夏頃から販売されるのだと思いますが、色がのることでどういった形になるのか楽しみです。

2019 2 25 02

HUNTERXHUNTER

HUNTERXHUNTERの蟻編、メルエムvsネテロ会長がフィギュア化されていました。 3Dの百式観音がどういった感じなのか、これは直接見ていただいたほうがよいのですが、結構マニアックなシーンをフィギュア化したなと思います。

ガルパン

今年の5月の劇場版が出るのですが、コトブキヤのフィギュアがとても良くできていました。 ガルパンの凄いところは主役ではない脇役や敵キャラも等しく人気があるところで、今回のワンフェスでは逆に大洗高校(主人公)側のフィギュアは一体もなかった気がしました。

SHIROBAKO

今までなかったのかと思いましたが、SHIROBAKOねんどろいど。 劇場版の公開が決まったということもあるのか、この時期で発売されるみたいです。

最後に

今回マクロレンズを使って撮影をしてみたのですが、結構キレイに撮れているなと感じました。 ただ倍率が35mmの単焦点レンズですので、細部にわたって撮影するのは難しかったです。もう少し倍率のあるレンズが欲しくなりました。

レッド・デッド・リデンプション2をクリアしました

先月から少しづつ遊んでいたPS4ソフト「レッド・デッド・リデンプション2」をクリアしました。 去年に発売し、結構話題になっていたソフトなので遊んでいる方は多いのかもしれませんが、とても面白かったです。

レッド・デッド・リデンプション2

2010年に「レッド・デッド・リデンプション」が発売されているのですが、私はこのシリーズを遊ぶのは初めてです。 話のつながりは特にないそうなので、いきなり2からはじめても問題ないです。

ゲーム内容

ゲーム内容は「オープンワールド」ゲームです。 メインのイベントを主軸として、サブイベントや探索や賞金首など色々なことができます。 移動手段は馬です。ファストトラベルは使えるのですが、主要な街にしかいけないこともあるのであまり利用頻度は高くありません。

感想

とりあえず進行度が100%になったので、そこまでの内容を加味して感想を書きたいと思います。

ボリューム

メインイベントがとても多いと感じたので軽く100時間以上遊ぶことができました。 ストーリーも単調に敵を倒すだけではなく、内容に波があるのでどれも楽しめました。 イベント以外にも様々な探索もあるのですが、私はほとんどできませんでした。 今後の追加コンテンツもありそうな感じですので、長く遊ぶことができると思います。

グラフィック

レッド・デッド・リデンプション2」はディスクが2枚入っています。 データ用とゲーム用です。それだけデータ量があるということです。 そのデータ量が示すように、グラフィックはとても綺麗です。 主人公のモデルのアニメーションも3Dだなと違和感を持たれないくらい精巧にできています(モブキャラはそうでもありませんが、) この美しい世界を見て回るだけでもこのソフトをやる価値があると感じました。

システム

システムはオープンワールドでよくあるゲームシステムなのですが、「レッド・デッド・リデンプション2」で面白いと思ったのは、ライフとスタミナに空腹度が絡んでくることです。 なにか食べないと痩せていきスタミナがなくなります。逆に太り過ぎるといったこともあります。 また、寝ないとモノを食べてもスタミナが回復しません。

また良い行いをすると評判があがり、悪行を繰り返すと評判が下がる評価システムがあり、イベントだけでなく、普段の行動時にどうするかを慎重に選ぶ必要がありました。

登場人物

仲間のキャラクターが多いので最初はどういった人物なのかわからないですが、とにかくイベントが多く色々なキャラクターと絡みが増えます。 そのため、どういった人物なのか段々とわかってきます。 そういったこともあり、ゲーム後半では結構キャラクターに愛着が生まれきました。

バトル

操作がとても複雑です。 オープンワールドは特にそうなのですが、色々できる反面プレイヤーの操作が簡単ではありません。ですので、操作ミスで他人の馬を盗んでしまったり、馬車に飛び乗ったりして指名手配されるなど、位置した行動ができないことが多々ありました。 これは慣れてくるとマシになるのですが、どうも序盤が大変です。

最後に

前評判通り、とても面白かったです。 ストーリーもとても良かったので、操作方法や移動手段に難儀しながらも最後まで遊ぶことができました。 西部をストーリーにするゲームをやったのは初めてだったのですが、歴史がどうなっていたかを学ぶこともできた気がします。 また、英語音声しかないこともあり、字幕と照らし合わせて、英語の勉強にもなった気がします。

【Unity】UnityのAttributesを調べてみた

個人的に一度調べてみたかった属性についてブログに書いていきたいと思います。いろいろな制約や拡張ができるので、上手く組み合わせて使えば作業速度や効率が良くなると思います。

Attributes - 属性

クラスに成約をもたせることができます。

RequireComponent

指定したクラスが必要になります。 例えばTextクラスが必ず必要な場合には次のような記述を行います。 [c] [RequireComponent(typeof(UnityEngine.UI.Text))] public class Hoge : MonoBehaviour {

} [/c]

もし必要なクラスがない場合にはダイアログが表示されます。 2019_02_14_memo

SerializeField

Inspector上のprivateのフィールドを設定できます。(これをシリアライズ化とも呼ぶらしい) Publicでも同じようなことはできますが、他のクラスから参照ができてしまうので、限定して利用したい場合に使います。 [c] [SerializeField] private string hogeText; [/c]

2019_02_14_memo2

AddComponentMenu

「AddComponentMenu」メニューのComponent」に特定のクラスを指定する場合に利用します。 次のコードでは「Hoge、AddComponentMenu」に追加します。 [c] [AddComponentMenu("Hoge/AddComponentMenu")] public class Hoge : MonoBehaviour {

} [/c]

画面上では次のようになります。 2019_02_07_03

ColorUsage

アルファを設定できるかどうかを調整できます。 ColorUsage

[c] [ColorUsage(false)] [SerializeField] private Color _color; [/c]

アルファの項目が無くなっています。 2019_02_15_moem

ContextMenu

ContextMenuを設定すれば、Inspector上で右クリックを押すとメソッドを実行できるようになります。 [c] [ContextMenu("Test")] public void Test() { Debug.LogError("Test"); } [/c] 2019 02 15 memo2

ContextMenuItem

ContextMenuItemは指定したフィールドで右クリックをすると、引数で指定したメソッドを呼び出せます。 ContextMenuItem - Unity Documentation

[c] [ContextMenuItem("Test","Test")] [SerializeField] private Color _color; [/c] 2019 02 15 memo3

DisallowMultipleComponent

DisallowMultipleComponentは同一のコンポーネントをアタッチできなくします。 [c] [DisallowMultipleComponent] public class Hoge : MonoBehaviour { } [/c]

参考サイト

UnityのAttribute(属性)についてまとめてメモる。

【Unity】FirstOrDefault()の引数

c#Linqを使う時に、最初の要素を取得したいときに「FirstOrDefault」をよく使っています。 要素がない場合には既定値(int型なら0、string型なら空)を返してくれます。 非常に便利なのですが、引数を使えばコードがより短くなる場合があります。

FirstOrDefault

FirstOrDefaultはLinqに定義されてされています。 FirstOrDefault - Microsoft

実は引数で条件を設定できます。 [c] List ids; ids.FirstOrDefault(x => x == 0); [/c]

この場合、0に等しい最初の要素を取り出せます。

ここコードはこのようにも置き換えられます。 [c] List ids; ids.Where(x => x == 0).FirstOrDefault(); [/c]

今まではWhereを使っていたのですが、FirstOrDefaultでも同じことができたのです。

【Unity】UIBehaviourについて

UnityにはMonoBehaviourの他に「UIBehaviour」というクラスが用意されています。 私も最近までこの存在を知らなかったのですが、結構いろいろなところで利用をされているのを見かけたので少し調べて見ることにしました。

UIBehaviour

公式のスクリプトのリファレンスです。 UIBehaviour

その名のようにUIで利用するクラスになります。 基本、MonoBehaviourの機能が使えるので一部のUnityのイベントサイクルに対応しています。

[c] // Awake protected override void Awake() { base.Awake(); }

// Start protected override void Start() { base.Start(); } [/c]

また、gameObjectやtransform、tagなども使うこともできます。 もちろん、GetComponentやStartCoroutineなども利用できます。

OnRectTransformDimensionsChange

RectTransformが変更されたときにこちらのメソッドが呼び出されます。 これが見た所UIBehaviour独自で使えそうな関数です。 [c] protected override void OnRectTransformDimensionsChange () { base.OnRectTransformDimensionsChange(); } [/c]

OnValidate

こちらはMonoBehaviourにもありますが、Inspector上にアタッチした際など呼び出されるので、強制的に何かしらの処理をしたいときなどに利用ができそうです。 [c] protected override void OnValidate() { base.OnValidate(); } [/c]

最後に

調べた所、MonoBehaviourをベースにUI作成向けに特化したクラスがUIBehaviourな感じがしました。 独自でUIパーツを実装する時にはUIBehaviourをとりあえず使っておいて損はなさそうです。

【Unity】Inspectorの変更を検知する

この度やりたいことは、Inspector上で何かしらの値を変更した時に、GameObjectがそれに伴い反応をさせることです。 色を変更すれば、すぐに色が変わる。デフォルトで用意されているUIパーツでは実現ができているのですが、これを独自に実装をします。

Inspectorの変更を検知する

まずは、Inspector上の変更を検知します。 いろいろ調べた所、エディタ拡張をすれば実現ができそうでした。

エディタ拡張

OnInspectorGui()で、DrawDefaultInspector()を使えば判定ができます。 [c] public override void OnInspectorGUI() { base.OnInspectorGUI();

if (DrawDefaultInspector()) { // ここで更新処理を入れる } } [/c]

OnInspectorGUI

OnInspectorGUIはEditorクラスを継承して利用します。 OnInspectorGUIをInspectorをカスタマイズすることができます。 [c] public class CustomUIEditor : Editor { public override void OnInspectorGUI() {

} }

[/c] [エディタ拡張]についてはこちら。 第9章 CustomEditor

DrawDefaultInspector

DrawDefaultInspectorはカスタムInspectorにデフォルトのInspectorを表示させます。 コードを追っていくとデフォルトのInspector内で値の変更があればtrueを返してくれます。 [c] return EditorGUI.EndChangeCheck() [/c] EditorGUI.EndChangeCheck

更新処理

先程のエディタ拡張内に更新処理を実装します。

[c] [CustomEditor(typeof(ChangeUI),true)] [CanEditMultipleObjects] public class CustomUIEditor : Editor {

} [/c]

まずは、CustomEditorで「エディタ拡張を使うクラス」と CanEditMultipleObjects「複数のオブジェクトを編集」できるようにします。

呼び出し先のクラス

エディタ拡張で使用するクラスを準備します。 [c] public abstract class ChangeUI : UIBehaviour {

if UNITY_EDITOR

public abstract void OnInspectorChanged();

endif

} [/c]

上記クラスを継承したクラスを使います。 Inspector上のhogeの値を変更した場合に特定の処理を呼び出せます。

[c] public class MyChangeUI : ChangeUI { [SerializeField] private int hoge;

if UNITY_EDITOR

public override void OnInspectorChanged()
{
    if (this == null)
    {
        return;
    }

    Debug.Log("hogeが更新されました");

}

endif

} [/c]