20210111のUnityに関する記事は5件です。

NavMesh

〇動的NavMesh機能は正式採用
「Unity 5.6からLow Level APIのような物が公開され、NavMeshを動的にベイクすることが可能になりました。」
http://tsubakit1.hateblo.jp/entry/2018/01/06/003209

昔は機能をAppendしていたが、Unity2019では普通に機能実装されている。た
Unity2018でも多分実装されていると思う。

〇メモ

https://xr-hub.com/archives/7639

image.png

Unity2019.4.16 Navigationsample

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity3D】シーンビュー(Scene view)での操作の感度が上がったり下がったりする原因【カメラ操作・視点操作・ホイール操作】

概要

Unit3D で作業をしているときに、

シーンビュー (Scene view、作業画面)での視点操作の感度が急に良くなったり悪くなったりしたので、

その原因を記しておこうと思います。


Unityバージョン:Unity 2019.4.14f1
使用言語:C#

結論

シーンビュー における「ピボットポイント (pivot point)」が原因です。


あなたの近くにあるゲームオブジェクト A にピボットポイントを設定して作業している間に、

偶然、遠くにあるゲームオブジェクト B にピボットポイントが設定されてしまうと、

視点操作の感度が急に悪くなったように感じます。


逆に、あなたの遠くにあるゲームオブジェクト B にピボットポイントを設定して作業している間に、

偶然、近くにあるゲームオブジェクト A にピボットポイントが設定されてしまうと、

視点操作の感度が急に良くなったように感じます。

本論

シーンビューには「ピボットポイント」という概念があります。

例えば、シーンビューで「回転」の視点操作をする(Alt キーを押したままクリック&ドラッグ)とき、

ある点を中心にして回転しますよね。

この点のことを「ピボットポイント (pivot point)」と呼びます。


ピボットポイントの設定方法は、

  • Hierarchy view でピボットポイントにしたいゲームオブジェクトをダブルクリックする
  • ピボットポイントにしたいゲームオブジェクトを選択した状態で F キーを押す

です。

こうすることで、対象のゲームオブジェクトの原点がピボットポイントに設定されます。


このピボットポイントが近くに設定されたり、遠くに設定されたりすることで、

視点操作の感度が良くなったり、悪くなったりするように見えるのです。

参考記事

Unity-sceneのカメラの移動が遅すぎる - teratail
補足:
こちらの記事ではピボットポイントは「注視点」と呼ばれています。
「注視点」という言葉は、ググってみるとピボットポイントではなく、ゲームシーンにおけるカメラ操作の文脈で使われていることが多かったです。

シーンビューのナビゲーション - Unity スクリプトリファレンス

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GetComponetsInChildren は孫も対象になるのか?

Unity 初心者向けの記事です。

Unity で開発していて、画面上に表示している TextMeshPro の値を変更したい場合が出てくると思います。
動的に生成したオブジェクトの場合など、インスペクターから設定できない場合に、コンポーネントを検索して設定する場合などがあると思いますが、そういう場合の変更方法になります。

TL;DR

getComponetsInChildren は一段階下の階層だけではなく、さらに下の孫階層なども検索してくれます。
ので、孫にある TextMeshPro の文字を変更した場合も、GetComponetsChildren で取得した結果から変更することができます。

前提

  • Unity 2019.4.9f1

やったこと

流れ

1.こんな感じのGameObjectを準備しておきます
2020-12-28_13h10_17.png
2. 階層を検索して孫が取れることを確認しています
3. 孫が取れている前提で、TextMeshPro の文字の値を変更しています

サンプルプログラム

    [SerializeField] private GameObject root;
    private void TestGetComponentsInChildren()
    {
        var r = Instantiate(root);

        // 生成したオブジェクト(root)から、TextMeshPro を持っているオブジェクトを検索する
        var children = r.GetComponentsInChildren<TextMeshPro>();
        if (children == null)
        {
            Debug.Log("children is null");
        }
        else
        {
            Debug.Log("children is NOT null");
            Debug.Log(children.Length);
            // 今回は Leaf1 と Leaf2 が TextMeshPro を持っているので、
            // 1つ下の階層も2つ下の階層も検索してくれていれば Leaf1, Leaf2 と出力されます
            Debug.Log(string.Join(",", children.Select(x => x.gameObject.name)));
        }

        // ↑ で取得できている前提で、Leaf2 のオブジェクトを持ってきます
        var grandChild = children.First(c => c.gameObject.name == "Leaf2");
        if (grandChild == null)
        {
            Debug.Log("grandChild is null");
        }
        else
        {
            Debug.Log("grandChild is NOT null");
            grandChild.GetComponent<TextMeshPro>().text = "grandChild";
        }
    }

結果

コンソールには孫まで取れていることがわかるログが出つつ、
2020-12-28_13h27_34.png
Leaf2 の TextMeshPro には grandChild が設定されています。
2020-12-28_13h28_15.png

おまけ

  • name で指定して対象のオブジェクトを取得しているので、一文字でも間違っているとエラーになります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Missing Project ID Because you are not a member of this project this build will not access Unity services. Do you want to continue?

Missing Project ID
Because you are not a member of this project this build will not access Unity services.
Do you want to continue?

image.png

解決策
ステップ1 NewLinkを押す
ステップ2 Createする
image.png

<参考>

https://qiita.com/nonkapibara/items/808834465b6d0157cfc6

Unityの公式マニュアルの方法にも対処方法が記載されていました。
https://docs.unity3d.com/ja/2019.1/Manual/UnityAnalyticsMismatchedProjectId.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity#JsonUtilityのデシリアライズ時の挙動確認とデシリアライズ失敗時にエラーを出させる方法

概要

UnityのJsonUtilityをサーバーレスポンスのデシリアライザとして使う際実用に耐えるかどうか確かめた際のログです。
めっちゃ適当で恐縮ですけど、以下のデシリアライズがちゃんとできるか確かめたものになります。

JSONとクラスのプロパティが一致

うまくいった。まぁこれうまくいかないわけないよねぇ。

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private int bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:{bbb}";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":3 }";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:3

リストを含んだクラスのデシリアライズ

うまくいった。

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private List<string> bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:{string.Join(",", bbb)}";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":[\"a\",\"b\",\"c\"]}";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:a,b,c

オブジェクトがネストしたクラスのデシリアライズ

これもうまくいく。

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private Test2 bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:[{bbb}]";
    }
}
[Serializable]
public class Test2 {
    [SerializeField] private string ccc;
    [SerializeField] private List<string> ddd;

    public override string ToString() {
        return $"ccc:{ccc}, ddd:{string.Join(",", ddd)}";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":{\"ccc\": \"test2\", \"ddd\": [\"a\",\"b\",\"c\"]}}";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:[ccc:test2, ddd:a,b,c]

Dictionary型を含んだクラスのデシリアライズ

うまくいかない。 まぁ、これは他の記事でも読んでたから想定内。
ネストしたクラスがデシリアライズできるなら問題はないかな。
(ただエラーが出ないのはちょっと問題だな…)

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private Dictionary<string, string> bbb;

    public override string ToString() {
        if (bbb == default) {
            return $"aaa:{aaa}, bbb:[]";
        }
        return $"aaa:{aaa}, bbb:[{string.Join(",", bbb.Select(a => a.Key + ":" + a.Value))}]";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":{\"ccc\": \"test2\", \"ddd\": \"test3\"}}";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:[]

JSONとクラスの型が違う場合

うまくいかない。 ただエラーにならず一致しない箇所が空やnullになる。
これもエラー吐いてくれないのねん…

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private string bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:{bbb}";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":{\"ccc\": \"test2\", \"ddd\": \"test3\"}}";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:

JSONとクラスのプロパティが一致しない場合

これもエラーは吐かれない。うーむ…。

[Serializable]
public class Test {
    [SerializeField] private string aaa;
    [SerializeField] private string bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:{bbb}";
    }
}
var json = "{\"aaa\":\"test1\", \"ccc\":\"test2\"}";
var test = JsonUtility.FromJson<Test>(json);
Debug.Log(test); // aaa:test1, bbb:

ジェネリクスを使ったクラスのデシリアライズ

これはうまくいった。よかった。
これ上手くいかなかったら使用見送るとこだった…

[Serializable]
public class Test<T> {
    [SerializeField] private string aaa;
    [SerializeField] private T bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:[{bbb}]";
    }
}

[Serializable]
public class Test2 {
    [SerializeField] private string ccc;
    [SerializeField] private string ddd;

    public override string ToString() {
        return $"ccc:{ccc}, ddd:{ddd}";
    }
}
var json = "{\"aaa\":\"test1\", \"bbb\":{\"ccc\":\"test2\", \"ddd\":\"test3\"}}";
var test = JsonUtility.FromJson<Test<Test2>>(json);
Debug.Log(test); // aaa:test1, bbb:[ccc:test2, ddd:test3]

結論

ギリ使えそう。
ただ、パラメータ不一致の場合に空文字だったりnullになったりするから何かしら必須の箇所はNullチェックする方法は考えないといけなさそう。

Nullチェックしてエラーを吐くようにする

こんな感じの作れば、デシリアライズする際にnullを許容しない変数がnullや空文字の場合、エラーにすることはできる。
もうちょい調整すればサーバーレスポンスのデシリアライザとして使えそうな気がしなくもない。

// カスタムアトリビュート作成
[System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public class NotNull : Attribute {
}

// これを使ってデシリアライズする
public class JSONDeserializer {
    public static T FromJSON<T>(string json) {
        var res = JsonUtility.FromJson<T>(json);
        var _type = res.GetType();
        // とりあえずprivateな変数だけ。publicも見たりする場合多分ここの処理は変更が必要になる
        var fields = _type.GetFields( BindingFlags.NonPublic | BindingFlags.Instance);
        foreach (var field in fields) {
            var attr = field.GetCustomAttribute(typeof(NotNull));
            if (attr == null) {
                continue;
            }

            var val = field.GetValue(res);

            if (val == null || string.IsNullOrEmpty(val.ToString())) {
                throw new Exception("えらーだよ");
            }
        }
        return res;
    }   
}

[Serializable]
public class Test {

    [SerializeField][NotNull] private string aaa;
    [SerializeField][NotNull] private string bbb;

    public override string ToString() {
        return $"aaa:{aaa}, bbb:[{bbb}]";
    }
}

var json = "{\"aaa\":\"test1\", \"bbb\":{\"ccc\":\"test2\", \"ddd\":\"test3\"}}";
var test = JSONDeserializer.FromJSON<Test>(json); //ここでException「えらーだよ」がthrowされる。
Debug.Log(test); // ここまで到達しない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む