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

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

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

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

Unity

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

Q&A

解決済

2回答

2401閲覧

(0,0,0)のような文字列をその値のままVector3に格納したい

pf0yukineko

総合スコア17

C#

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

Unity

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

0グッド

2クリップ

投稿2018/01/16 14:09

タイトルの通りですが、
"(0,0,0)"という文字列をテキストファイルから引っ張ってきてその値をVector3に入れたいです。このような行為は可能なのでしょうか?
回答よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

文字列の加工とか解析はちょっと自信がないのですが、こんなメソッドを用意してみてはいかがでしょう?

C#

1using UnityEngine; 2 3public class TestScript : MonoBehaviour { 4 public static Vector3 StringToVector3(string input) 5 { 6 var elements = input.Trim('(', ')').Split(','); // 前後に丸括弧があれば削除し、カンマで分割 7 var result = Vector3.zero; 8 var elementCount = Mathf.Min(elements.Length, 3); // ループ回数をelementsの数以下かつ3以下にする 9 10 for (var i = 0; i < elementCount; i++) 11 { 12 float value; 13 14 float.TryParse(elements[i], out value); // 変換に失敗したときに例外が出る方が望ましければ、Parseを使うのがいいでしょう 15 result[i] = value; 16 } 17 18 return result; 19 } 20 21 private void Start() 22 { 23 Debug.Log(StringToVector3("(1, 2, 3)")); // 通常の場合 → (1.0, 2.0, 3.0) 24 Debug.Log(StringToVector3("(1, 2)")); // 成分の数が足りない → (1.0, 2.0, 0.0) 25 Debug.Log(StringToVector3("(1, 2, 3, 4, 5, 6)")); // 成分の数が多い → (1.0, 2.0, 3.0) 26 Debug.Log(StringToVector3("1, 2, 3")); // 丸括弧がない → (1.0, 2.0, 3.0) 27 Debug.Log(StringToVector3("(Infinity, -Infinity, NaN)")); // 特殊な値を含む → (Infinity, -Infinity, NaN) 28 Debug.Log(StringToVector3("(1.23e456, Foo, 1.23e4)")); // Xが大きすぎる、Yが無効な文字列、Zは有効な文字列 → (0.0, 0.0, 12300.0) 29 Debug.Log(StringToVector3("")); // 空の文字列 → (0.0, 0.0, 0.0) 30 Debug.Log(StringToVector3(null)); // 引数がnull → NullReferenceException: Object reference not set to an instance of an object 31 } 32}

投稿2018/01/16 21:40

編集2018/01/16 22:08
Bongo

総合スコア10807

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

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

pf0yukineko

2018/01/17 07:09

回答ありがとうございました。おかげさまで何とか実装できそうです。
guest

0

正規表現とLINQを使った別解で多くの値を使用する場合として紹介させていただければと思います。
なお特異値に対応していないためご了承ください。

csharp

1var Array = new List<string>{ 2"(49.407,49.803,49.167)", 3"(87.16,85.037,25.271)", 4"(29.383,50.355,15.982)", 5"(64.465,.65,17.449)", 6"(56.985,32.233,12.329)", 7"(77.615,95.882,95.838)", 8"(52.097,4.635,30.818)", 9"(99.441,25.725,82.946)", 10"(56.082,7.196,21.708)", 11"(37.538,73.773,59.15)" 12}; 13 14var vectorRegex = new Regex(@"(((\d*?)(.\d*?)?),((\d*?)(.\d*?)?),((\d*?)(.\d*?)?))"); 15 16var ParsedArray = Array.Select(val=>vectorRegex.Match(val)) 17 .Select(val=> 18 new string[]{val.Groups[1].Value, val.Groups[4].Value, val.Groups[7].Value} 19 .Select(s=> 20 float.TryParse(s,out float f) ? f : 0 21 ) 22 );

解説

正規表現について

前提
Regexについては、C#本体のSystem.Text.RegularExpressionsに含まれているためusingで追加します。

Regexのコンストラクタには正規表現パターンを入れていきますが、ここで使用しているのは下記のものです

  1. \d : 数値1文字と一致する
    • : 前のパターンが0個連続して存在する
  2. ? : 前のパターンが0ないし1存在する。*あるいは+の前に付けると最短で一致するものとして指定。
  3. () : 囲った対象をグループ化する。
  4. \ : 正規表現で使用する文字列の前に置くと文字そのものとして判別させる

(((\d*?)(.\d*?)?),((\d*?)(.\d*?)?),((\d*?)(.\d*?)?))
今回使用した上記パターンを分解すると

  1. (
  2. ((\d*?)(.\d*?)?)

2-1. (\d*?)
2-2. (.\d*?)?
3. ,
4. )

の4つで構成しています。


上記のうち2番目だけ補足します。

前半部分の(\d*?)については整数を表現しています。
後半部分の(.\d*?)?については小数点以下を表現しています。最後の?については小数点以下があるかもしれないし、ないかもしれないという感じですね
これを合成してグループ化することで整数ないし小数点以下を含む数字として表現できます。

やり方によって特異値にも対応可能だと思いますが、そのあたりは割愛します。

LINQ部分について

C#本体のSystem.Linqをusingで追加してください。

  • 1回目のSelect

ここは文字列を正規表現のふるいにかけています。

  • 2回目のSelect

正規表現をかけた結果を文字列配列に格納し、更にその配列をSelectを使って一括処理しています。

  • 入れ子のSelect

文字列の配列なのでそのまま入れると型エラーが起きるので一括してパースをかけています。
エラーが起きた場合は0を返すようにしているため、1回目のふるいで何も出なかった場合でも0を返されます。

更にSelectを使用することで複数のVector3を一括で作成することもできます

投稿2018/01/17 13:47

Argent

総合スコア59

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

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

Bongo

2018/01/17 21:28

正規表現はなかなか使う機会がなくて疎かったので、詳細なご解説をいただけて勉強になりました。正しい形式になっているか一発で検証できて、実に強力ですね!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問