🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1361閲覧

structで作ったListから、Rigidbodyを取得し、操作したい。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2019/09/08 13:21

前置き

Unityでターン制の3DRPGを作っています(ポケモンに近い感じです)。プレイヤーが自由に操作できる通常状態(矢印キーなどでどこにでも移動できる状態)から、周囲をさまよっているモンスターに触れる事で戦闘が始まります。戦闘はターン制なので、矢印キーなどでは操作できません(戦う、逃げるなどのコマンド)。

困っている事

戦闘が始まる際、プレイヤーが勝手に動いてしまう(仕様上X軸とZ軸の移動と、全ての軸の回転を止めなければならない)のを防ぐために、Rigidbodyを操作する必要がありました。そこで、前から使っていたキャラクターの情報を入れたList(プレイヤーとは別のオブジェクトにアタッチしている)を利用することにしました。このリストは、シーンが切り替わるたびに、シーン間を移動するので、常にプレイヤーと共に共存しています。このリストにプレイヤーのRigidbodyを入れ、参照しようと思ったのですが、うまくいきませんでした。一応先にコードを貼ります。

Unity

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Linq; 5 6public class CharacterData : MonoBehaviour 7{ 8 public List<CharaList> CharaData = new List<CharaList>(); 9 public List<Rigidbody> EntityRigidBodys = new List<Rigidbody>(); 10 11 [System.Serializable] 12 public struct CharaList 13 { 14 public string name; 15 public string roll; 16 public float STR; 17 public float DEX; 18 public GameObject EntityObjects; 19 public Rigidbody rb; 20 } 21 22 void Start() 23 { 24 CharaData.Add(new CharaList() 25 { 26 name = "Player1", 27 roll = "Player", 28 STR = 10f, 29 DEX = 5f, 30 EntityObjects = GameObject.FindWithTag("Player"), 31 rb = GameObject.FindWithTag("Player").GetComponent<Rigidbody>() 32 }); 33 CharaData.Add(new CharaList() 34 { 35 name = "Boss1", 36 roll = "Boss", 37 STR = 10f, 38 DEX = 10f, 39 EntityObjects = GameObject.FindWithTag("Boss"), 40 rb = GameObject.FindWithTag("Boss").GetComponent<Rigidbody>() 41 }); 42 } 43 44 public void GetAllRigidbody() 45 { 46 EntityRigidBodys = CharaData.FindAll(rb); 47 EntityRigidBodys.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotation; 48 } 49}

発生したエラー

Assets/Scripts/Test Data/CharacterData.cs(46,46): error CS0103: The name 'rb' does not exist in the current context Assets/Scripts/Test Data/CharacterData.cs(47,26): error CS1061: 'List<Rigidbody>' does not contain a definition for 'constraints' and no accessible extension method 'constraints' accepting a first argument of type 'List<Rigidbody>' could be found (are you missing a using directive or an assembly reference?)

このコードはGetAllRigidbody()のなかの、CharaData.FindAll()でrbの要素を全検索し、一つ下の行でRigidbodyのプロパティを変更しようとしています。ですが、おそらく私の検索力不足のせいで使い方を間違っている可能性があります。

実現したいこと

ゲームの仕様上、戦闘するキャラクターを事前に決めておくことができないので,Rigidbody取得方法としてはGetComponentしかありません。その条件をクリアした上で、Listで自由に入れ替えができるようにし、そのListの中からRigidbodyを参照できるようにしたいです。ご教授いただければ幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Linq; 5 6public class CharacterData : MonoBehaviour 7{ 8 public List<CharaList> CharaData = new List<CharaList>(); 9 10 [System.Serializable] 11 public struct CharaList 12 { 13 public string name; 14 public string roll; 15 public float STR; 16 public float DEX; 17 public GameObject EntityObjects; 18 public Rigidbody rb; 19 } 20 21 void Start() 22 { 23 CharaData.Add(new CharaList() 24 { 25 name = "Player1", 26 roll = "Player", 27 STR = 10f, 28 DEX = 5f, 29 EntityObjects = GameObject.FindWithTag("Player"), 30 rb = GameObject.FindWithTag("Player").GetComponent<Rigidbody>() 31 }); 32 CharaData.Add(new CharaList() 33 { 34 name = "Boss1", 35 roll = "Boss", 36 STR = 10f, 37 DEX = 10f, 38 EntityObjects = GameObject.FindWithTag("Boss"), 39 rb = GameObject.FindWithTag("Boss").GetComponent<Rigidbody>() 40 }); 41 } 42 43 public void GetAllRigidbody() 44 { 45 foreach(var rb in CharaData.Select(chara => chara.rb)) 46 { 47 rb.constraints 48 = RigidbodyConstraints.FreezePositionX | 49 RigidbodyConstraints.FreezePositionZ | 50 RigidbodyConstraints.FreezeRotation; 51 } 52 //もしくは 53 //foreach(var chara in CharaData) 54 //{ 55 // chara.rb.constraints 56 // = RigidbodyConstraints.FreezePositionX | 57 // RigidbodyConstraints.FreezePositionZ | 58 // RigidbodyConstraints.FreezeRotation; 59 //} 60 61 } 62}

rbはCharaListのフィールドであるため、CharacterDataの中でrbと言っても誰?そんなやつは現在のコンテキストに居ないよ?というのが1個めのエラー(CS0103)です。

2個めのエラーはList<Rigidbody>にはconstraintsというものが存在しない。何だそれは?というエラーです。

Linqやforeachを用いたコレクションに対する列挙操作の基本が欠けているように思えます。foreach文、Linq、またLinqを使う上で良く一緒に用いるラムダ式について学べば、今後似たようなことをする際に困ることはないでしょう。

あと、CharaListとCharaData、名前をつけるなら逆じゃないでしょうか・・・・

他にも問題がありそうな点はありますが(敵増やすたびにStartのコード書き直してタグ増やすのか、同じ内容のFindが2回連続で呼ばれている等)、今の時点でわかりやすく説明できる自信がないので、また何か問題があったら質問してください。

投稿2019/09/08 16:59

編集2019/09/08 17:04
Ram.Type-0

総合スコア424

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

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

退会済みユーザー

退会済みユーザー

2019/09/10 00:15

解決いたしました!ありがとうございます。もう少し勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問