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

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

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

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

Unity3D

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

解決済

Listを他のスクリプトで読み出したい

syosn938
syosn938

総合スコア4

C#

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

Unity3D

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

2回答

0グッド

1クリップ

443閲覧

投稿2022/11/02 08:22

編集2022/11/07 05:11

前提

Unityでハンドトラッキングを利用したシステムを作っています。
スクリプトをまたいでのListの利用方法が分からず困っています。
勉強中に身なのでつたない質問かと思いますがよろしくお願いします。

<作成したいシステム全体の概要>
UIのボタンをクリックした時に、人差し指の先の座標にオブジェクトを生成し、リストに座標値を格納する
→他のシーンで別のスクリプトから座標値を順次呼び出して再びオブジェクトを生成する

実現したいこと

  • 作成されたListを他のスクリプトで利用したい

ヒエラルキー、インスペクターの画像

イメージ説明

発生している問題

調べながら「試したこと」に記述したような変更をしてみたのですが、ここから他のスクリプトでどのように読み出せばよいのか分かりません。
もしくはそもそも現段階で間違っていたらご指摘頂けますと幸いです。

追記:hogefugapiyo様のコードを参考にさせて頂いたところ、CheckPos.csで[SerializeField] PositionList.r_index_finger_tip_marker;の最後のセミコロンに対してerror CS1519 Invalid token ';' in class, record, struct, or interface member declaration.が出ました。

該当のソースコード

C#

1//PositionList.cs 2public class PositionList : MonoBehaviour 3{ 4 public GameObject obj; 5 public int n; 6 public int i; 7 List<Vector3> posList = new List<Vector3>();//ご提示頂いたコードを参考にBottonClickSetからこちらに移動 8 public void ButtonClickSet() 9 { 10 //List<Vector3> posList = new List<Vector3>(); 11 for (i = 1; i < n; i++) 12 { 13 Transform myTransform = this.transform; 14 Vector3 worldPos = myTransform.position; 15 float x = worldPos.x; 16 float y = worldPos.y; 17 float z = worldPos.z; 18 19 Instantiate(obj, new Vector3(x, y, z), Quaternion.identity); 20 posList.Add(new Vector3(x, y, z)); 21 22 Debug.Log("Listの値" + posList[i]); 23 24 } 25  } 26 public List<Vector3> GetPosList() 27 { 28 return posList; 29 } 30}

試したこと

ご提示いただいたコードを該当コードに追加し、呼び出す側の別のスクリプト内に下記の様に記述しました。

C#

1//CheckPos.cs 2public class CheckPos : MonoBehaviour 3{ 4  [SerializeField] PositionList.r_index_finger_tip_marker;//error CS1519 発生場所 5  public int i; 6 7 pubilic void Check(){ 8 List<Vctor3> posListY = r_index_finger_tip_marker.GetPosList(); 9 10 for(int i = 0; i < posListY.Count;i++){ 11 Debug.Log(posListY[i]); 12 } 13 } 14}

補足情報(FW/ツールのバージョンなど)

Unity 2021.3.4f1

以下のような質問にはグッドを送りましょう

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

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

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

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

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

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

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

適切な質問に修正を依頼しましょう。

len_souko

2022/11/04 06:13

PositionListとは何ですか? 提示されたソースコードでは以下の部分でしか登場していません new PositionList.GetPosList(); また、そもそも文法的に誤りです。 ただ、誤りであることは間違いないのですが、物が分からない以上はどうすべきなのかも判断付きません。 必要な箇所だけと思って切り出したのでしょうが、切り出していないソースコードはあなたしか知りませんので、そこに起因することはあなた以外では誰にも判断できませんので、記載してください。 また、Unity特有の機能もありますので、インスペクター等も画像で貼っておくとより話が通じやすくなるかと思います。
syosn938

2022/11/04 06:17

ご指摘並びにアドバイスありがとうございます。 不足している情報について追記いたします。
len_souko

2022/11/04 12:59 編集

> List<Vctor3> posListY = new PositionList.GetPosList(); まず、こちらの一行で問題点が色々あります ・new はクラスのインスタンスを生成するために行う物であり、この書き方だとPositionListクラスの中にGetPosListクラスを定義していないと文法上意味が通りません=>メソッドとして定義してあるので「new」が不要 ・PositionListクラスのインスタンスメソッドをインスタンス経由経由でなくクラス名から読んでいる為staticメソッドとして呼ぼうとしている=>内容を見ても返す値がインスタンスに属するフィールドなのでstaticでは存在していない為無理 ・PositionListのインスタンスがどこにどうあるものなのかの情報が無いため、PositionListをアタッチしているGamObjectとCheckPosをアタッチしているGameObjectが何なのか分かるようにインスペクターを見せてくれないと無理 と、先に書いたインスペクター等も画像で貼ってくれないと誰も状況が分からないという話です syosn938さんにはご自身のパソコンで見ているから状況が見えて入るはずですが、他の人にはあなたのパソコンの画面は見れないのでGameObjectやスクリプトがどのようにアタッチされているのか分からないので回答しようにもできない状況です なお、初心者マークを付けていて現在のこの質問で提示する情報の具合から言って状況は見えているかもしれないけど理解は出来ていないかと思われます なので、不要だと判断して提示しないままだと解決はしないと思いますので、とりあえずヒエラルキーを展開して提示されたスクリプトがアタッチされているところが確認できるインスペクターと両方を画像にとって貼り付けてみて下さい
syosn938

2022/11/04 13:08

丁寧なご指摘ありがとうございます。 土日は開発に使用しているパソコンが使えないため、月曜になりましたらすぐに確認して画像を添付します。 至らない点が多く非常に申し訳ないです。
hogefugapiyo

2022/11/08 00:33 編集

加筆返信しようと思ったのですが他の方が解説いただいたので、そちらご参考ください。 [SerializeField] で参照を取って、その対象からメソッドを叩きたかったという形になります! PositionList 型の変数を定義して、それをシリアライズすることでインスペクター上からドラッグ&ドロップで対象となるGameObjectを指定する…といった流れを想定していました。 そのためそこに記述すべきなのは [SerializeField] PositonList 変数名; となります。 下記URLなども確認してみてください。 http://maniera.xyz/2019/11/18/post-368/ https://a-craftron.com/2021/03/02/2709/

回答2

0

ベストアンサー

質問へのコメントとして書いていましたが、ここでやり取りする分には回答になるのでは?と思ったのでこちらへコピペしています
その為、マークダウンをきちんと使用していないので見づらいかもしれませんがご了承ください。

[SerializeField] PositionList.r_index_finger_tip_marker;

[SerializeField]はUnityが内部で持っているフィールドをシリアライズ化してインスペクターで操作できるようにする機能などに利用されています。C#の文法的には属性と呼ばれるものです。
PositionListはクラス名です
「.」は名前空間やクラス名やクラスのインスタンス(オブジェクトともいわれたりします)の配下の名前空間・クラス・メソッド・フィールド・プロパティ等を指定する際に使用します。「三丁目の田中さん」であれば「三丁目.田中さん」となりますし、「佐藤さんの眼鏡」であれば「佐藤さん.眼鏡」といった感じです(変な例ですが)
つまり、ここで書かれている内容だと次のフィールドをインスペクターで使えるようにして!とお願いしていますが、PositionList.r_index_finger_tip_markerと書いてあるので、文法の順序的にはデータ型を指定する場所なのでPositionListクラスにr_index_finger_tip_markerというデータ型などのメンバーが宣言されてないやんと怒られている状況です。コンパイラ的には多分この後ろにスペースを置いてフィールド名が書かれるはずなのですが、型と思ったら定義されてないから分かんねーわと判断したことになります
でも、r_index_finger_tip_marker.GetPosList();を見る限り、r_index_finger_tip_markerは肩を指し示すものではなく、PositionListのインスタンスと思われます。なので、PositionList.r_index_finger_tip_markerではなくて、PositionList r_index_finger_tip_marker(半角スペースで繋ぐ)がやりたかったことと思われます。

Unityを扱う方によく見られるのですが、兎にも角にもC#の文法を勉強してから始めてください
漠然とC#の文法を勉強しようとすると公式サイトでは難しそうに思えて即挫折するかもしれないので、
https://ufcpp.net/
まずはこちらを見て上のメニューのC#をクリックで表示されるC#の億時ページの特に基礎まわりをしっかりと読んでからやりましょう

その上で、Unityの話が始められるようになると思います
でもってそっちの話だと、そもそも「r_index_finger_tip_marker」はGameObjectです。
Unityの不便なところですが、インスペクターには何を追加したのかが後からは分からないところですね
Cubeだったり色々と
ただGameObjectであることは間違いないので、CheckPosを先に挙げたように修正してやるとアタッチしているGameObjectのインスペクターにPositionList型のGameObjectを設定する(用語忘れました)欄が出てきますので、r_index_finger_tip_markerをインスペクターから設定してあげれば、List<Vctor3> posListY = r_index_finger_tip_marker.GetPosList();
が文法上はおかしくなくなるはずです。
ButtonClickSetが呼ばれる前だと空っぽのリストだけどエラーにならないように考えているか?逆にButtonClickSetを複数回呼ぶとクリアせずに同じ情報源からデータを追加して要るっぽいので重複登録されまくりでは?といった疑問はあるけれど、そこらあたりはお仕事っぽいので先輩に訊いてください

投稿2022/11/07 12:27

len_souko

総合スコア1307

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

このような回答には修正を依頼しましょう。

回答へのコメント

syosn938

2022/11/10 03:57

丁寧な説明と何をすべきかまで教えて頂きありがとうございます。 とりあえず今回質問させて頂いたことはlen_souko様、hogefugapiyo様や皆さんのご助力のおかげで達成できました。 今後はまずC#の基礎を学んでいきたいと思います。 ありがとうございました。

0

新しいほう

すいません、私の前提が間違っていたかも。これらのスクリプトはGameObjectなどにアタッチされてたりしますか?
CheckPosからListを見に行こうとする場合、PositionListのことを知っておく必要があります。

アタッチして参照を取るか、コンポーネントから探すなどといった形で参照することができます。

cs

1//CheckPos.cs 2public class CheckPos : MonoBehaviour 3{ 4  [SerializeField] PositionList obj; // こうしてインスペクターからPositionListがついたオブジェクトをアタッチしてもOK 5  public int i; 6 7 pubilic void Check(){ 8 9 List<Vctor3> posListY = obj.GetPosList(); 10 11 for(int i = 0; i < posListY.Count;i++){ 12 Debug.Log(posListY[i]); 13 } 14 } 15}

cs

1//CheckPos.cs 2public class CheckPos : MonoBehaviour 3{ 4  public int i; 5 6 pubilic void Check(){ 7 // 無理やりオブジェクトタイプで検索して拾ってくるやり方:ヒエラルキー上にアクティブな状態なら拾えるはず(あんまり良くないですが暫定的に 8 var _obj = FindObjectOfType<PositionList>(); 9 List<Vctor3> posListY = _obj.GetPosList(); 10 11 for(int i = 0; i < posListY.Count;i++){ 12 Debug.Log(posListY[i]); 13 } 14 } 15}

下記最初の書き込み

提示コードがいまいち分からずですが、Listを外部から拾えるようにして
外部から参照できれば目的の挙動に近づく気がします。

getter/setterを設定してもいいかも。
https://unitygeek.hatenablog.com/entry/2017/04/15/143053

cs

1List<Vector3> posList = new List<Vector3>(); 2 3public void ButtonClickSet() 4 { 5 // List<Vector3> posList = new List<Vector3>(); 6 for (i = 1; i < n; i++) 7 { 8 Transform myTransform = this.transform; 9 Vector3 worldPos = myTransform.position; 10 float x = worldPos.x; 11 float y = worldPos.y; 12 float z = worldPos.z; 13 14 Instantiate(obj, new Vector3(x, y, z), Quaternion.identity); 15 posList.Add(new Vector3(x, y, z)); 16 17 Debug.Log("Listの値" + posList[i]); 18 19 } 20 } 21 22public List<Vector3> GetPosList (){ 23 return posList; 24}

他のスクリプトからGetPosList()を呼べば、posListが返ってくるかなと思います

投稿2022/11/02 08:34

編集2022/11/04 09:22
hogefugapiyo

総合スコア3222

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

このような回答には修正を依頼しましょう。

回答へのコメント

Zuishin

2022/11/02 09:33

C# にグローバル変数はありません。 Unity の C# がマイクロソフトの C# とは違うという俗説もデマです。 この回答で説明されているのは一見トップレベルステートメントのローカル変数に見えますが、Unity の話なのでフィールドではないでしょうか。
hogefugapiyo

2022/11/02 10:01

ありがとうございます。けしときました
fana

2022/11/04 02:56

(重箱の隅な感じですが,コード内の先頭の注釈に「グローバル変数」という記述が残ってますよ)
syosn938

2022/11/04 04:52

皆様ご回答ありがとうございます。 今、提示していただいたコードをもとに呼び出す側のスクリプトを記述しているのですがエラーが出てしまいます。 質問文に追記しますのでよろしければご教授ください。
hogefugapiyo

2022/11/04 09:20 編集

すいません、私の認識が間違っていたかもしれません。GameObjectとかにアタッチして使うスクリプトで合ってますでしょうか。 PositionListの関数をたたきにいくので、そいつの参照を取る前提で考えていました。加筆してみたのでもし認識こっちであってたら試してみていただければと
syosn938

2022/11/07 05:38 編集

お返事遅くなり、またこちらの情報が不足していたことでお手数おかけして申し訳ございませんでした。 r_index_finger_tip_markerというオブジェクトにPositionList.csをアタッチしています。 ご提示いただいた方法を試してみたところシリアライズが上手く反応していないようでエラーが出てしまいました。[SerializeField] int i;など簡単なもので試したところ上手くシリアライズできたのでリストは扱いが異なるのでしょうか? 再度情報を追加致しましたのでもしよろしければご助力頂けますと幸いです。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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

C#

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

Unity3D

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