強火で進め

このブログではプログラム関連の記事を中心に書いてます。

【Unity】Collider 2D の Layer Overrides

動作検証環境

  • Unity 2022.2.0f1

はじめに

Rigidbody2D と Box Collider 2D など、 XXX Collider 2D の Inspector に有る Layer Overrides について解説します。

プロパティ

プロパティの説明はこの様になりますがここだけ見てもイマイチ分かりづらいと思いますので次の項目の「解説」と合わせて確認して下さい。

プロパティ名 説明
Layer Override Priority 競合発生時の設定の優先度。
Include Layers 接触が発生するレイヤーを設定。
Exclude Layers 接触が発生しないレイヤーを設定。
Force Send Layers 接触時に力を送るレイヤーを設定。
Force Receive Layers 接触時に力を受けるレイヤーを設定。
Contract Capture Layers キャプチャされるレイヤーを設定。
Callback Layers 他の Collider 2D との衝突時にコールバックを発生されるレイヤーを設定。

解説

A という GameObject に付けられている XXX Collider 2D の Include Layers や Exclude Layers 、それが B という GameObject に付けられている XXX Collider 2D の設定と競合した時の処理のルールはこちら。

  1. A と B の両方が同じルールの場合はそのルールが採用される。
  2. A または B が include (包含) か exclude (除外) を選択している場合はそのルールが採用される。
  3. A と B の両方が include と exclude と異なるルールを選択した場合には Layer Override Priority (プログラムで使う場合は Collider2D.layerOverridePriority )の値が高い方のルールが採用される。
  4. A と B の両方が include と exclude と異なるルールを選択した場合に Layer Override Priority の値が同一の場合には接触は発生しない。

説明用として、以下の様なオブジェクトが配置されているプロジェクトを準備しました。

準備したオブジェクトの色と同じ Layer を準備し、それぞれの色に合わせた Layar を設定しています。

オブジェクト Layer
A Red
B Green
C Blue

Exclude Layers

A の Exclude Layers で Green だけにチェックし、他の Box はデフォルトのままにした場合。

Exclude (除外) に設定した Geen の Layer に属する B には接触しなくなり、存在しないものとして扱われている事が確認できます。床は除外対象では無いので床を透過する事は有りません。

Exclude Layers と Include Layers の組み合わせ

A の Exclude Layers で Green と Blue 、 B の Include (含める) Layers で Red をチェックした場合。

B Include Layers の設定をしているので A と接触しそうに思えますが実際にはルール 4. の「 A と B の両方が include と exclude と異なるルールを選択した場合に Layer Override Priority の値が同一の場合には接触は発生しない。」が適用される為、 B 、 C 共に存在しないものとして扱われます。

追加で B の Layer Override Priority を 1 に変更したい場合。

B との接触が発生する様になりました。これはルール 3. の「 A と B の両方が include と exclude と異なるルールを選択した場合には Layer Override Priority (プログラムで使う場合は Collider2D.layerOverridePriority )の値が高い方のルールが採用される。」が適用された為です。

Force Send Layers

A の Force Send Layers で Green だけにチェックし、他の Box はデフォルトのままにした場合。

A の力( Force )は B だけに送られる( Send) ので移動しますが、 C には力が送られないので移動しない事が確認できます。

Force Receive Layers

A の Force Receive Layers で Green と「床」のレイヤーで有る Defualt だけにチェックし、他の Box はデフォルトのままにした場合。

A は先に落ちた C からの力は受けない(移動しない)。しかし、その後の B の力は受ける為、移動する事が確認できます。

Contract Capture Layers

Contract Capture (キャプチャ契約) Layers は以下の様な API の動作に影響を与えます。チェックが付いてないレイヤーはキャプチャの対象外となり、「接触している」と判定されなくなったり、 OnCollisionEnter2D などのコールバックが呼ばれなくなります。

  • Physics2D.IsTouching
  • Rigidbody2D.IsTouching
  • Collider2D.IsTouching,
  • Physics2D.IsTouchingLayers
  • Rigidbody2D.IsTouchingLayers
  • Collider2D.IsTouchingLayers
  • Physics2D.GetContacts
  • Rigidbody2D.GetContacts
  • Collider2D.GetContacts
  • OnCollisionEnter2D
  • OnCollisionStay2D
  • OnCollisionExit2D
  • OnTriggerEnter2D
  • OnTriggerStay2D
  • OnTriggerExit2D

docs.unity3d.com

Callback Layers

Callback Layers でチェックが付いているレイヤーに属する GameObject の Collider 2D との衝突時にはコールバックを発生させます。 ここの設定に影響を受けるものは以下のものです。

  • OnCollisionEnter2D
  • OnCollisionStay2D
  • OnCollisionExit2D
  • OnTriggerEnter2D
  • OnTriggerStay2D
  • OnTriggerExit2D

docs.unity3d.com

【Unity】 Platform Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Platform Effector 2D は2Dゲームの床を作る時に使うコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Platform Effector 2D の処理対象となる。
Use One Way チェックした時、一方通行の設定が有効。
Use One Way Grouping チェックした時、複数の Collider が使われている時に全ての Collider が一方通行を通過した時のみ地面に着地する。チェックされてない時は通過した Collider のみが地面に着地する。
Surface Arc Use One Way がチェックしされている時のみ有効。地面の範囲を角度で指定。
Use Side Friction チェックした時、横から当たった時に Friction (摩擦)が考慮されます。
Use Side Bounce チェックした時、横から当たった時に Bounce (跳ね返り)が考慮されます。
Side Arc 衝突が発生した時に側面とみなす角度を設定。側面と判定された時には Use Side Friction と Use Side Bounce の設定が反映されます。

解説

Use One Way Grouping

この様なサンプルを準備します。

こういう構成になっていて、

こういう Component を設定しています。

■ Use One Way Grouping にチェックしない時

通過した赤いBoxだけが地面に立ちます。

■ Use One Way Grouping にチェックした時

両方が通過しない場合には地面に立たずに落下します。

Surface Arc

Scene ビュー上には角度が可視化されています。

指定した角度の範囲に衝突法線( collision normal )が収まった場合、地面とみなされます。

Circle Collider 2D と一緒に使った時

Surface Arc の範囲から外れたら落下しているのが確認できます。

Polygon Collider 2D と一緒に使った時

最初は Surface Arc = 30 、途中から Surface Arc = 140 に変更しています。

30 の時は壁を通過しますが 140 になったら壁に衝突し始めるのが確認できます。

なお、 Surface Arc の円弧の範囲が壁際で分かりやすい様に自作のデバッグ描画を行っています。

因みにコードはこちらになります。

using UnityEngine;

public class DebugSurfaceArc : MonoBehaviour
{
    [SerializeField] PlatformEffector2D platform;
    float arc = 0;
    [SerializeField] float scale = 1.0f;

    private Transform trans;
    // Start is called before the first frame update

    private void Start()
    {
        trans = gameObject.transform;
        if (platform == null)
        {
            Debug.LogError("PlatformEffector2Dの参照を設定して下さい。");
        }
    }
    void OnDrawGizmos()
    {
        if (trans == null) return;
        if (platform != null)
        {
            arc = platform.surfaceArc;
        }

        float halfArc = arc * 0.5f;
        float arc1 = 90.0f + halfArc;
        float arc2 = 90.0f - halfArc;
        Vector3 startPoint = trans.position;
        float rad;

        Vector3 normal = Vector3.up;

        // Arcの範囲
        {
            Vector3 direction;

            Gizmos.color = Color.white;
            // 円弧描画のAPIが無いので DrawWireSphere で代用
            Gizmos.DrawWireSphere(startPoint, scale);

            Gizmos.color = Color.green;
            startPoint = trans.position;
            // 度(°)をラジアンに変換
            rad = Mathf.PI / 180 * arc1;
            direction = Vector3.zero;
            direction.x = Mathf.Cos(rad);
            direction.y = Mathf.Sin(rad);
            direction *= scale;
            Gizmos.DrawRay(startPoint, direction);
            rad = Mathf.PI / 180 * arc2;
            direction = Vector3.zero;
            direction.x = Mathf.Cos(rad);
            direction.y = Mathf.Sin(rad);
            direction *= scale;
            Gizmos.DrawRay(startPoint, direction);
        }

        // Surface面と法線との直角を表す
        {
            float lineSize = 0.2f * scale;
            Vector3 p1, p2, p3;

            startPoint = trans.position;
            p1 = startPoint;
            p1.x += lineSize;
            p2 = p1;
            p2.y += lineSize;
            p3 = p2;
            p3.x -= lineSize;
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(startPoint, p1);
            Gizmos.DrawLine(p1, p2);
            Gizmos.DrawLine(p2, p3);
        }

        // 法線
        Gizmos.color = Color.red;
        Gizmos.DrawRay(startPoint, normal * scale);
    }
}

移動している円の顔が衝突する壁の法線は緑の矢印で示した向きとなります。

これは Surface Arc = 140 まで増やすと範囲内に収まる事が確認できます。その為、 140 に変わった時点から壁に衝突する様になりました。

Box Collider 2D と一緒に使った時

Box Collider 2D と一緒に使った時にはこのくらい小さい範囲でも衝突が発生します。 Surface Arc = 1 でも衝突が発生し、 0 にすると流石に通過する様になります。

円の顔が地面にぶつかる時の衝突法線は緑の矢印の向きとなります。これは Surface Arc の範囲内となるので衝突するという挙動になります。

Use Side Friction と Use Side Bounce

■ Use Side Friction 、 Use Side Bounce のどちらにもチェックをしていない時

■ Use Side Friction をチェックした時

摩擦が効いているので回転が発生しているのが確認できます。

■ Use Side Bounce をチェックした時

跳ねるようになったのが確認できます。

【Unity】 Surface Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Surface Effector 2D はエスカレーターやベルトコンベアな様なものを再現する事ができるコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Surface Effector 2D の処理対象となる。
Speed 接地したターゲットに加えられる速度。正の数の場合には X 方向(右方向)、負の数の場合には -X 方向(左方向)の力が加えられる。
Speed Variation ランダムで設定される速度。「Speed+(0~ここで指定した値のランダム値)」が最終的に出力される速度になる。
Force Scale 指定された速度に到達しようとする力をスケーリングを0~1.0の範囲で指定。0の場合は全く力が加えられなくなり、 Surface Effector 2D を無効化した状態と同様になる。1にした場合にはターゲットの現在の Velocity を無視して指定した速度( Speed で指定した値)を強制します。
Use Contact Force チェックをすると接触した時にターゲットに回転の力が加わります。
Use Friction チェックをすると Friction (摩擦)が考慮されます。
Use Bounce チェックをすると Bounce (跳ね返り)が考慮されます。

解説

Speed と Speed Variation

Speed と Speed Variation の値をこの様にした場合に移動速度がバラけているのが確認できます。

Force Scale

円形の顔は右方向の力を常に発生していて、床からは左方向への速度を発生を受けるというサンプルを準備しました。

■ Force Scale = 0.01

床からの力を突破して右へ移動しました。

■ Force Scale = 0.1

床からの力が勝ち、左へ移動しました。

【Unity】 Point Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Point Effector 2D は引力や反発力を表現をしたい時に使用するコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Point Effector 2D の処理対象となる。
Force Magnitude 力の強さ。正の数の場合には反発の力、負の数の場合には引力となる。
Force Variation ランダムで設定される力の強さ。「Force Magnitude+0~ここで指定した値の範囲のランダム値」が最終的に出力される力の強さになる。
Distance Scale Force Mode の値が Constant 以外の時に発生する距離による効果にスケールをかける。
Drag 移動を抑える力の強さを設定。
Angular Drag 回転(角速度)を抑える力の強さを設定。
Force Source ターゲットのオブジェクトを引き付けたり、反発させたりするポイントを指定。Collider を選択した場合には Collider の位置に、 Rigidbody を選択した場合には重心がそのポイントとなる。
Force Target ターゲットのオブジェクト上の力を与えるポイントを指定。Collider を選択した場合には Collider の位置に、 Rigidbody を選択した場合には重心がそのポイントとなる。
Force Mode Constant 、 Inverse Linear 、 Inverse Squared のいずれかを選択可能。それぞれの効果については後述。

解説

ここでは解説の為に以下の様なプロジェクトを準備しました。

緑色の顔の Point Effector 2D の効果で白い顔が中心に向かってに吸い込まれるというサンプルで解説します。

それぞれの顔の GameObject にはこの様なコンポーネントが付けて有ります。

白色の顔

  • Circle Collider 2D
  • Rigidbody 2D

緑色の顔

  • Circle Collider 2D
  • Rigidbody 2D
  • Point Effector 2D

Point Effector 2D はこの様に設定しています。

Force Magnitude

正の値の場合には反発の力、負の値の場合には引力が発生している事が確認できます。

Force Magnitude = 20

Force Magnitude = -100

Force Mode で設定可能な値について

■ Constant

Target Point からの距離に関わらず常に100%の力で影響を与えます。

■ Inverse Linear

Target Point から離れるほど力は直線的に減衰して行きます。

■ Inverse Squared

Target Point から離れるほど力は2乗で減衰して行きます。

万有引力の法則」など「逆2乗の法則」を持つものを再現したい場合に使用します。

Distance Scale

Distance Scale は距離による影響をスケールします。その為、 Force Mode の値が Constant 以外に設定しないと意味が有りません。

数値を大きく設定するほど影響を与える力が弱くなっている為、中央に集まる速度が遅くなっているのが確認できます。

■ Distance Scale = 1

■ Distance Scale = 10

Drag

数値が大きいほど Target Point を中心に発生している白い顔のバウンドが収まるのが速くなっているのが確認できます。

■ Drag = 1

■ Drag = 10

【Unity】 Buoyancy Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Buoyancy Effector 2D は浮力や流れなどの水の表現をしたい時に使用するコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Buoyancy Effector 2D の処理対象となる。
Surface Level 水面の位置を設定。
Density 密度の設定。値が大きいほど浮力が上がります。
Linear Drag 直線的な移動の力を抑える力の強さを設定。
Angular Drag 回転(角速度)を抑える力の強さを設定。
Flow Angle 水の流れる方向を角度で指定。
Flow Magnitude 水の流れる力の強さ。
Flow Variation ランダムで設定される水の流れる力の強さ。「Flow Magnitude+0~ここで指定した値の範囲のランダム値」が最終的に出力される力の強さになる。

解説

Surface Level

Surface Level の現在の位置は Scene ビューでは水色のラインで表示されます。

デフォルト値の 0 の時には中央に位置するので Scene ビューで確認しながら自分のゲームに合った位置に移動させます。

Linear Drag

値が大きい方がより速く静止します。

Angular Drag

値が大きい方がより速く静止します。

Flow Angle と Flow Magnitude

Flow Angle0Flow Magnitude3 を設定する事で+X方向(右方向)へ水が流れます。

Flow Angle を 90、180、270 に変更した場合には水はこの様な方向へ流れます。

※実際にはオブジェクトには「水の流れ / 浮力 / 重力」が加わる為、完全に水の流れの方へ移動させたい場合には浮力と重力をゼロに設定する必要が有ります。

Flow Variation

Buoyancy Effector 2D にこの様に設定した状態で水の中にオブジェクトをどんどん生成するとオブジェクトの流れる速度がそれぞれ異なる事が確認できます。

【Unity】 Area Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Area Effector 2D は Collider で設定した領域と接触した時に様々な力を与えるコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Area Effector 2D の処理対象となる。
Use Global Angle チェックを付けると Force Angle の指定がワールド座標での角度として指定される。
Force Angle 力を加える向き(角度)。
Force Magnitude 力の強さ。
Force Variation ランダムで設定される力の強さ。「Force Magnitude+0~ここで指定した値の範囲のランダム値」が最終的に出力される力の強さになる。
Force Target 力を加える位置を指定。Collider を選択した場合には Collider の位置に、 Rigidbody を選択した場合には重心に力が加えられる。
Drag 移動を抑える力の強さを設定。
Angular Drag 回転(角速度)を抑える力の強さを設定。

解説

Force Magnitude と Force Angle

緑色エリアには Area Effector 2D を設定し、赤い Box に力が加わる環境を準備します。 なお、 Box の Rigidbody 2DGravity Scale0 に設定して重力はかかっていない状態にします。

この状態でこの様に Force Managitude10 を設定すると Box は右へ移動して行きます。 これは Force Angle0 で有ること合わせた効果です。

Force Angle を 90、180、270 に変更した場合には Box はこの様な方向へ移動します。

Force Variation

この2つの緑色エリアにはどちらにも Force MagnitudeForce Variation に同じ値を設定をしています。

「Force Magnitude + Force Variation でのランダム値」の力が加えられるので実行させると2つの Box の移動量に差が発生します。

Drag

Drag の値が大きいほど減速が大きい事が確認できます。

Angular Drag

Angular Drag の値が大きいほど回転の減速が大きい事が確認できます。

【Unity】 Constant Force 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Constant Force 2D は Rigidbody 2D に一定の力を加え続けるコンポーネントです。 自動的に移動させたり、回転させたりする事ができます。

docs.unity3d.com

プロパティ

プロパティ名 説明
Force 指定の方向に力を加える(絶対座標)。
Relative Force 指定の方向に力を加える(相対座標)。
Torque 正の数で指定すると反時計回り、負の数で指定すると時計回り方向に力が加えられる。

Force と Relative Force の比較

設定

両方の Box 共通

  • Rigidbody 2D の Gravity Scale は 0

1 の Box

  • Rotation の Z に 45
  • Constant Force 2D の Force の X に 1

2 の Box

  • Rotation の Z に 45
  • Constant Relative Force 2D の Force の X に 1

1の Box は絶対座標でのX方向、2の Box は相対座標でのX方向へ移動している事が確認できます。

Torque の検証

設定

両方の Box 共通

  • Rigidbody 2D の Gravity Scale に 0

1 の Box

  • Constant Force 2D の Torque に 3

2 の Box

  • Constant Force 2D の Torque に -3

1の Box は反時計回り、2の時計回りに回転している事が確認できます。