コンテンツにスキップ

UdonSharp v0.20.3→v1.1.0でできるようになったこと

VRChat Creator CompanionでUdonSharp1.1.0が利用できるようになり、いろいろ機能が増えたが、新しい機能に対する使い方がまとめられていないので、サンプルコードとともにまとめる。

継承サポート

1.0系の目玉機能。オブジェクト指向プログラミングであるクラスの継承が使えるようになりました。 子クラスで仮想メソッドを実装することで、実行するメソッドを付け替えるなどの処理ができるようになります。

例:IActionクラスを継承したクラスの配列から順番にActionを実行する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using UdonSharp;

/// <summary>
/// アクションの基本クラス
/// </summary>
public class IAction : UdonSharpBehaviour
{
    // virtualを付けて仮想メソッド化
    public virtual void Action(string playerName)
    {

    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using UdonSharp;
using UnityEngine;

/// <summary>
/// 攻撃アクション(設定したダメージを表示する)
/// </summary>
public class AttackAction : IAction
{
    /// <summary>
    /// ダメージ
    /// </summary>
    [SerializeField]
    int damage = 10;

    public override void Action(string playerName)
    {
        Debug.Log(playerName + " Attack! " + damage + " damage!");
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UdonSharp;
using UnityEngine;

/// <summary>
/// 防御アクション設定した成功率で成功したか失敗したか表示
/// </summary>
public class DefenceAction : IAction
{
    /// <summary>
    /// 成功率インスペクターから変更できる
    /// </summary>
    [SerializeField]
    float successRate = 0.5f;

    public override void Action(string playerName)
    {
        if (successRate < Random.Range(0.0f, 1.0f))
        {
            Debug.Log(playerName + " Defence...SUCCESS!!");
        }
        else
        {
            Debug.Log(playerName + " Defence...FAILD");
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UdonSharp;
using UnityEngine;

/// <summary>
/// 設定したアクションを順番に実行する
/// </summary>
public class ActionPlayer : UdonSharpBehaviour
{
    [SerializeField]
    IAction[] actions;

    void Start()
    {
        Debug.Log("PlayAction!");

        string playerName = "PLAYER1";

        foreach(var action in actions)
        {
            action.Action(playerName);
        }
    }
}

実行例

ActionPlayerのインスペクタ。AttackAction、DefenceActionを同じIAction型の配列に含められる。

実行結果

設定したダメージや成功率で判定された結果が出力されます。

UdonBehaviorの配列

これまでUdonBehaviorの配列は作れませんでしたが、1.0以降から作れるようになりました。

例:インタラクトしたら複数のUdonBehaviorにSencCustomEventするスクリプト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

/// <summary>
/// インタラクトしたら複数のUdonBehaviorにSencCustomEventするスクリプト
/// </summary>
public class MultiplySendCustom : UdonSharpBehaviour
{
    [SerializeField]
    UdonBehaviour[] udonBehaviours; // UdonBehaviorの配列が宣言できるようになった
    [SerializeField]
    string command;

    public override void Interact()
    {
        foreach(var udon in udonBehaviours)
        {
            udon.SendCustomEvent(command);
        }
    }
}

またUdonBehavior型だけでなく、カスタムなUdonBehaviorクラスの配列も作れるようになっています。

例: 複数のItemクラスにIDを割り振る例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using UdonSharp;
using UnityEngine;

public class Item : UdonSharpBehaviour
{
    [SerializeField]
    int id;

    public void SetID(int _id)
    {
        id = _id;
    }

    public int GetID()
    {
        return id;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UdonSharp;
using UnityEngine;

public class ItemIDSetter : UdonSharpBehaviour
{
    [SerializeField]
    Item[] items; // 自作クラスの配列サポート!!

    void Start()
    {
        // IDをセット
        for(int i = 0; i < items.Length;++i)
        {
            items[i].SetID(i);
        }

        // IDを出力する
        foreach(var item in items)
        {
            Debug.Log(item.GetID());
        }
    }
}

UdonBehavior(自作Udonクラス)のGetComponent<>対応

v0.20.3 ではUdonBehaviorを取得するのに、GetComponent<>は使用できず、以下のような周りくどい方法でしか取得できませんでした。

1
UdonBehavior udon =  (UdonBehavior)gameObject.GetComponent(typeof(UdonBehavior));

1.1.0では他のUnityコンポーネントと同様に以下のように取得できるようになりました。

1
UdonBehavior udon = gameObject.GetComponent<UdonBehavior>();

また自作クラスも同じようにGetComponent<>で取得できるようになり、さらに継承したクラスに対しても使うことができます。

1
2
// CustomUdonComponentというUdonを作った場合もこれで取得できる!
CustomUdonComponent udon = gameObject.GetComponent<CustomUdonComponent>();

Enumサポート

自作の列挙型が使えるようになりました。インスペクターにもプルダウンメニューとして表示され、モードの設定などが作りやすくなりました。

例:モード切替をEnumで実装する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using UdonSharp;
using UnityEngine;

/// <summary>
/// 列挙型はクラスの外で宣言
/// </summary>
public enum MODE
{
    MODE_A,
    MODE_B,
    MODE_C,
}

public class ModeChange : UdonSharpBehaviour
{

    public MODE mode; // 自作の列挙型が使える!

    void Start()
    {
        switch(mode)
        {
            case MODE.MODE_A:
                Debug.Log("Active MODE_A");
                break;
            case MODE.MODE_B:
                Debug.Log("Active MODE_B");
                break;
            case MODE.MODE_C:
                Debug.Log("Active MODE_C");
                break;
        }
    }
}

インスペクター表示

プルダウンメニューになって便利

関数のオーバーロードのサポート

関数名が同じだが引数が異なるいわゆる関数のオーバーロードがUdonSharpでも使えるようになりました。

例えば以下のようなfloatやintでその符号反転した値を返す関数は以下のように定義できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
float GetMinus(float i)
{
    return -i;
}

int GetMinus(int i)
{
    return -i;
}

...

int i = 1;
i = GetMinus(i); // GetMinus(int i)が呼ばれる。

float f = 1.0f;
f = GetMinus(f); // GetMinus(float f)が呼ばれる。

Staticメソッドのサポート

Staticメソッドが定義できるようになりました。 newでインスタンス化しなくても決まり切った静的な処理などはこれで呼べるようになります。残念ながらStaticフィールドには対応していませんでした。

1
2
3
4
5
6
7
8
public class StaticTest : UdonSharpBehavior
{
    // クラスに関連するID的な
    public static int GetStaticID()
    {
        return 135233;
    }
}
1
2
3
4
5
6
7
8
9
public class TestCallStatic : UdonSharpBehavior
{
    void Start()
    {
        // new しなくても直接呼び出せる。
        var id = StaticTest.GetStaticID();
        Debug.Log(id);
    }
}

インスペクターのマルチ編集サポート

v0.20.3までは、オブジェクトを複数選択した状態でインスペクターのマルチ編集ができませんでしたが、v1.0以降でサポートされました。

プレハブ関係のサポート

プレハブ階層構造にした場合に、差分に対応した。 これまではフィールド単位での差分は取れなかった。 ただし古いUdonSharpからだと切り替え処理が必要?(この関係で古いUdonsharpがはいったプレハブが壊れる場合がある(要調査))