VRCでUdonSharpのギミックを作るに当たっての基礎的な部分①【Interact,Update】

# ギミックを作りたいけど、C#とかUdonSharpがわからない！
ごもっともです。
前回の記事はそういうのを一切無視してゴリ押しで投稿したので反省します。

前の記事は忘れたので説明が重複するかもしれませんが、Udonsharpでコードを記述(プログラミング)するにあたって最低限必要な部分と多少必要な部分を説明します。
説明が必要な用語も同時に説明していきます。
自分がよく使う用語は**太字**にするので、必要に応じて覚えてください。

※わかりやすいように、最初のうちは**マジックナンバー**をあえて使います。
　慣れてきた頃に変えます。
>マジックナンバー スクリプト上に直に書かれた数字や文字。
>書いた本人はわかるけど、他人から見たらなんでその数字なのかわからないので非推奨。

~~~C#
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class begin : UdonSharpBehaviour
{
    void Start()
    {
        
    }
}
~~~

Unity上でCreate→U# Scriptを行った際に、末尾が.csのファイルが作成されますが、それをダブルクリックで開くと上のようなテキストが表示されるかと思います。

`void Start()`はこのスクリプトを**アタッチ**したオブジェクトが、初めて**Active**になった際に実行される部分です。
>アタッチ→紐づけること。
>Active→UnityのInspectorタブの☑のところ。Activeにすると見えるようになったり動作したりするようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/db2fc595-dcda-ed78-b51e-a0742a1fa83a.png)
>厳密には違うけどだいたいそんな感じで最初は覚えといてもらえると


一番最初はこれしか無いので、行いたい動作をここに追加していくことになります。

また、`Start()`など、名前+()+{}で囲まれた部分、一連の処理を記載した部分を **メソッド(method)** と呼びます。

Unityにはあらかじめ定義されたメソッドがいくつか存在するので、それを使っていくことになります。
もしくは、処理が面倒なときに自分でメソッドを作って処理やデバッグを簡単にすることも出来ます。

## void Update()
### 用途：処理全般に広く使う
毎フレームごとに呼び出される処理です。あまり重い処理を入れると動作がかなり重くなるので、ほどほどにしましょう。
オブジェクトを動かすときなどに使います。
> **void** **戻り値**が無いということを示します。
> **戻り値** メソッドを呼んだ際、処理が終わった後に返ってくる値のことを示します。
>処理が失敗していたら0、処理が成功していたら1、のような値で示されます。
>戻り値のあるメソッドが出てきたら改めて追記しますね、たぶん
### Update使用例

1. Unity上でCreate→U# Script
1. 新しいウィンドウが開くので、ファイル名をbeginにして保存
1. ファイルが生成されるまで待ち、生成されたbegin.csをダブルクリックで開く
1. 下のコードをコピペ

を行ってください。

~~~C#
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;


public class begin : UdonSharpBehaviour
{
    void Start()
    {
    
    }
    void Update()
    {
        this.gameObject.transform.position += new Vector3(0.01f, 0f, 0f);
    }
}
~~~
>**Vector3** 3Dベクトルを表します。カッコで囲まれた順に、x,y,zの順で記載します。
>サイズや回転、位置を表す際などに使用します。
>
>this.gameObject.transform.position
>this.gameObject このスクリプトがつけられているオブジェクトのこと、
>transform トランスフォームっていうステータス。回転とか位置とかサイズとかが入ってる。
>position 位置。
>要約すると、**このゲームオブジェクトの、トランスフォーム値のうち、位置をどうにかします**　という意味。
>.(ドット)は日本語の「の」に置き換えて読んでみるとわかりやすいかも

ずっとxの正の向きに移動し続けるコードです。
では、実際に動作確認をしてみましょう。

1. Unityの画面に戻り、**Hierarchy**上で右クリック→3D Object→Cube(positionは適当に変えてOK)
1. 右側のInspectorウィンドウ最下部、Add Componentボタンをクリック→🔍欄にUdonと入力
1. 候補に出てきたUdon Behaviourを選択
1. 先ほど作成した際に勝手に作られたファイルbegin.asset **(begin.csではない方)** をInspector上のUdon BehaviourのProgramSourceの欄にドラッグ＆ドロップ(よくわからなかったら前々々回あたりの記事にSS付きで書いてます)
1. 上の再生ボタンをクリック

 ![VCC_Test-s-PC_-Mac-_-Linux-Standalone-Unity-2019.4.31f1-Personal_-_DX11_-2023-02-22-21-50-10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/a49dfc1e-ed33-ca98-c9f5-c979f8bad590.gif)

無限に移動し続けます。

>Hierarchy Sceneにあるオブジェクトが一覧で表示されている場所。デフォルトは左側。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/d50a42d3-25cd-d5a1-3986-706f0da502bf.png)

このように、処理を続けて行うことができたりするのがUpdateメソッドになります。
**処理を変えれば一定時間おきに行うなども可能です。**

## void Interact()
### 用途 スイッチのON/OFFやギミックの開始などの広汎な処理

ワールドでカーソルを当てるとなんか説明文が表示されて、コントローラのトリガーを引くと色々起きるあれです。
VRCのワールドでミラーやライトのON/OFFによく使われてるやつです。

ミラーとそれのON/OFFを切り替えるスイッチのギミックを作ってみましょう。
ここからの流れは、大体こんな感じ。
1. スクリプトを組む
1. CubeとかをHierarchy上から作成する
1. 右側のInspectorウィンドウでAdd Component→Udon Behaviour
1. スクリプトを作成したときに出来たCSファイルの隣のU#アイコンのなんかをProgram Sourceにドラッグ＆ドロップ
1. 必要に応じて設定
1. 再生
1. 正しく動作することが確認できたら実際にBuild
1. 問題なければワールドをアップロード

今は1-6番までで動作の確認を終わらせていますが、
VRで確認したい人はワールドアップロードまで進めちゃっていいと思います。
(トラストランクNew User以上じゃないとアップロードまではできませんが)

>Build 実際に動かしてみること、みたいなニュアンス。
>VCCを使ってUnity上では動くのが確認できるけど、VRChat上では動かないなんてこともあるので。

話がそれましたが、スクリプトを書いていきましょう。
スクリプトの名前はmirrorSwitchとでもしておきます。
~~~C#
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class mirrorSwitch : UdonSharpBehaviour
{
    public GameObject mirror;
    void Start()
    {
        
    }
    void Interact()
    {
        mirror.SetActive(!mirror.activeSelf);
    }
}

~~~

・`void Start`の上になんか増えました。
・`void Interact`が増えました。

    void Interact()

VRCで手を近づけるとなんか操作できるやつがあると思います、それを実装するためのメソッドです。
処理が行われるのは**オブジェクトに近づいてトリガーボタンを押したとき**と思ってもらえればいいです。
微妙に語弊がありますが、だいたいそんな感じです。

    mirror.SetActive(true or false);

`mirror`という名前のオブジェクトをTrueならアクティブに、Falseなら非アクティブにします。

    !mirror.activeSelf

`mirror.activeSelf`は、`mirror`がアクティブならTrue,非アクティブならFalseというデータが入ってきます。
`!`はTrueとFalseの状態を逆にします。
つまり、このコードの意味は
**mirrorというオブジェクトの状態を、mirrorがアクティブなら非アクティブに、非アクティブならアクティブに変更します。**
ということになります。

※**if文使って書いてもいいと思います**。こっちのほうが短く書けるだけです。


### 注意
**このコードをアタッチしたオブジェクトにコライダーが無い場合、操作できません。**
Cubeとかには最初からコライダーがついているので大丈夫ですが。

では、Unity上で確認してみましょう。

1. Hierarchy上で右クリック→3D Object→Cube
1. Cubeを選択した状態で、右側のInspector→Transform(一番上のとこ)→Position　x=5,y=0.5,z=2と設定
1. 右側のInspectorの一番下のAdd Componentボタン→Udon Behaviourを検索して追加
1. 先程のmirrorSwitch.assetをProgram Sourceにドラッグ＆ドロップ
1. 赤線を引いた場所にあるVRCMirrorというやつを赤矢印で引っ張ったあたりにドラッグ＆ドロップ
 ![VCa1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/acd7efc2-8c6a-814e-ecd1-e68e8ab55f24.png)
1. VRC Mirrorを選択した状態で、右側のInspector→Transform(一番上のとこ)→Position　x=5,y=1,z=0.5と設定
1. VRC Mirrorを選択した状態で、右側のInspector→Transform(一番上のとこ)→**Rotation**　x=0,y=90,z=0と設定
1. Cubeを選択した状態で、Hierarchy上のVRCMirrorをドラッグして右側のMirrorの欄にドロップ
![VCa2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/d00b28ff-cfe8-dc35-523c-88be06cc1554.png)

それでは動作確認してみましょう。
再生ボタンを押して、シミュレータ上で操作してみましょう。

![VCC_Test-s-PC_-Mac-_-Linux-Standalone-Unity-2019.4.31f1-Personal_-_DX11_-2023-02-23-23-42-08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708808/d71da439-11f9-0754-addf-122466762681.gif)

ミラーのOn/OFFが切り替えられるようになっていますね。


>**public** 
>**宣言**したオブジェクトや変数などがUnity上で設定できるようになる、みたいな認識で大丈夫です。
>厳密には **「スコープ」** の一種で、「外部からも参照できる」と言った感じの意味です。↔**private** 
>
>**宣言** 使う変数やオブジェクトを**型**を決めて名前を付けておくこと、的な意味。
>例文 public GameObject mirror;
>というコードの場合、「public」な mirror という名前の GameObject を、このコード上で使います。
>とあらかじめ書いておくことで、その下の行以降からはそのmirrorなどの名前をつけたオブジェクトに操作を行うことができるようになります。
>
>**変数**
>コードで使う数字や文字などを入れておく箱みたいなもの。
>高校数学で「奇数を2a+1とおく(aは自然数)」みたいな答案書いたりすると思うけど、そのa。
>
>**型** 文字列、小数、整数、GameObjectといった、ある程度決まった枠みたいなもの。
>上で言う(aは自然数)みたいな制約。

以降の部分は長くなるので記事を分割します。