質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • C#

    8522questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    5117questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • UI

    125questions

    UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

unityでnode editorのようなツールを作りたい

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 116

前提・実現したいこと

unityでユーザが編集可能なnodeとnodeをつなげてグラフにするツールを作成したいです。
しかし、unityでnode graphの実装の方法を調べても見つからないです。
Node editorを実装しているのはたくさんありますが、uGUI上で動かせるものは見当たらないです。

質問

いま、最も欲している知識はuGUIでNode editorを実装する方法、もしくは、そのようなアセットです。
この件について何か知っている方がおられたら教えてください。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

そのものが作れるアセットについては私は知らないので割愛します。
以下、自作する場合。

描画について、とりあえず「ボックス」と「ボックスを繋ぐ線」があればノード的な見た目になると思います。
ボックスはまぁいいとして(普通のImageでいい)、線も直線であれば普通のImageを駆使して作れなくはないです。が、負荷と手間が大変だと思うので、「ugui 線を引く」「ugui ベジェ曲線」などでGoogle検索すると出る情報を参考にした方がいいと思います。
なお描画だけであれば図形を描くアセットも存在するようです。

プログラムについては「適切な形に設計・開発してください」としか言えません。
エディタ拡張によるノードエディターの作り方が参考になると思います。

使い物になるレベルの物を作るのは大変だと思いますが頑張ってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

アセットストアを探してみても、確かにビジュアルプログラミング関連でグラフ式UIを採用しているものは結構あるようですが、プレイヤーに操作してもらうためのUI部品的なキットは見当たりませんね...
ざっとみてみたところ、ご所望のものに一番近そうなのはUI Graphでしょうか。ですが、無料でしたので試してみたものの、このアセットが用意してくれるのはRectTransform同士を繋ぐ線を引く機能のみのようで、ノードの設計やプレイヤーの操作に対する応答などは各自で作らなければならなそうです。
逆に、このアセット自体の機能はシンプルですので、グラフ構造の可視化目的に限らず単に線を引くための用途に流用することもできそうですね。

ひとまず試しに、プレイヤーの操作でノードの接続線を張るのをやってみました。
下図のようなプレハブを作成し...

ノードプレハブ

ノード本体部分のスクリプトは単にドラッグで位置を移動するだけ、

using UnityEngine;
using UnityEngine.EventSystems;

public class Node : MonoBehaviour, IBeginDragHandler, IDragHandler
{
    private Camera canvasCamera;
    private RectTransform canvasTransform;
    private Vector2 offset;
    private RectTransform rectTransform;

    public void OnBeginDrag(PointerEventData eventData)
    {
        Vector2 position;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.canvasTransform,
            eventData.position,
            this.canvasCamera,
            out position);
        this.offset = this.rectTransform.anchoredPosition - position;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 position;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.canvasTransform,
            eventData.position,
            this.canvasCamera,
            out position);
        this.rectTransform.anchoredPosition = position + this.offset;
    }

    private void Awake()
    {
        this.rectTransform = this.transform as RectTransform;
        var canvas = this.rectTransform.root.GetComponent<Canvas>();
        this.canvasTransform = canvas.transform as RectTransform;
        this.canvasCamera = canvas.worldCamera;
    }
}

ノードの右側に突き出た出力ポートのスクリプトでは、ドラッグ開始時に見えない末端オブジェクトを作って出力ポートとの間に接続線を張り、そのままドラッグ操作で末端を移動できるようにして、入力ポートにドロップされたらそこにあらためて接続線を張り直すようにしてみました。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class OutputPort : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    private Camera canvasCamera;
    private RectTransform canvasTransform;
    private RectTransform connectionHandle;
    private readonly List<RaycastResult> raycastResults = new List<RaycastResult>();
    private RectTransform rectTransform;
    private Connection tempConnection;

    public void OnBeginDrag(PointerEventData eventData)
    {
        var handle = new GameObject("Handle");
        this.connectionHandle = handle.AddComponent<RectTransform>();
        this.connectionHandle.SetParent(this.canvasTransform, false);
        Vector2 position;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.canvasTransform,
            eventData.position,
            this.canvasCamera,
            out position);
        this.connectionHandle.anchoredPosition = position;
        this.connectionHandle.sizeDelta = Vector2.zero;
        ConnectionManager.CreateConnection(this.rectTransform, this.connectionHandle);
        this.tempConnection = ConnectionManager.FindConnection(this.rectTransform, this.connectionHandle);
        var points = this.tempConnection.points;
        points[0].direction = ConnectionPoint.ConnectionDirection.East;
        points[0].color = this.GetComponent<Image>()?.color ?? Color.white;
        points[1].direction = ConnectionPoint.ConnectionDirection.West;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 position;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.canvasTransform,
            eventData.position,
            this.canvasCamera,
            out position);
        this.connectionHandle.anchoredPosition = position;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        ConnectionManager.RemoveConnection(this.tempConnection);
        Destroy(this.tempConnection.gameObject);
        this.tempConnection = null;
        Destroy(this.connectionHandle.gameObject);
        this.connectionHandle = null;

        EventSystem.current.RaycastAll(eventData, this.raycastResults);
        foreach (var raycastResult in this.raycastResults)
        {
            var port = raycastResult.gameObject.GetComponent<InputPort>();
            if (port != null)
            {
                var portTransform = port.transform as RectTransform;
                ConnectionManager.CreateConnection(this.rectTransform, portTransform as RectTransform);
                var connection = ConnectionManager.FindConnection(this.rectTransform, portTransform);
                var points = connection.points;
                points[0].direction = ConnectionPoint.ConnectionDirection.East;
                points[0].color = this.GetComponent<Image>()?.color ?? Color.white;
                points[1].direction = ConnectionPoint.ConnectionDirection.West;
                points[1].color = port.GetComponent<Image>()?.color ?? Color.white;
            }
        }
    }

    private void Awake()
    {
        this.rectTransform = this.transform as RectTransform;
        var canvas = this.rectTransform.root.GetComponent<Canvas>();
        this.canvasTransform = canvas.transform as RectTransform;
        this.canvasCamera = canvas.worldCamera;
    }
}

ノードの左側に突き出た入力ポートは特に機能を持たせておらず、入力ポートであると識別するためのただの目印になっています。

using UnityEngine;

public class InputPort : MonoBehaviour
{
}

動かしてみたところ、下図のようになりました。

ノードを接続

実際にグラフエディターとして意味のある動作をさせるには本腰を入れて作り込む必要がありそうですね。sakura_hanaさんのアドバイスの通り、ソースコードを見ることができるアセットがありましたらそれを見てみるのが有効だろうと思います。さすがにそのままパクってしまうのはまずいでしょうが、設計する上でのヒントとして役に立つのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C#

    8522questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    5117questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • UI

    125questions

    UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。