テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】新しいインプットシステムで、バーチャルパッドに対応させる

f:id:tsubaki_t1:20191014002517g:plain

バーチャルパッドに対応させる

 新しいInput Systemでバーチャルパッドを作ってみます。モバイルでは殆どの環境ではゲームパッドもキーボードもマウスも繋がっていないので、バーチャルパッドは悪い選択肢ではないと思います。特にカメラが追跡するタイプのサードパーソンゲームでは。

 今回はゲームパッドの入力をオーバーライドしてUIからの操作を注入するアプローチをとります。前提としてゲームがNew Input Systemでゲームパッドに対応している必要があります。今回のゲームの場合「Leftスティックで移動」「Westボタンで弾が出る」という操作を事前に実装し、そのゲームにバーチャルパッド対応を行います。

f:id:tsubaki_t1:20191014004033j:plain
ActionMapsを定義して、ゲームパッドとキーボード操作に対応させる

 なお、このバーチャルパッドは現行主流の押した位置からの差分ではなく、一世代古い固定位置からのバーチャルパッドです。

手順1:UIを作る

 最初にUIのレイアウトを決めます。バーチャルスティック一つにボタンが二つといった感じでしょうか。アンカーも使って画面サイズが変わってもちゃんと追随できるようにしておきます。このUIはボタンで作っておくと、実際にタッチさせているかどうかが視覚的に分かりやすくて良いです。スティックは親を作っておくと座標を動かしやすくて良いです。  

f:id:tsubaki_t1:20191014005157j:plain
UIの構成

 ゲームを再生してみるとUIが反応しないかもしれません。これはEventSystemに古いInput Systemのものを使用している為です。StandaloneInputModuleInputSystemUIInputModuleに変更してやれば使用可能になります。

f:id:tsubaki_t1:20191014005941j:plain
EventSystemを新しいInputSystemに対応させる

手順2:UIのボタンを押したら弾を出す

 「Westボタンで弾が出る」の動作を、UIのボタンを押したら射撃を行うようにします。正確にはボタンのタップに合わせてWestボタンのステータスを更新するだけです。結果としてUIのボタンを押すと弾が出ます。

  1. UIのWestボタンOnScreenButtonコンポーネントを追加
  2. Control PathにButton West[GamePad]を選択

 これでUIのボタンを押せばButton Westが押された事になります。

 一点注意としては、このボタンのタップ判定はButtonのIntractableではなくImageのRaycast Targetが使用される点です。なのでUIを一気に無効化する場合はCanvasGroupのBlock Raycaster等を使用します。

f:id:tsubaki_t1:20191014011821g:plain
ボタンを押したら弾が出る

手順3:スティックを動かしたら動く

 「Leftスティックで移動」の動作を、UIのバーチャルスティックを動かしたら動く形に変更します。

  1. UIのスティック(ドラッグで動くUI)にOnScreenStickコンポーネントを追加
  2. Control PathにLeft Stick[GamePad]を選択

 これでスティックを動かせばプレイヤーが動くようになります。あとはMovementRangeで感度を調整したりします。

f:id:tsubaki_t1:20191014013227j:plain
コンポーネントの設定

オマケ:ボタン操作でプレイヤーを動かす

 OnScreenButtonではゲームパッドのボタンだけでなくキー入力も上書き出来るので、シミュレーションで「上」「下」「左」「右」といった厳密な操作が必要な場合は、ボタンとキーを上書きするのも面白いかもしれません。

f:id:tsubaki_t1:20191014012733g:plain
スティックではなくボタンで動かす

f:id:tsubaki_t1:20191014012827j:plain
ボタンにキー操作を割り当てる

関連

tsubakit1.hateblo.jp

【Unity】新・新しいInput Systemの使い方(Inputsystem ver 1.0版)

以前書いた新しいInput Systemの記事の書き直しです。

新しいInput System(1.0)

 Unity 2019.3にて、新しいInput Systemのバージョンが1.0になりました。まぁ、まだPreviewなんですが。とはいえ1.0になったのでソコまでAPIが変化することは無いだろうと期待して、使い方的な記事を書いてみます。

f:id:tsubaki_t1:20191012195650j:plain
InputSystemもついにVer 1.0に…

導入

  1. Window > Package Managerでパッケージマネージャーを開く
  2. AdvanceShow Preview Packagesを有効にする
  3. Input System を選択して Installを押す
  4. PlayerSetting > Player > Active Input HandlingInput Manager(Old)からInput System Package に変更
  5. Unityエディターを再起動

f:id:tsubaki_t1:20191012200534j:plain
InputSystemの切り替えは勝手に行われている事もある

作るもの

 左右に移動してジャンプする…という超簡単な動作を作ります。

f:id:tsubaki_t1:20191013023755g:plain
左右に動いてジャンプするだけ

基本的な流れは下の通り。

  1. InputActionで、プレイヤーが行う操作とキーの割り当てを行う
  2. スクリプトでキー操作を受け取る処理を記述

以前の「キーの入力状態を取得して操作を記述する」と比較すると少し抽象的になっています。

手順1:Input Actionsを作る

 まずInputActionsを作ります。無くても使おうと思えば使えますが(例えばUnityEngine.InputSystem.Gamepad.current.leftStick等で)これをベースに作ると途中から辛くなってくるので、最初にInput Actionsを作ってしまいます。

 Input Actionsは、特定のアクションにどういった操作を割り当てるのかを定義するファイルです。InputSystemではInputActionsで定義したアクションに対して、スクリプトを割り当てるイメージで使えます。

f:id:tsubaki_t1:20191012203506j:plain
InputActionの定義内容

 まずはファイルを生成します。

  1. Assets > Create > Input ActionsでInputActionsを作成。ファイル名はPlayerActにする。
  2. PlayerActiを選択し、Generate C# Classにチェックを入れる。
  3. PlayerActiEdit Assetを選択。

 中身を設定していきます。アクション名を登録し、ActionTypeで入力が返す値を設定する感じです。

  1. ActionMap+をクリック。名前は横スクロールの操作なのでPlatformActionに設定。
  2. Actions+をクリックしてアクションを二つ作成、名前は移動操作の「Move」とジャンプの「Jump」に設定。
  3. MoveのActionTypeをValueに変更、Control TypeはVector2を設定。
  4. JumpのActionTypeをValueに変更、ControlTypeはButtonを設定。

f:id:tsubaki_t1:20191013031329j:plain
アクションを作成

 アクションにキー操作を登録します。今回はキーボード入力操作とゲームパッドの操作を登録します。キーボード入力は複数のキー入力を一つの入力に統合する2D Vector Compositeを使ってまとめます。

  1. Moveの右にある+を押しAdd Bindingを選択。BindingのPathをD-Pad[GamePad]を選択。
  2. Moveの右にある+を押しAdd 2D Vector Compositeを選択。
    UpW [Keyboard]を選択。 DownS [Keyboard]を選択。
    LeftA [Keyboard]を選択。 RightD [Keyboard]を選択。
  3. Jumpの右にある+を押し、Add Bindingを選択。
    BindingのPathにButton West[GamePad]を選択。
  4. Jumpの右にある+を押し、Add Bindingを選択。
    BindingのPathにSpace [Keyboard]を選択。
  5. Save Assetを選択

f:id:tsubaki_t1:20191013032046j:plain
InputActionsの設定

 次は作成した設定を使用してキャラクターを動かします。

手順2:キャラクターを動かす(コールバックで動かす場合)

 まずコールバックベースで動かすアプローチについてです。コールバックはInputActionsが自動で生成してくれるコードを使用して実現します。コードは指定が無ければInputActionと同じフォルダに生成されます。

 コードにはファイル名+ActionMapというインターフェースが含まれており、これを継承したクラスをActionMapに登録すれば、入力が入る度にコールバックが呼ばれるようになります。入力時のパラメーターはcontext.ReadValue<T>()で取得します。TがInputActionsのControlTypeと一致していないと動かないので注意が必要です。またControlTypeは実態と型が一致していない事もあるので、そのあたりも注意が必要です。例えばAxisやButtonはfloatです。

 新しいインプットシステムは、基本的にinput.Enable()input.Disable()が必要です。それと破棄時にはinput.Dispose()した方が良さそな気配があります。

public class MovePlayer : MonoBehaviour, PlayerAct.IPlatformActionActions
{
    PlayerAct.PlatformActionActions input;

    [SerializeField] MoveComponent move;
    float horizontal;

    void Awake()
    {
        // インプットを生成して、自身をコールバックとして登録
        input = new PlayerAct.PlatformActionActions(new PlayerAct());
        input.SetCallbacks(this);
    }

    // インプットの有効・無効化
    void OnDestroy() => input.Disable();
    void OnEnable() => input.Enable();


    void OnDisable() => input.Disable();
    void Update() => move.MoveHorizontal(horizontal);

    // --------------
    // コールバック
    // --------------
    public void OnJump(InputAction.CallbackContext context)
    {
        move.Jump();
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        // 押しっぱなしの動作は、直接オブジェクトを動かすのではなく方向性のみを登録する
        horizontal = context.ReadValue<Vector2>().x;
    }
}

 ここで注意すべきは、このイベントは「値の変化時に呼ばれるっぽい」という点です。そのためMoveアクション(WASDキーにバインド)のような常に押し続ける操作はすぐに動きを停止してしまいます。これは値の変化を変数に格納し、後程Updateで反映することで回避出来ます。これバグかと思ったら仕様っぽいです。

 またコールバックは「一フレームに複数呼ばれる」事があります。New Input Systemはフレームの間の入力も取得する事ができます。コールバックは設定のタイミングで一気に処理されますが、入力時の時間はcontext.timeで確認出来ます。これをうまく使うと、基本的にフレームを落としても滑らかな操作といった事が可能かもしれません。

https://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20190108/20190108222131.gif

手順2:キャラクターを動かす(ポーリングして動かす場合)

 コールバックの動作は便利ではありますが面倒くさいという点も確かにあります。いくつかのゲームは普通にUpdateのタイミングでプレイヤーが責任持って入力を取得する…といったモノの方が好ましいです。ということで、今度はポーリングスタイルで入力を取得します。

 使う場合は単純にActionMapのActionからReadValue<T>()で値を取得するだけです。

public class MovePlayer2 : MonoBehaviour
{
    [SerializeField] MoveComponent move;

    // インプットの登録と破棄
    PlayerAct input;
    void Awake() => input = new PlayerAct();
    void OnDisable() => input.Disable();

    // インプットの有効・無効化
    void OnDestroy() => input.Disable();
    void OnEnable() => input.Enable();


    void Update()
    {
        // スティックの移動を取得して動かす
        var velocity = input.PlatformAction.Move.ReadValue<Vector2>();
        move.MoveHorizontal(velocity.x);

        // ジャンプボタンが押されているか判定して動かす
        var isJumpButtonPressed = (input.PlatformAction.Jump.ReadValue<float>() >= InputSystem.settings.defaultButtonPressPoint);
        if (isJumpButtonPressed)
            move.Jump();
    }
}

 仕様かバグなのか微妙ですが、一つ注意点として「Interactions」という入力の動作をフィルタリングして特定の動作を行わないとアクションを呼ばない設定があるのですが、これが設定されてるとうまく動かない事があります。

f:id:tsubaki_t1:20191013040348j:plain
Jumpの場合は付けてると便利だけど、ポーリングに使うとジャンプ出来なくなる設定

 もしコールバックのように一フレーム内で起こった入力をすべて取得したい場合、下のような記述で取得できます。InputStateHistory recordsで観測するアクションを指定し、records.StartRecordingでアクションを格納していきます。なおInteractionsのようなアクションをフィルタする機能は使えないっぽいです。ストリームの値を読んでるだけなので是非もないね。

public class MovePlayer3 : MonoBehaviour
{
    [SerializeField] MoveComponent move;

    // インプットの登録と破棄
    PlayerAct input;
    InputStateHistory records;

    void Awake()
    {
        input = new PlayerAct();
        records = new InputStateHistory(input.PlatformAction.Jump.controls);
        records.historyDepth = 16;
    }
    void OnDestroy()
    {
        records.Dispose();
        input.Disable();
    }

    // インプットの有効・無効化
    void OnEnable() => records.StartRecording();
    void OnDisable() => records.StopRecording();

    void Update()
    {
        foreach (var record in records)
        {
            var isJumpPressed = record.ReadValue<float>() >= InputSystem.settings.defaultButtonPressPoint;
            if (isJumpPressed)
                move.Jump();
        }
    }
}

 以前はUnsafeを要求していたので、それと比べれば大分楽に使えるようになりましたが、2D Vector Compositeで使用するとうまく動作しなかったり、時々シャックリを起こしたように入力が取れなかったり、何となく妙な癖があります。

キーコンフィグ

動的にアクションに割り当てたキー操作を変更したり出来ます。

// ジャンプの操作にFキーを追加
input = new PlayerAction();
input.Move.Jump.AddBinding("<Keyboard>/f");

補足

 なおPlayerInputという簡単に使用できるハイレベルAPIが用意されていますが、これはUnity 2019.3では期待通りに動作しませんでした。正確にはUnityEventを使用するケースで入力内容を取得できません。同梱のサンプルも動作しないのでバグと思われます(2019.2では動作します)。

Unity 2019.3 b7だと正常に動作しました

関連

今回の記事が面倒くさいと感じた人向け

tsubakit1.hateblo.jp

【Unity】Burstコンパイラでルックアップテーブルを使用する

f:id:tsubaki_t1:20191011215417j:plain

ルックアップテーブルを使おう

ルックアップテーブル:複雑な計算処理を単純な配列の参照処理で置き換えて効率化を図るために作られた、配列や連想配列などのデータ構造のことをいう。(Wikipediaより)

 事前計算を使用するというのは割とありがたいアプローチの一つです。例えば角度からベクトルを計算したい時、角度をラジアンに変換して云々という処理を毎回じっこうせずとも、特定の要素にアクセスすれば値を得られるという形にできます。当然、値の制度は非常に低い物になるでしょうが、それが必要な場合は十分とも言えます。

// 毎回計算する場合
var rad = math.radians(angle);
var velocity = new Vector3(math.cos(rad), math.sin(rad));

// 事前計算した結果を使用する場合
var velocity = AngleToVelocity[angle]

 これをBurstでも使いたいと思いますが、一つ問題があります。Burstはマネージドメモリを使用できないという点です。そのためNativeArrayで定義する必要がありそうに見えます。これは問題ないと言えば問題ないかもしれませんが、やる場合には通常の配列を定義してNativeArrayに変換する流れが必要になってくるので、あまりイケてないように見えます。

Burstでルックアップテーブルを使おう

 先日のUniteの講演で気づいたのですが、どうやら通常のフィールドとして定義した配列を使用できる方法があるみたいです。

 利用できる条件は単純で static readonly な配列は使用できるみたいです。例えば下のように定義しておくと、Burstでも使用することが出来ました。

    public static readonly float2[] AngleToVelocity = new float2[] {
        new float2(0f, 1f),
        new float2(-0.01745241f, 0.9998477f),
        new float2(-0.0348995f, 0.9993908f),
        new float2(-0.05233596f, 0.9986295f),
       .
       .
       .

 注意点としては、BurstとC#で少し挙動が変わるという点です。C#の動作では static readonlyな配列は、中身を変更することが可能です。しかしBurstの場合は変更した中身を無視して最初に定義した数値を使用します。この問題はエディターだと分かりやすく、Burstコンパイルが完了するまでは*1値を書き換えることが可能ですが、Burstのコンパイル完了後はコードに記述した値が使用されます。

f:id:tsubaki_t1:20191011215915j:plain
定義

サンプル

角度の方向に向かってGameObjectを進めます。

using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Burst;
using Unity.Jobs;
using Unity.Collections;

public class MoveByAngle : MonoBehaviour
{
    [Range(0, 359)]
    public int angle;

    [BurstCompile]
    struct MoveTransform : IJobParallelForTransform
    {
        public int angle;
        public void Execute(int index, TransformAccess transform)
        {
            var velocity2D = AngleToVelocity[angle] * 0.1f;
            transform.position += new Vector3(velocity2D.x, velocity2D.y);
        }
    }

    JobHandle handle;

    TransformAccessArray transforms;

    void OnEnable()
    {
        transforms = new TransformAccessArray(1);
        transforms.Add(transform);
    }

    void OnDisable()
    {
        handle.Complete();
        transforms.Dispose();
    }

    void Update()
    {
        handle.Complete();
        handle = new MoveTransform { angle = angle }.Schedule(transforms, handle);
        JobHandle.ScheduleBatchedJobs();
    }

    public static readonly float2[] AngleToVelocity = new float2[] {
        new float2(0f, 1f),
        new float2(-0.01745241f, 0.9998477f),
        new float2(-0.0348995f, 0.9993908f),
        new float2(-0.05233596f, 0.9986295f),
        new float2(-0.06975648f, 0.9975641f),
        new float2(-0.08715575f, 0.9961947f),
        new float2(-0.1045285f, 0.9945219f),
        new float2(-0.1218694f, 0.9925461f),
        new float2(-0.1391731f, 0.9902681f),
        new float2(-0.1564345f, 0.9876884f),
        new float2(-0.1736482f, 0.9848077f),
        new float2(-0.190809f, 0.9816272f),
        new float2(-0.2079117f, 0.9781476f),
        new float2(-0.2249511f, 0.9743701f),
        new float2(-0.2419219f, 0.9702957f),
        new float2(-0.2588191f, 0.9659258f),
        new float2(-0.2756374f, 0.9612617f),
        new float2(-0.2923717f, 0.9563047f),
        new float2(-0.309017f, 0.9510565f),
        new float2(-0.3255681f, 0.9455186f),
        new float2(-0.3420202f, 0.9396926f),
        new float2(-0.3583679f, 0.9335804f),
        new float2(-0.3746066f, 0.9271839f),
        new float2(-0.3907311f, 0.9205049f),
        new float2(-0.4067367f, 0.9135454f),
        new float2(-0.4226183f, 0.9063078f),
        new float2(-0.4383712f, 0.8987941f),
        new float2(-0.4539905f, 0.8910065f),
        new float2(-0.4694716f, 0.8829476f),
        new float2(-0.4848097f, 0.8746197f),
        new float2(-0.5f, 0.8660254f),
        new float2(-0.5150381f, 0.8571673f),
        new float2(-0.5299193f, 0.8480481f),
        new float2(-0.5446391f, 0.8386706f),
        new float2(-0.5591929f, 0.8290375f),
        new float2(-0.5735765f, 0.819152f),
        new float2(-0.5877853f, 0.809017f),
        new float2(-0.601815f, 0.7986355f),
        new float2(-0.6156614f, 0.7880108f),
        new float2(-0.6293204f, 0.7771459f),
        new float2(-0.6427876f, 0.7660444f),
        new float2(-0.6560591f, 0.7547096f),
        new float2(-0.6691306f, 0.7431449f),
        new float2(-0.6819984f, 0.7313536f),
        new float2(-0.6946583f, 0.7193398f),
        new float2(-0.7071068f, 0.7071067f),
        new float2(-0.7193398f, 0.6946583f),
        new float2(-0.7313538f, 0.6819984f),
        new float2(-0.7431449f, 0.6691306f),
        new float2(-0.7547097f, 0.656059f),
        new float2(-0.7660445f, 0.6427876f),
        new float2(-0.777146f, 0.6293204f),
        new float2(-0.7880108f, 0.6156614f),
        new float2(-0.7986355f, 0.601815f),
        new float2(-0.8090171f, 0.5877851f),
        new float2(-0.819152f, 0.5735765f),
        new float2(-0.8290376f, 0.5591928f),
        new float2(-0.8386706f, 0.544639f),
        new float2(-0.8480482f, 0.5299191f),
        new float2(-0.8571673f, 0.5150381f),
        new float2(-0.8660254f, 0.5f),
        new float2(-0.8746197f, 0.4848096f),
        new float2(-0.8829477f, 0.4694715f),
        new float2(-0.8910065f, 0.4539905f),
        new float2(-0.8987942f, 0.438371f),
        new float2(-0.9063078f, 0.4226182f),
        new float2(-0.9135455f, 0.4067366f),
        new float2(-0.9205048f, 0.3907312f),
        new float2(-0.9271839f, 0.3746065f),
        new float2(-0.9335805f, 0.3583679f),
        new float2(-0.9396927f, 0.34202f),
        new float2(-0.9455186f, 0.3255681f),
        new float2(-0.9510565f, 0.309017f),
        new float2(-0.9563048f, 0.2923716f),
        new float2(-0.9612617f, 0.2756373f),
        new float2(-0.9659258f, 0.258819f),
        new float2(-0.9702958f, 0.2419218f),
        new float2(-0.9743701f, 0.224951f),
        new float2(-0.9781476f, 0.2079117f),
        new float2(-0.9816272f, 0.190809f),
        new float2(-0.9848078f, 0.1736481f),
        new float2(-0.9876883f, 0.1564345f),
        new float2(-0.9902681f, 0.1391731f),
        new float2(-0.9925462f, 0.1218693f),
        new float2(-0.9945219f, 0.1045284f),
        new float2(-0.9961946f, 0.08715588f),
        new float2(-0.9975641f, 0.06975645f),
        new float2(-0.9986296f, 0.05233604f),
        new float2(-0.9993908f, 0.03489941f),
        new float2(-0.9998477f, 0.01745242f),
        new float2(-0.9999999f, 5.960464E-08f),
        new float2(-0.9998477f, -0.01745248f),
        new float2(-0.9993908f, -0.03489959f),
        new float2(-0.9986296f, -0.05233586f),
        new float2(-0.9975641f, -0.06975651f),
        new float2(-0.9961947f, -0.08715594f),
        new float2(-0.9945219f, -0.1045285f),
        new float2(-0.9925462f, -0.1218693f),
        new float2(-0.990268f, -0.1391732f),
        new float2(-0.9876884f, -0.1564347f),
        new float2(-0.9848078f, -0.1736484f),
        new float2(-0.9816272f, -0.1908089f),
        new float2(-0.9781476f, -0.2079117f),
        new float2(-0.97437f, -0.224951f),
        new float2(-0.9702957f, -0.241922f),
        new float2(-0.9659258f, -0.258819f),
        new float2(-0.9612617f, -0.2756375f),
        new float2(-0.9563047f, -0.2923716f),
        new float2(-0.9510565f, -0.3090172f),
        new float2(-0.9455186f, -0.3255682f),
        new float2(-0.9396927f, -0.3420202f),
        new float2(-0.9335804f, -0.3583682f),
        new float2(-0.9271838f, -0.3746067f),
        new float2(-0.9205049f, -0.3907312f),
        new float2(-0.9135454f, -0.4067367f),
        new float2(-0.9063078f, -0.4226184f),
        new float2(-0.8987939f, -0.4383713f),
        new float2(-0.8910066f, -0.4539905f),
        new float2(-0.8829476f, -0.4694716f),
        new float2(-0.8746197f, -0.4848098f),
        new float2(-0.8660254f, -0.5000001f),
        new float2(-0.8571673f, -0.515038f),
        new float2(-0.848048f, -0.5299193f),
        new float2(-0.8386706f, -0.5446391f),
        new float2(-0.8290375f, -0.559193f),
        new float2(-0.8191521f, -0.5735766f),
        new float2(-0.8090171f, -0.5877852f),
        new float2(-0.7986354f, -0.601815f),
        new float2(-0.7880107f, -0.6156617f),
        new float2(-0.777146f, -0.6293204f),
        new float2(-0.7660444f, -0.6427877f),
        new float2(-0.7547095f, -0.656059f),
        new float2(-0.7431448f, -0.6691307f),
        new float2(-0.7313538f, -0.6819984f),
        new float2(-0.7193397f, -0.6946584f),
        new float2(-0.7071068f, -0.7071067f),
        new float2(-0.6946582f, -0.7193398f),
        new float2(-0.6819984f, -0.7313538f),
        new float2(-0.6691306f, -0.7431448f),
        new float2(-0.656059f, -0.7547096f),
        new float2(-0.6427875f, -0.7660446f),
        new float2(-0.6293203f, -0.777146f),
        new float2(-0.6156614f, -0.7880107f),
        new float2(-0.6018149f, -0.7986356f),
        new float2(-0.5877852f, -0.8090171f),
        new float2(-0.5735763f, -0.8191522f),
        new float2(-0.5591928f, -0.8290377f),
        new float2(-0.544639f, -0.8386706f),
        new float2(-0.5299191f, -0.8480481f),
        new float2(-0.515038f, -0.8571672f),
        new float2(-0.5000001f, -0.8660253f),
        new float2(-0.4848095f, -0.8746197f),
        new float2(-0.4694716f, -0.8829476f),
        new float2(-0.4539904f, -0.8910065f),
        new float2(-0.4383711f, -0.8987941f),
        new float2(-0.4226183f, -0.9063078f),
        new float2(-0.4067366f, -0.9135456f),
        new float2(-0.3907309f, -0.9205049f),
        new float2(-0.3746065f, -0.9271837f),
        new float2(-0.3583679f, -0.9335804f),
        new float2(-0.34202f, -0.9396927f),
        new float2(-0.3255681f, -0.9455187f),
        new float2(-0.3090171f, -0.9510566f),
        new float2(-0.2923716f, -0.9563048f),
        new float2(-0.2756374f, -0.9612616f),
        new float2(-0.2588189f, -0.9659259f),
        new float2(-0.2419219f, -0.9702957f),
        new float2(-0.2249511f, -0.9743701f),
        new float2(-0.2079116f, -0.9781476f),
        new float2(-0.1908088f, -0.9816272f),
        new float2(-0.1736483f, -0.9848078f),
        new float2(-0.1564344f, -0.9876882f),
        new float2(-0.139173f, -0.9902682f),
        new float2(-0.1218693f, -0.9925461f),
        new float2(-0.1045285f, -0.9945219f),
        new float2(-0.08715564f, -0.9961947f),
        new float2(-0.06975647f, -0.9975641f),
        new float2(-0.05233581f, -0.9986296f),
        new float2(-0.03489945f, -0.9993908f),
        new float2(-0.01745246f, -0.9998477f),
        new float2(8.742278E-08f, -1f),
        new float2(0.01745239f, -0.9998477f),
        new float2(0.03489963f, -0.9993908f),
        new float2(0.05233599f, -0.9986296f),
        new float2(0.06975664f, -0.9975641f),
        new float2(0.08715582f, -0.9961947f),
        new float2(0.1045284f, -0.9945219f),
        new float2(0.1218695f, -0.9925461f),
        new float2(0.1391731f, -0.9902682f),
        new float2(0.1564344f, -0.9876882f),
        new float2(0.1736485f, -0.9848076f),
        new float2(0.190809f, -0.9816272f),
        new float2(0.207912f, -0.9781474f),
        new float2(0.2249513f, -0.9743699f),
        new float2(0.2419218f, -0.9702957f),
        new float2(0.2588193f, -0.9659257f),
        new float2(0.2756375f, -0.9612616f),
        new float2(0.2923715f, -0.9563048f),
        new float2(0.3090172f, -0.9510564f),
        new float2(0.3255683f, -0.9455185f),
        new float2(0.3420204f, -0.9396925f),
        new float2(0.3583681f, -0.9335804f),
        new float2(0.3746066f, -0.9271837f),
        new float2(0.3907313f, -0.9205048f),
        new float2(0.4067367f, -0.9135454f),
        new float2(0.4226183f, -0.9063078f),
        new float2(0.4383713f, -0.8987941f),
        new float2(0.4539905f, -0.8910065f),
        new float2(0.4694717f, -0.8829476f),
        new float2(0.4848097f, -0.8746197f),
        new float2(0.5f, -0.8660253f),
        new float2(0.5150382f, -0.8571672f),
        new float2(0.5299193f, -0.8480481f),
        new float2(0.5446389f, -0.8386706f),
        new float2(0.559193f, -0.8290374f),
        new float2(0.5735764f, -0.819152f),
        new float2(0.5877855f, -0.8090168f),
        new float2(0.601815f, -0.7986356f),
        new float2(0.6156614f, -0.7880108f),
        new float2(0.6293206f, -0.7771457f),
        new float2(0.6427876f, -0.7660444f),
        new float2(0.6560589f, -0.7547096f),
        new float2(0.6691308f, -0.7431448f),
        new float2(0.6819984f, -0.7313536f),
        new float2(0.6946586f, -0.7193396f),
        new float2(0.7071069f, -0.7071067f),
        new float2(0.7193398f, -0.6946584f),
        new float2(0.7313538f, -0.6819981f),
        new float2(0.7431449f, -0.6691306f),
        new float2(0.7547097f, -0.6560589f),
        new float2(0.7660446f, -0.6427875f),
        new float2(0.777146f, -0.6293204f),
        new float2(0.788011f, -0.615661f),
        new float2(0.7986357f, -0.6018147f),
        new float2(0.8090169f, -0.5877855f),
        new float2(0.8191521f, -0.5735763f),
        new float2(0.8290375f, -0.5591928f),
        new float2(0.8386708f, -0.5446388f),
        new float2(0.8480482f, -0.5299189f),
        new float2(0.8571674f, -0.515038f),
        new float2(0.8660255f, -0.5f),
        new float2(0.8746197f, -0.4848095f),
        new float2(0.8829475f, -0.4694716f),
        new float2(0.8910066f, -0.4539902f),
        new float2(0.8987941f, -0.4383709f),
        new float2(0.9063078f, -0.4226182f),
        new float2(0.9135455f, -0.4067366f),
        new float2(0.9205048f, -0.3907312f),
        new float2(0.9271839f, -0.3746064f),
        new float2(0.9335805f, -0.3583677f),
        new float2(0.9396926f, -0.34202f),
        new float2(0.9455186f, -0.3255682f),
        new float2(0.9510564f, -0.3090171f),
        new float2(0.9563048f, -0.2923715f),
        new float2(0.9612618f, -0.2756373f),
        new float2(0.9659258f, -0.258819f),
        new float2(0.9702958f, -0.2419214f),
        new float2(0.9743701f, -0.2249513f),
        new float2(0.9781476f, -0.207912f),
        new float2(0.9816273f, -0.1908089f),
        new float2(0.9848078f, -0.1736481f),
        new float2(0.9876884f, -0.1564341f),
        new float2(0.9902681f, -0.1391728f),
        new float2(0.9925462f, -0.1218692f),
        new float2(0.994522f, -0.1045284f),
        new float2(0.9961947f, -0.0871557f),
        new float2(0.997564f, -0.06975651f),
        new float2(0.9986296f, -0.05233574f),
        new float2(0.9993908f, -0.03489923f),
        new float2(0.9998477f, -0.01745224f),
        new float2(0.9999999f, 5.960464E-08f),
        new float2(0.9998477f, 0.01745224f),
        new float2(0.9993908f, 0.03489977f),
        new float2(0.9986295f, 0.05233622f),
        new float2(0.9975641f, 0.06975663f),
        new float2(0.9961947f, 0.0871557f),
        new float2(0.9945219f, 0.1045284f),
        new float2(0.9925461f, 0.1218696f),
        new float2(0.9902681f, 0.1391733f),
        new float2(0.9876884f, 0.1564345f),
        new float2(0.9848077f, 0.1736486f),
        new float2(0.9816272f, 0.190809f),
        new float2(0.9781475f, 0.207912f),
        new float2(0.97437f, 0.2249513f),
        new float2(0.9702957f, 0.241922f),
        new float2(0.9659258f, 0.2588195f),
        new float2(0.9612616f, 0.2756377f),
        new float2(0.9563048f, 0.2923715f),
        new float2(0.9510565f, 0.3090172f),
        new float2(0.9455186f, 0.3255681f),
        new float2(0.9396925f, 0.3420205f),
        new float2(0.9335804f, 0.3583682f),
        new float2(0.9271838f, 0.3746067f),
        new float2(0.9205048f, 0.3907313f),
        new float2(0.9135455f, 0.4067366f),
        new float2(0.9063078f, 0.4226182f),
        new float2(0.8987939f, 0.4383714f),
        new float2(0.8910065f, 0.4539906f),
        new float2(0.8829475f, 0.4694717f),
        new float2(0.8746198f, 0.4848096f),
        new float2(0.8660255f, 0.4999999f),
        new float2(0.8571672f, 0.5150383f),
        new float2(0.848048f, 0.5299194f),
        new float2(0.8386706f, 0.5446391f),
        new float2(0.8290375f, 0.5591929f),
        new float2(0.8191521f, 0.5735763f),
        new float2(0.8090168f, 0.5877855f),
        new float2(0.7986354f, 0.6018151f),
        new float2(0.7880107f, 0.6156615f),
        new float2(0.7771457f, 0.6293207f),
        new float2(0.7660446f, 0.6427875f),
        new float2(0.7547097f, 0.6560588f),
        new float2(0.7431448f, 0.6691307f),
        new float2(0.7313537f, 0.6819984f),
        new float2(0.7193395f, 0.6946587f),
        new float2(0.7071066f, 0.707107f),
        new float2(0.6946582f, 0.71934f),
        new float2(0.6819983f, 0.7313538f),
        new float2(0.6691306f, 0.7431449f),
        new float2(0.6560587f, 0.7547098f),
        new float2(0.6427874f, 0.7660446f),
        new float2(0.6293203f, 0.7771461f),
        new float2(0.6156614f, 0.7880108f),
        new float2(0.601815f, 0.7986355f),
        new float2(0.5877853f, 0.8090169f),
        new float2(0.5735762f, 0.8191522f),
        new float2(0.5591927f, 0.8290377f),
        new float2(0.5446389f, 0.8386706f),
        new float2(0.5299193f, 0.8480481f),
        new float2(0.5150382f, 0.8571672f),
        new float2(0.4999998f, 0.8660255f),
        new float2(0.4848095f, 0.8746198f),
        new float2(0.4694715f, 0.8829476f),
        new float2(0.4539901f, 0.8910067f),
        new float2(0.4383713f, 0.898794f),
        new float2(0.422618f, 0.9063079f)
    };
}

関連

www.youtube.com

*1:エディターでBurstを実行する場合、コンパイル完了まで通常のC#の処理が実行される

【Unity】LWRPで特定のモデルのみポストプロセスがかからないようにする

f:id:tsubaki_t1:20191010195816j:plain
一部のモデルにだけ、色あせるポストプロセスをかけない
昨日の応用で、一部のモデルにだけポストプロセスがかからないようにします。

一部のモデルだけポストプロセスの影響をかけないようにする

 以前に紹介した方法はカメラのスタックが現在使えない関係上、使用できなくなりました。そのため、一部にのみポストプロセスをかけないといった設定を実現するには、少しアプローチを変える必要があります。

 とはいえ悪い話ではありません。以前のアプローチはレイヤーを何度も変える関係上、パフォーマンス(特にPhysics関連のコンポーネントを持っている場合)に影響がある可能性がありましたが、今回はレイヤーを何度も変えないので多分問題は無いでしょう。

 基本的には昨日のアプローチと殆ど同じです。つまり レンダリングしてポストプロセス描画後に特定のレイヤーに所属するメッシュを描画する という事です。ただし今回は不透明を指定しCameraのDepthを上書きしません。これにより 奥行判定も綺麗に出る事が期待出来ます。

f:id:tsubaki_t1:20191010200823j:plain
ポストプロセスの影響を受けるモデルにさえぎられても、ちゃんと描画できている

手順

 手順は殆どが昨日の焼き直しです。

  1. Create > Rendering > ***Pipeline > Forward Renderer でCustom Forward Rendererアセットを作ります。その後、Lightweight Renderer Pipeline AssetのRender TypeをCustomに設定し、Custom Forward Rendererアセットを登録。
  2. Project Settings> Tag and Layer を選択し、WithoutPostProcess(任意の名前)的なレイヤーを作る。
  3. ポストプロセス対象外にしたいGameObjectをWithoutPostProcess所属にする
  4. 1で作成したCustom Forward Rendererアセットを選択。
  5. Default Layer Mask から WithoutPostProcess を外す。
  6. Render Features+ を押す。追加するパスは Rendere Object を選択。
  7. NameWOPP(任意)に変更。
  8. EventAfter Rendering に変更。

f:id:tsubaki_t1:20191010201459p:plain
レイヤーを追加

f:id:tsubaki_t1:20191010201922j:plain
Custom Forward Rendererの設定を変更

 半透明も使用したい場合、追加でRenderer Feature+を押し、パスを追加。上の手順の7.8.を設定後、Filters>QueueTransparentにすればよいです。

f:id:tsubaki_t1:20191010202410j:plain
半透明がある場合でも問題なく表現出来ている

注意点

「ポストプロセスの影響を受けない」は、単純なカラーコレクション等なら多分問題はないのですが、DOFやBloomといった色を滲ませる表現がある場合は微妙な表現になるかもしれません。