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

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

新規登録して質問してみよう
ただいま回答率
85.47%
C#

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

UI

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

3回答

1746閲覧

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

HirokiMorikawa

総合スコア8

C#

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

UI

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/03/13 15:16

前提・実現したいこと

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

質問

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

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

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

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

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

投稿2019/03/14 02:24

sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

横から失礼します。
とてもありがたいスレッドでした。

Bongoさんのレスを実装しているのですが、
ConnectionManager
などの定義が見当たらず実装に苦労しています。

gitなどに上記状況など上がっていたりしますでしょうか?

もしくは、どのようにしたら上記コメントと同じ状況を自分の環境に再現できますでしょうか?

お手数おかけしますがどうぞよろしくお願いいたします。

投稿2020/01/21 02:19

nkazto

総合スコア9

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Bongo

2020/01/21 12:51

ConnectionManagerは回答の最初の方で申し上げた「UI Graph」に収録されていたものです。もしかしてこのアセットをインストールしていなかった...とかではないでしょうか?
nkazto

2020/01/23 05:51

失礼しました! その通りです。 単体で動くものを探していたので、勘違いしていました。 UI Graphを前提としていると書いてあったのですが、すみません。
guest

0

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

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

ノードプレハブ

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

C#

1using UnityEngine; 2using UnityEngine.EventSystems; 3 4public class Node : MonoBehaviour, IBeginDragHandler, IDragHandler 5{ 6 private Camera canvasCamera; 7 private RectTransform canvasTransform; 8 private Vector2 offset; 9 private RectTransform rectTransform; 10 11 public void OnBeginDrag(PointerEventData eventData) 12 { 13 Vector2 position; 14 RectTransformUtility.ScreenPointToLocalPointInRectangle( 15 this.canvasTransform, 16 eventData.position, 17 this.canvasCamera, 18 out position); 19 this.offset = this.rectTransform.anchoredPosition - position; 20 } 21 22 public void OnDrag(PointerEventData eventData) 23 { 24 Vector2 position; 25 RectTransformUtility.ScreenPointToLocalPointInRectangle( 26 this.canvasTransform, 27 eventData.position, 28 this.canvasCamera, 29 out position); 30 this.rectTransform.anchoredPosition = position + this.offset; 31 } 32 33 private void Awake() 34 { 35 this.rectTransform = this.transform as RectTransform; 36 var canvas = this.rectTransform.root.GetComponent<Canvas>(); 37 this.canvasTransform = canvas.transform as RectTransform; 38 this.canvasCamera = canvas.worldCamera; 39 } 40}

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

C#

1using System.Collections.Generic; 2using UnityEngine; 3using UnityEngine.EventSystems; 4using UnityEngine.UI; 5 6public class OutputPort : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler 7{ 8 private Camera canvasCamera; 9 private RectTransform canvasTransform; 10 private RectTransform connectionHandle; 11 private readonly List<RaycastResult> raycastResults = new List<RaycastResult>(); 12 private RectTransform rectTransform; 13 private Connection tempConnection; 14 15 public void OnBeginDrag(PointerEventData eventData) 16 { 17 var handle = new GameObject("Handle"); 18 this.connectionHandle = handle.AddComponent<RectTransform>(); 19 this.connectionHandle.SetParent(this.canvasTransform, false); 20 Vector2 position; 21 RectTransformUtility.ScreenPointToLocalPointInRectangle( 22 this.canvasTransform, 23 eventData.position, 24 this.canvasCamera, 25 out position); 26 this.connectionHandle.anchoredPosition = position; 27 this.connectionHandle.sizeDelta = Vector2.zero; 28 ConnectionManager.CreateConnection(this.rectTransform, this.connectionHandle); 29 this.tempConnection = ConnectionManager.FindConnection(this.rectTransform, this.connectionHandle); 30 var points = this.tempConnection.points; 31 points[0].direction = ConnectionPoint.ConnectionDirection.East; 32 points[0].color = this.GetComponent<Image>()?.color ?? Color.white; 33 points[1].direction = ConnectionPoint.ConnectionDirection.West; 34 } 35 36 public void OnDrag(PointerEventData eventData) 37 { 38 Vector2 position; 39 RectTransformUtility.ScreenPointToLocalPointInRectangle( 40 this.canvasTransform, 41 eventData.position, 42 this.canvasCamera, 43 out position); 44 this.connectionHandle.anchoredPosition = position; 45 } 46 47 public void OnEndDrag(PointerEventData eventData) 48 { 49 ConnectionManager.RemoveConnection(this.tempConnection); 50 Destroy(this.tempConnection.gameObject); 51 this.tempConnection = null; 52 Destroy(this.connectionHandle.gameObject); 53 this.connectionHandle = null; 54 55 EventSystem.current.RaycastAll(eventData, this.raycastResults); 56 foreach (var raycastResult in this.raycastResults) 57 { 58 var port = raycastResult.gameObject.GetComponent<InputPort>(); 59 if (port != null) 60 { 61 var portTransform = port.transform as RectTransform; 62 ConnectionManager.CreateConnection(this.rectTransform, portTransform as RectTransform); 63 var connection = ConnectionManager.FindConnection(this.rectTransform, portTransform); 64 var points = connection.points; 65 points[0].direction = ConnectionPoint.ConnectionDirection.East; 66 points[0].color = this.GetComponent<Image>()?.color ?? Color.white; 67 points[1].direction = ConnectionPoint.ConnectionDirection.West; 68 points[1].color = port.GetComponent<Image>()?.color ?? Color.white; 69 } 70 } 71 } 72 73 private void Awake() 74 { 75 this.rectTransform = this.transform as RectTransform; 76 var canvas = this.rectTransform.root.GetComponent<Canvas>(); 77 this.canvasTransform = canvas.transform as RectTransform; 78 this.canvasCamera = canvas.worldCamera; 79 } 80}

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

C#

1using UnityEngine; 2 3public class InputPort : MonoBehaviour 4{ 5}

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

ノードを接続

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

投稿2019/03/14 10:44

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問