LoginSignup
0
1

【Unity】 Playerが近づいた時のみ見える( 透明→不透明)オブジェクトを作る

Last updated at Posted at 2023-01-07

初めに

この記事はUnity初学者が学習の備忘録として書いたものです.誤っている点もあるかと思いますので,ご指摘いただけると幸いです.

(Unity2020.3を使用)

完成イメージ

Unity公式チュートリアル"Roll-a-ball"に追加機能として実装しました.
https://learn.unity.com/project/roll-a-ball

ezgif.com-gif-maker.gif

利用した機能

プレーヤーの接近検知にはOnTriggerOnCollisionメソッドを利用しました.

接触イベント

上記の記事で説明されているように,Colliderコンポーネントが取り付けられたGameObjectでは他のColliderとの接触時に実行したい処理を,OnTrigger・OnCollisionメソッドで指定しておくことができます.
※少なくともどちらかのGameObjectにRigidbodyコンポーネントも必要です.

image.png

OnTrigger・OnCollisionの違い

これらは接触イベントの対象となるColliderのTrigger状態(※すり抜ける否か)によって使い分けます.

image.png

今回はプレイヤー側にTriggerあり(すり抜ける)のSpher Clliderを取り付け,これを探索範囲としてTriggerなし(すり抜けない)の壁への近接判定を行います.よって上図の対応からOnTriggerに処理を記述します.

image.png

3種類のOnTrigger

また,OnTriggerには呼び出されるタイミングが異なる3種類が用意されています.これによってflagやstateなどのあるタイミングで状態を切り変える処理や,接触が起きている間に繰り返し呼び出したい処理をそれぞれ設定することができます.

メソッド 機能
OnTriggerEnter() Triggerオブジェクトに侵入した瞬間に呼び出される
OnTriggerStay() Triggerオブジェクトに侵入している間呼び出され続ける
OnTriggerExit() Triggerオブジェクトから脱出した瞬間に呼び出される

実装したコンポーネント(スクリプト)

今回は「プレイヤーが一定の距離まで近づいたら,距離に応じた透明度を設定する」という実装にしたいためOnTriggerStay()を使用しました.※透明度はMeshコンポーネントのmaterial.colorのalpha値で設定

また,接触相手のGameObjectが透明な壁かどうかは透明度の制御スクリプト(InvisibleObjectコンポーネント)がアタッチされているかで判定しています.

PlayerSearchArea.cs
[RequireComponent(typeof(SphereCollider))]
public class PlayerSearchArea : MonoBehaviour {

    private SphereCollider area;   // 探索エリアとして扱うClollider    
    private float areaRadius = 5;  // SphereColliderの半径

    void Start() {
        area = GetComponent<SphereCollider>();
        area.radius = areaRadius;
    }

    // ↓ 他のColliderが探索エリア内にいる限り呼ばれ続ける
    private void OnTriggerStay(Collider other) {
        // 相手が不可視オブジェクトの場合,
        if (other.gameObject.TryGetComponent<InvisibleObject>(out var obj)) {

            // 距離に応じてalpha値を設定
            var distance = (transform.position - other.transform.position).magnitude;
            var aipha = Mathf.Clamp01(1 - distance / areaRadius);
            obj.SetVisibility(true, aipha);     // InvisibleObjectクラスの透明度設定メソッド
        }
    }

こちらが相手側にアタッチしておくスクリプトです.Meshマテリアルの透明度を設定するメソッドをpublicで用意しておき,初期化時に見えないようにしておきます.
※今回の機能には不要なプロパティ(IsVisible)が含まれています.

InvisibleObject.cs
[RequireComponent(typeof(MeshRenderer))]
public class InvisibleObject : MonoBehaviour{

    // 制御対象
    private MeshRenderer mesh;

    // 透明かどうか
    public bool IsVisible { get; private set; } = false;

    // 
    void Start() {
        mesh = GetComponent<MeshRenderer>();
        SetVisibility(false);           // 可視性に対応したalpha値を適用
    }

    // 可視性を設定し,見える場合はalpah値を指定可能
    public void SetVisibility(bool visibility, float alpha=1f) {
        IsVisible = visibility;
        SetMeshAlpha(IsVisible ? alpha : 0f);
    }
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1