LineRendererコンポーネントを使って空中で描けるペンを作成します。

Udonスクリプト作成

サンプルの PenLineとSimplePenをU#に書き直し

Udon Graph

デカすぎるので画像の添付は省略

U#

PenLineBySharpとSimplePenBySharp

public class SimplePenBySharp : UdonSharpBehaviour
{
    private PenLineBySharp line;

    private bool isDrawing;

    private Vector3 startPosition;

    public float minMoveDistance = 0.1f;

    private Vector3[] points;

    private LineRenderer lineRenderer;

    public Transform penTip;

    private int currentIndex = -1;

    public int pointsPerUpdate = 10;

    public Transform linesContainer;

    [UdonSynced]
    private int nextLineIndex = 0;

    private GameObject[] pool;

    private LineRenderer[] linePool;

    void Start()
    {
        linePool = linesContainer.GetComponentsInChildren< LineRenderer>();
    }

    public override bool OnOwnershipRequest(VRCPlayerApi requestingPlayer, VRCPlayerApi requestedOwner)
    {
        return true;
    }

    public override void OnPickupUseDown()
    {
        // Get new Line from Pool
        lineRenderer = linePool[nextLineIndex];
        line = (PenLineBySharp)lineRenderer.GetComponent(typeof(UdonBehaviour));
        Networking.SetOwner(Networking.LocalPlayer, line.gameObject);
        line.gameObject.SetActive(true);

        // Increment next Line Index
        if (nextLineIndex++ >= linePool.Length)
        {
            nextLineIndex = 0;
        }

        // Reset Variables
        isDrawing = true;
        lineRenderer.positionCount = 2;

        startPosition = penTip.position;
        currentIndex = 0;

        // Initialize Line with 2 Points at Pen Tip
        for (int i = 0; i < 2; i++)
        {
            lineRenderer.SetPosition(i, penTip.position);
        }
    }

    private void Update()
    {
        //Debug.Log(items.Length);

        // Are we drawing?
        if (!isDrawing) return;

        // Has the pen moved enough?
        if (Vector3.Distance(penTip.position, startPosition) > minMoveDistance)
        {
            // Increase Points in Line
            lineRenderer.positionCount = currentIndex+1;

            // Add Point to Line
            lineRenderer.SetPosition(currentIndex, penTip.position);
            startPosition = penTip.position;

            // Increment currentIndex
            currentIndex++;

            // Group Point Updates to reduce Network Traffic
            if ((currentIndex % pointsPerUpdate) == 0)
            {
                line.OnUpdate();
            }
        }
    }

    public override void OnPickupUseUp()
    {
        isDrawing = false;
        line.OnFinish();
    }
}

public class PenLineBySharp : UdonSharpBehaviour
{
    private bool isDown;

    [UdonSynced]
    private Vector3[] points = new Vector3[10];

    public LineRenderer lineRenderer;

    public void OnFinish()
    {
        lineRenderer.Simplify(0.005f);
        OnUpdate();
    }

    public void OnUpdate()
    {
        points = new Vector3[lineRenderer.positionCount];
        lineRenderer.GetPositions(points);

        RequestSerialization();
    }

    public override void OnDeserialization()
    {
        // Set LinePositions from Synced Data
        lineRenderer.positionCount = points.Length;
        lineRenderer.SetPositions(points);
    }

    public override bool OnOwnershipRequest(VRCPlayerApi requestingPlayer, VRCPlayerApi requestedOwner)
    {
        return true;
    }
}

シーン作成

うーん。特に解説することがない・・・他の記事と解説が被るので省略します。

さいごに

サンプルコードをU#への書き直し作業は過去最大で大変でした。特にエラーが発生してもログに残らないのは辛すぎます。try-catch構文も使えないので、エラー発生時にログを残すことが出来なかったのでバグの特定に時間がかかりました。U#辛すぎますね・・

ペンを作成する

投稿ナビゲーション


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)