プログラマじゃない人向けUdon講座（鏡の出し入れ発展編）


前回：[鏡の出し入れ](https://qiita.com/tamsco274/items/3d0c255494b25511475c)


#目標
EnterTrigger/ExitTriggerを使ってみる

#ほんへ

##近づいたら鏡を表示する
「近づいたら」と言っていますが、実際は**「トリガーに侵入したら表示する」**です。
###手順
1,コライダー(トリガー)を設置する
2,コライダーにスクリプトを当てる
3,コーディングする

###1,コライダーを設置する
まずは鏡が表示される範囲を示すオブジェクトを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/cab3e599-1a9a-3f94-58d7-97327bab07a1.png)
分かりやすい名前に変更し、（一応）マテリアルを変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/98371910-f532-e874-5076-25835e3bc4a5.png)
サイズ変更、移動を行い、「Is Trigger」のチェックを付けます。
「Mesh Renderer」のチェックを外していますが、気になる人は「Mesh Renderer」を削除しても問題ありません。


###2,コライダーにスクリプトを当てる
前回と同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/fb76d825-e9b3-05f2-111a-a3d9898ace7a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/6901a261-c788-b36c-cec6-875bb6a4dcd6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/82045c60-9bc2-b75c-180d-fe9ac8bb9e24.png)

###3.1,コーディングする
以前は「Interact」を用いましたが、今回は「OnPlayerTriggerEnter」を用います。

```csharp:MirrorTrigger.cs
    

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MirrorTrigger : UdonSharpBehaviour
{

    //鏡オブジェクト
    [SerializeField] private GameObject Mirror;

    void Start()
    {
        
    }

    public override void OnPlayerTriggerEnter(VRCPlayerApi player)
    {
        //鏡をOnにする
        Mirror.SetActive(true);
    }
}
```
その後、Mirrorを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/2ce07a9d-9d32-1bbf-5080-c2f7b5a0a61a.png)

一応完成です。アップロードして様子を見ましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/9524b649-4db1-0d5c-63a4-031ba860bf1e.png)
出ましたね。離れても消えませんが。
ついでに言うと、現状では自分以外のプレイヤーが入った場合でも表示されてしまいます。

まずは自分が入ったときにのみ反応するように改良しましょう。
###3.2コーディングする（自分が入ったときのみ反応させる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399875/1d0f67d2-3dc0-cace-4919-04ea5cd337f4.png)

IF文を追加します。IF文を用いることにより、条件分岐が可能になります。
「プレイヤーが侵入した場合、鏡を表示する」という動作を、
「プレイヤーが侵入した場合、**そのプレイヤーが自分だった場合、**鏡を表示する」に変更します。

```csharp:MirrorTrigger.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MirrorTrigger : UdonSharpBehaviour
{

    //鏡オブジェクト
    [SerializeField] private GameObject Mirror;

    void Start()
    {
        
    }

    public override void OnPlayerTriggerEnter(VRCPlayerApi player)
    {
        //トリガーに侵入したのが自分だった場合
        if (player == Networking.LocalPlayer)
        {
            //鏡をOnにする
            Mirror.SetActive(true);
        }
    }
}
```

これでOKです。次は、プレイヤーが離れた時に非表示にしましょう。
##離れたら鏡を非表示にする
「onPlayerTriggerExit」を用います。
他のプレイヤーが離れても反応しないよう、上記同様にIf文を追加しています。

```csharp:MirrorTrigger.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MirrorTrigger : UdonSharpBehaviour
{

    //鏡オブジェクト
    [SerializeField] private GameObject Mirror;

    void Start()
    {
        
    }

    public override void OnPlayerTriggerEnter(VRCPlayerApi player)
    {
        //トリガーに侵入したのが自分だった場合
        if (player == Networking.LocalPlayer)
        {
            //鏡をOnにする
            Mirror.SetActive(true);
        }
    }

    public override void OnPlayerTriggerExit(VRCPlayerApi player)
    {
        //トリガーに侵入したのが自分だった場合
        if (player == Networking.LocalPlayer)
        {
            //鏡をOffにする
            Mirror.SetActive(false);
        }
    }
}
```

これでOKです。


#解説
今回用いたメソッドでは、[引数](https://ja.wikipedia.org/wiki/%E5%BC%95%E6%95%B0)があります。
「VRCPlayerApi player」がソレです。


```csharp:MirrorTrigger.cs
  public override void OnPlayerTriggerEnter(VRCPlayerApi player)
```

「VRCPlayerApi型」の「player」を意味しています。変数の宣言と同様です。
この「player」には、「誰がトリガーに入ったか/出たか」の情報を持っています。

If文の基本的な構文は以下の通りです。

```csharp:sample.cs
  if(条件式)
   {
      //Trueの時に行いたい処理（条件式が成り立つ時）
   }
   else
   {
      //Falseの時に行いたい処理（条件式が成り立たない時）
　　　//省略可能
   }
```
今回の条件式は以下の通りです。
「Networking.LocalPlayer」は、**自分**を意味しています。

```csharp:MirrorTrigger.cs
          //トリガーに侵入したのが自分だった場合
        if (player == Networking.LocalPlayer)
        {
            //鏡をOnにする
            Mirror.SetActive(true);
        }
```

条件式で用いられている「==」は、[比較演算子](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/comparison-operators)と呼ばれます。
「==」は、左辺と右辺が一致している場合にTrueを返します。つまり、
「player」が「Networking.LocalPlayer」と同じだった場合、{ }の中の処理を行います。

#シメ
今日はIf文が出て来ました。かなりよく使います。
（スコアが一定以上の時に処理、キーがOnの時にドアを開ける、等…）
プログラミングで大切なのは応用力です。最初はよく分からなくても、原理を理解すれば応用が出来ます。
挫折しないよう、**理解できる友達を作って**挑戦しましょう。