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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

2回答

2342閲覧

Unity Visual Scripting(Bolt)でDictonaryのStruct型の要素値が同一になりユニーク値にならない

koz555

総合スコア5

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2021/04/30 02:56

編集2021/05/02 09:48

Unity公式フォーラムでも回答がつかないので、こちらで質問させてください。

Unity 2021 Visual Scripting(bolt)で、Dictionaryにint,myStructをsaved variableとして使用したいです。
boltのインスペクタで変数が表示される所までは上手く出来ました。
しかしdicionary key0の変数timeLinePrefabにAを設定し、key1にはBを設定すると、key0のAもBの値に上書きされてしまいます。
これを回避するにはどうすれば良いですか?

using UnityEngine; using Unity.VisualScripting; [System.Serializable] [Inspectable] public struct StageStruct { [Inspectable] public GameObject timeLinePrefab; [Inspectable] public Material backGroundMaterial; // nullならステージ1のマテリアル使用する事 [Inspectable] public bool isCleard; [Inspectable] public int cleardScore = 0; }

イメージ説明

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

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

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

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

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

koz555

2021/05/02 07:45

すみません、class→structの間違いでした
guest

回答2

0

ベストアンサー

Boltはほとんど経験がなくて的外れかもしれませんので、あくまでも参考程度ということでご容赦ください。

ある要素のプロパティを書き換えると他の要素のプロパティも一斉に変わってしまうのは、確かに値型と参照型の挙動と違い(参考:値型と参照型 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C)を連想したのですが、試しに下記のようにclassstructにしてみても...

lang

1using UnityEngine; 2using Unity.VisualScripting; 3 4[System.Serializable] 5[Inspectable] 6public struct StageStruct 7{ 8 [Inspectable] public GameObject timeLinePrefab; 9 [Inspectable] public Material backGroundMaterial; // nullならステージ1のマテリアル使用する事 10 [Inspectable] public bool isCleard; 11 [Inspectable] public int cleardScore = 0; 12}

やはり同様に変な挙動になってしまいました。

図1

何かこの現象を回避する手はないものか、といじっているうちに至った手段として...

  • 「New Item:」欄の値側の型はひとまずStageStruct以外の型を選択する。
  • キー側のキーを書き換えながら、必要な数の要素をひととおり追加してしまう。
  • 要素が揃ったところで、個々の要素の型をStageStructに切り替える。

としたところ、下図のように個々の要素を個別に編集できました。

図2

ですがどうにも面倒で、何か根本的な解決法が欲しいところではあります。「Inspectable属性を付けるだけでBolt上で使用可能になる」という機能は魅力的なだけに残念な感じですね。
radianさんの「設定している部分のソースが無いので」とおっしゃるのはもっともな話で、デバッガで挙動を追跡すれば手がかりが見つかるかもしれないとは思いました。ですが情けないことに、私にとってはどうにも複雑怪奇なコードで挫折しました...今後のアップデートで修正されるのを期待したいところです。

組み込みの型ではこのような変な現象は起こらないようですが、組み込みの型と独自の型で何が違うのだろうか...と考え、もしかすると型を画面上に描画する機構が用意されているかどうかに起因するのかもしれない、と思いました。
そこで下記のように...

lang

1using System; 2using UnityEngine; 3#if UNITY_EDITOR 4using UnityEditor; 5 6[CustomPropertyDrawer(typeof(StageStruct))] 7public class StageStructDrawer : PropertyDrawer 8{ 9 public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 10 { 11 return EditorGUI.GetPropertyHeight(property); 12 } 13 14 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 15 { 16 EditorGUI.PropertyField(position, property, label, true); 17 } 18} 19#endif 20 21[Serializable] 22public struct StageStruct 23{ 24 public GameObject timeLinePrefab; 25 public Material backGroundMaterial; // nullならステージ1のマテリアル使用する事 26 public bool isCleard; 27 public int cleardScore; 28} 29 30namespace Unity.VisualScripting.Generated.PropertyProviders 31{ 32 [SerializedPropertyProvider(typeof(StageStruct))] 33 public class PropertyProvider_StageStruct : SerializedPropertyProvider<StageStruct> 34 { 35 } 36}
  • classではなくstructとする。
  • Inspectable属性は外してしまう。
  • StageStructDrawerを追加し、ここに描画処理を記述する。
  • Bolt上で使えるようにPropertyProvider_StageStructも用意する。

としたところ、下図のように個々の要素が独立するようになりました。

図3

とはいえこれはこれで手間がかかりますし、表示のされ方も少々ブサイクです。見栄えをよくするにはもっとしっかりStageStructDrawerを作り込む必要があり、ますます面倒になってしまいそうですね...

投稿2021/05/02 06:37

Bongo

総合スコア10811

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

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

koz555

2021/05/02 08:15 編集

再現までして頂きありがとうございます。 その後classになっていたので「あらっ!」と思い変えてもこちらも同じでした。 Listだと普通に使えます。 あれこれ調べ再度基礎を見直しても分からず、調べた所UnityのGenericは標準ではListはシリアライズ可能だがDictionaryはいろいろな理由から非サポートらしいということが分かりました。 拡張してまでも面倒だし後々アップデートなどで急に使えなくなったりなど面倒な事になりそうなのでBolt上ではDictionaryにStruct orカスタム型を使うのは断念しました。 【Unity】Genericなクラスをシリアライズで来た - テラシュールブログ http://tsubakit1.hateblo.jp/entry/2019/11/01/225048 また、以下を読んでStructも使わんとこう…と思いました。 C#に潜むstructの罠 - KAYAC engineers' blog https://techblog.kayac.com/trap-around-struct-in-csharp 今は不変部分はScriptable Objectに分け、保存必要なSavedパラメータはListにして試している所です。 今度はBolt上でList<CustomType>がLinq(個人開発の小さいゲームなのでパフォーマンスよりも書きやすさ重視です)のWhere的なフィルタ使い方がわからず、結局この部分はC#で書いた方が早いのか(マウスポチポチで作っていきたいタイプなのでBoltでなるべく完結させたいのですが)と思っています。 どなたかboltに詳しい方がいらっしゃるかもしれないし、dictionary(簡単に)使えたら便利なのでもうしばらく質問はオープンにしておきます。
guest

0

単純に同じオブジェクトを設定しているだけではないかと推定しますが、設定している部分のソースが無いので断定はできません。名前がStageStructなのにclassなのも突っ込みたいところですが…
構造体とクラスの違いは理解していますか?
構造体型 (C# リファレンス)
クラスと構造体の違い
あと、オーバーライドも単語の意味を分かってなさそうなので、C#の基本から一度きちんと学習し直す事をお勧めします。

投稿2021/04/30 03:32

編集2021/04/30 03:34
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問