###前提・実現したいこと
Unityで車を動かす実験をしています。
WheelColliderなどですでにトルクをかけれているので後は、MT車を再現するべくエンジンの回転数とアクセル開度から出力トルクを求めれるようにしたいと思っています。
そこで、CSVファイルにそのデータを大雑把にまとめたマップファイルを作って、それを配列変数に読み込もうとしたのですが、変数への代入時にフリーズしてしまいます。
後述するソースコードのうち、先頭の変数がマップを代入したい変数、最後の二重Forの中のTorqueMap[i,j] = というのがフリーズする行です。
CSVファイルは縦11、横5のデータで、読み込み自体はできています。
###発生している問題・エラーメッセージ
実行すると初期化中にUnity自体がフリーズしてしまいます。
コメントアウトを使ってフリーズした個所を調べたところ先ほどの行に行きつきました。
エラーメッセージ等は一切出てきません。
出てくる前にフリーズです。
###該当のソースコード
C#
1public float[,] TorqueMap; 2public string FilePath; 3 4void Start () { 5 //MapFileに読み込み 6 StreamReader MapFile = newStreamReader(Application.dataPath +FilePath); 7 //読み込んだデータをstring型に変換 8 string MapStr = MapFile.ReadToEnd( ); 9 System.StringSplitOptions option =StringSplitOptions.RemoveEmptyEntries; 10 11 //行ごとに分ける 12 string [ ] lines = MapStr.Split(new char [ ] { '\r', '\n' }, option); 13 //カンマ分けの準備(区分けする文字を設定する) 14 char [ ] spliter = new char [1] { ',' }; 15 //行数 16 int h = lines.Length; 17 //列数 18 int w = lines[0].Split(spliter, option).Length; 19 20 21 //配列の要素数を宣言 22 Debug.Log (h + "," + w); 23 TorqueMap = new float[h , w]; 24 25 //行データを切り分けて,2次元配列へ変換する 26 for(int i = 0; i < 4; i++) 27 { 28 string [ ] splitedData = lines [i].Split(spliter, option); 29 for(int j = 0; j < 4; j++) 30 { 31 TorqueMap [i, j] = int.Parse(splitedData [j]); 32 } 33 } 34}
###試したこと
フリーズした行を
c#
1TorqueMap [1, 1] = int.Parse(splitedData [j]);
のようにしたところ動作しました。
しかし動作はするのですが「IndexOutOfRangeException: Array index is out of range.」というエラーが常に出続けています。
c#
1TorqueMap = new float[h , w];
という行を
c#
1TorqueMap = new float[11 , 5];
としても同じでした。
配列の数を決定するときの変数h、wをデバッグで表示させても11、5で問題はなかったです。
###補足情報
Unityは最新版で、スプリクトエディタにはMonoDevelopを使っています。
言語はC#です。
C言語自体は3年ほど遊んでますが、Unityは初めて1か月程度でいまだに独特の文法に慣れていません。
Unityで配列変数を使ったのは今回が初めてで、宣言の時点で結構躓いてます。
おそらくとっても単純なミスな気がしますが、3時間にらめっこしても自分にはわかりませんでした。
###追加
TorqueMapを利用する関数
c#
1//エンジンの駆動トルクを配列から算出する 2public float EngineTorque(float RPM, float Axel) 3{ 4 float Axel0, Axel50, Axel100; 5 int i = 0; 6 7 //配列の中からRPMの次に大きい回転数を探す 8 while (true) 9 { 10 if (TorqueMap [i, 0] <= RPM) { 11 i++; 12 } 13 } 14 //開度ごとにトルクを算出 15 Axel0 = TorqueMap[i - 1,1] + (TorqueMap[i,1] - TorqueMap[i - 1,1]) * RPM / (TorqueMap[i,0] - TorqueMap[i - 1,0]); 16 Axel50 = TorqueMap[i - 1,2] + (TorqueMap[i,2] - TorqueMap[i - 1,2]) * RPM / (TorqueMap[i,0] - TorqueMap[i - 1,0]); 17 Axel100 = TorqueMap[i - 1,3] + (TorqueMap[i,3] - TorqueMap[i - 1,3]) * RPM / (TorqueMap[i,0] - TorqueMap[i - 1,0]); 18 //Axelに応じた値を出力 19 if (Axel < 0.5) { 20 return Axel0 + Axel50 * Axel * 2; 21 } else { 22 return Axel50 + Axel100 * Axel * 2; 23 } 24} 25 26//エンジンの抵抗を配列から算出する 27public float EngineResistanceTorque(float RPM) 28{ 29 int i = 0; 30 31 //配列の中からRPMの次に大きい回転数を探す 32 while (true) 33 { 34 if (TorqueMap [i, 0] <= RPM) { 35 i++; 36 RPM = RPM - 500; 37 } 38 } 39 i = 5; 40 //抵抗をトルクを算出 41 return TorqueMap[i - 1,3] + (TorqueMap[i,3] - TorqueMap[i - 1,3]) * RPM / (TorqueMap[i,0] - TorqueMap[i - 1,0]); 42} 43 44//エンジンの回転状態、タイヤへの出力をシミュレーションする 45public float EngineOutputTorque(float GearRaito_T, float GearRaito_F, float Axel, float Clutch) 46{ 47 return EngineTorque (EngineRPM, Axel) * Clutch * GearRaito_T * GearRaito_F; 48 //EngineRPM = EngineRPM + (EngineTorque (EngineRPM, Axel) - EngineTorque (EngineRPM, Axel) * Clutch * GearRaito_T * GearRaito_F - EngineResistanceTorque(EngineRPM)) / 8f * 10f * 35f * 180f / 3.14f; 49 EngineRPM = 1000; 50}
外部から呼び出されるのはEngineOutputTorqueのみです。
上の二つは配列のがばがばなデータからそれらしい値を計算して出すようにしたつもりのプログラムでたぶん式は間違っています。
EngineOutputTorqueの式も、とりあえず頭の中の理論で組み立てたもので、おそらく間違っています。
回答1件
あなたの回答
tips
プレビュー