色味の調整

editor_ios_color

Unity Editor上で見るのと、iOSに書き出してみたら色が違った。
データ自体はpsdだけど、ためしにpngにしてカラープロファイルを切っても一緒だった。なにが悪いんでしょうか。。?ひょっとしてディスプレーのカラープロファイルの影響でそう見えただけ?
とりあえずデザインデータを書き換えずになにかできるかなと調べていたらColor Collection CurvesColorSuiteというライブラリを見つけました。
Continue…

‘.’ is not a valid texture file name on asset…

‘.’ is not a valid texture file name on asset ‘***’ on material ‘Tree02Mat__UVTest’ of renderer ‘***’. The file will be ignored

Blenderで作った3Dファイルを読み込むとたまにこのエラーが出る。
どうもBlender上で参照しているファイルが、Blenderファイルに埋め込みの場合(外部ファイルでない場合)、Unity側が画像ファイルを見つけられずに困ってしまうらしい。
blender_image_deleteBlender上で画像ファイルを消すには、UV/Image Editorを開いて、下のメニューにあるバツマークをShiftを押しながら押すと消える。そのあと画像のプルダウンから、該当のファイル名の先頭に0(ゼロ)がついていればOK。

BlenderでUVMap編集時の調整

uv_editing

BlenderでUVを編集時になんか同じ点の場所が動いちゃうなーと思ったら、、、

このUVマップを表示するか、3Dにて該当の箇所のみ表示するかの切り替えで片方のみ動くようになった。

Mecanim(Animator) + Script

Mecanimでアニメーションを付けつつ、一部のパーツをスクリプトで制御したいときにちょっとはまりました。スクリプトで制御しても動かない。。
なかなか情報が見つからなかったけど、3Dモデルのアニメーション後の情報は LateUpdate() にて取得できるので、そこで無理やり動かせば動きを制御できるとの情報をゲット。DOTweenで言えば SetUpdate(UpdateType.Late) を使えばOK!でも動きが終わるともとの3Dのアニメーションに戻るのでこれで対応できることは少ないかも。。。
Continue…

回転

Unityでのオイラー角

スクリプトとInspectorの角度が一致しないと思ったら、Unity内ではオブジェクトの傾きはQuaternionで保持しているので、0-360度の範囲を超える情報というのを持っていないようです。
UnityのマニュアルのUnityの回転と向きによると、365度と入れた場合は、5度に置き換わるため、360度+5度という情報は消えてしまうようです。

DOTweenでの回転方向

なぜかDOTweenを使って、DORotateQuaternionをした際に、45と45±360を入れた際に回転方向が逆になった。上記でいうと、360ずらしたものは同じはずなので、向きなどないような気もするけど、、、
Quaternionが複雑なのでどの場合でもこれができるのかはわからないけど、とりあえず回転方向を変えたい場合は360度ずらした数値を入れるとできました。
回転する際には1度角度を0-360の範囲で再設定したほうがいいかもしれません。

DOTweenでの複数回回転

複数回回転するには、720度などと入れても2回転はしません。
そこで、SetLooks(int)とRotateMode.FastBeyond360をつかって、やろうと思いましたが、DORotateで回すと意図しない回り方をすることがあります。
なので、OnCompleteに回転するメソッドを再度呼び出し任意の回数をしたところで抜けるようにしました。
[unitycsharp]
TweenCallback RoundAction = null;
float startRotateAngleX = trans.localEulerAngles.x;

RoundAction = () => {
if (++count > 4) return;

startRotateAngleX += 180f;
trans.DOLocalRotateQuaternion(Quaternion.AngleAxis(startRotateAngleX, Vector3.right), 0.15f).SetEase(Ease.Linear).OnComplete(RoundAction);
};

RoundAction();
[/unitycsharp]

ん〜、これだとイージングがLinerでないと変だし、一瞬止まるのでなんかもっといい方法があるような気がします。。。

アセットバンドルの書き出しがおかしい

ときどきアセットバンドルの書き出しがおかしく、表示がごちゃごちゃに崩れることがある。
おそらく、アセットバンドルのリソースが更新されているにもかかわらず、アプリ側のリソースの使い方が更新されていないような感じで、画面がグチャグチャになる。
iOSでよく起こるけど、大概Unityから再度Xcodeプロジェクトを書き出すと直る。
それでもダメな場合は、Unityを再起動。
わりと頻繁に起こるんだけど、僕だけ?

uGUIのサイズ調整

低スペックの端末(Android)でuGUIのテクスチャ素材が多いため落ちる現象が起きました。
本来であればデザイン素材の見直しや、オブジェクトのロード、破棄するタイミングから見直しをするべきなのですが、どうしても時間がなく、テストフェーズも終わってしまったので下記のような対応をしてみた記録。。。

まずはたくさん使われているuGUIのテクスチャのインポートセッティング。
texture_import_settings
パッキングタグを設定しつつ、Max Sizeでそのテクスチャのサイズを小さくなるように設定。
本来、パッキングタグをつけてしまえば同じパッキングタグ同士がアトラス化され、2のべき乗のサイズになるので、Max Sizeを触る意味はないのですが、直接画像の解像度を変更するのはちょっとイヤなので、、、ここで無理やりサイズ調整。
サイズ調整できるのは2のべき乗なので、あまり小さくなってしまうものはサイズを変えず、うまく小さくできそうなものだけ変更。
sprite_packer
そして、Sprite Packerにてすべての画像を確認し、余白が大きいアトラスがあれば頑張ってサイズが小さくなるように、素材を1つ1つ調整。
逆に、いくらMax Sizeを小さくしてもアトラスが小さくならないものは意味がない。
あまり良くない方法ですが、、、緊急対応ということで。

TouchScriptでの領域の制限

3D空間のタッチやフリックなどのジェスチャーに便利なTouchScriptで、部分的にタッチやジェスチャーを判定する領域を制限したかったので調べてみた。
どの空間(レイヤー)でジェスチャーをジャッジするかというのが、TouchScript.Layersパッケージにあって、主に

  • CameraLayer
  • CameraLayer2D
  • FullscreenLayer
  • UILayer
  • この4つ。
    CameraLayerはRayを飛ばして、3D空間のオブジェクトにヒットしているかの判定をする。
    CameraLayer2Dは2Dアプリ用。
    FullscreenLayerは画面にタッチしてれば当たり判定が入る。
    UILayerはuGUIのSpriteに対してヒットすれば判定が入る。

    タッチ領域の制限にはLayer Maskというプロパティがあるので、これをつかってもできるかも??ですが、今回はUILayerを使うことに。

    touch_script_uilayer

    こんな感じでUILayerのGameObjectか、その下の階層にImageなどを配置してやるとその範囲でジェスチャーを拾ってくれる。
    (*追記17.01.19 : UILayerはこの画像の構造だと動かなくなったので、Canvasなど上のGameObjectに当てた方がいいっぽい)
    ちなみにTapGestureをFlickGestureの上に置いてしまうと、先に判定が入ってしまいフリックが拾いづらいので注意。
    あとはこんな風に自作のコンポーネントのGestureControllerにてジェスチャーを登録すれば完了。

    [unitycsharp]
    /// <summary>
    /// ジェスチャー判断用。
    /// </summary>
    [SerializeField]
    FlickGesture flickGesture;
    [SerializeField]
    TapGesture tapGesture;

    /// <summary>
    /// OnEnable.
    /// </summary>
    void OnEnable() {
    this.flickGesture.Flicked += this.OnFlicked;
    this.tapGesture.Tapped += this.OnTapped;
    }

    /// <summary>
    /// OnDisable.
    /// </summary>
    void OnDisable() {
    this.flickGesture.Flicked -= this.OnFlicked;
    this.tapGesture.Tapped -= this.OnTapped;
    }
    [/unitycsharp]

    文字列からstatic/classプロパティの取得

    staticプロパティを文字列から取得する方法がわからなかったので調べてみた。
    ついでに、文字列でオブジェクトのプロパティの取り出しとメソッドの実行も。

    [unitycsharp]
    class TestClass {
    public static string StaticPropName = "StaticValue";
    public int propName = 100;
    public string TestFunc(int num) {
    return "TestFuncValue : " + num;
    }
    }

    TestClass test = new TestClass();
    Type testType = test.GetType();
    print(testType.GetField("propName").GetValue(test));
    // 出力 : 100

    print(testType.GetMethod("TestFunc").Invoke(test, new object[]{ 777 }));
    // 出力 : TestFuncValue : 777

    Type typeOfTestClass = typeof(TestClass);
    print(typeOfTestClass.GetField("StaticPropName").GetValue(typeOfTestClass));
    // 出力 : StaticValue
    [/unitycsharp]