https://linen.dev logo
プラグドア
# forum
d
今作成している特急車両にプラグドアを実装したいのですが、スクリプトを描き始めたばかりで基礎程度のことしかわからず、作り方もわからないので困ってます。作り方を知っている方、ご教授いただけると幸いです。
y
まず、RTMでパーツを移動させる場合、単純に座標に数値を足しただけだと1フレームで瞬間移動してしまうので、徐々に変化させるための「アニメーション変数」が必要です。 また、RenderScriptはクライアント側で毎フレーム実行され、毎回の処理の間でデータを持ち越すために、何らかの保存手段を用いなければいけません。 いくつか手段はありますが、私は「datamap」と言うentity内にデータを記録する機能をよく使用しています。 datamapはまず始めに
Copy code
js
var dataMap = entity.getResourceState().getDataMap();
のように宣言した後、
Copy code
js
datamap.getHoge("key");
のようにデータを呼び出し、処理を挟んだ後、最後に
Copy code
js
dataMap.setHoge("key", data, flug);
のようにデータを記録して次回の処理に持ち越します。 "Hoge"の部分には保存したいデータの型を入れ、整数の"Int"、浮動少数値の"Double"、文字列の"String"、真偽値の"Boolean"などを使うことが出来ます。 "key"は変数名のように、データの名前を付けてあげて、 "data"に保存したいデータの変数などを、 "flug"は0~4を入れてサーバーとの同期や保存の有無などを選びます。アニメーション変数など描画スクリプト内だけで完結する場合は"0"で良いでしょう。
あとは以下のような感じで、Aの動き(X軸)とBの動き(Z軸)が加算代入/減算代入で交互に動く仕組みを作ってあげて、
Copy code
js
//宣言
var dataMap = entity.getResourceState().getDataMap();
var moveA = dataMap.getDouble("moveA");
var moveB = dataMap.getDouble("moveB");

//Aの動き
if(trigger && moveA < 1.0 && (detectTick(entity) == true)){
    moveA += 0.01;
    dataMap.setDouble("moveA",moveA,0 && (detectTick(entity) == true));
}else if(!trigger && moveA > 0.0 && moveB <= 0.0 && (detectTick(entity) == true)){
    moveA -= 0.01;
    dataMap.setDouble("moveA",moveA,0);
}
//Bの動き
if(trigger && moveB < 1.0 && moveA >= 1.0 && (detectTick(entity) == true)){
    moveB += 0.01;
    dataMap.setDouble("moveB",moveB,0);
}else if(!trigger && moveB > 0.0 && frontHoodState <= 0.0 && (detectTick(entity) == true)){
    moveB -= 0.01;
    dataMap.setDouble("moveB",moveB,0);
}
あとは可動幅の設定と描画構文を書きます。
Copy code
js
var door_X = (0.05 * moveA);//X軸に0.05m(5cm)の可動幅を設定
var door_Z = (1.0 * moveB);//Z軸に1.0m(100cm)の可動幅を設定

//描画構文
GL11.glPushMatrix();//パーツ位置を呼び出し
GL11.glTranslatef(door_X, 0.0, door_Z);//パーツ移動処理
door_FL.render(renderer);//パーツ描画
GL11.glPopMatrix();//パーツ位置を保存
これにて基本的なプラグドアのコードは完成です。 補足ですが、コード内の
Copy code
js
 (detectTick(entity) == true)
はtick処理と呼ばれ、毎フレーム動いてしまって速さがfps依存になってしまう処理速度を、1tick(通常1/20秒)毎に固定するためのコードです。私はだいたいhi03氏作成の以下の関数をお借りして呼び出してます。
Copy code
js
function detectTick(entity){//tick管理
  var entityID = entity.func_145782_y(),
      tick = renderer.getTick(entity),
      prevTickID = 1,
      prevTick = renderer.getData(entityID << prevTickID);
      renderer.setData(entityID << prevTickID,tick);
  if(prevTick==tick){
    return false;
  }else{
    return true;
  }
}
また、移動速度が速すぎたり遅すぎる場合は、加算代入/減算代入の値を増やしたり減らしたりしてみて下さい。
ドアの状態は、
Copy code
js
//1.7.10
var doorState = entity.getTrainStateData(4);
//1.12.2
var doorState = entity.getVehicleState(TrainState.getStateType(4));
で取得できます。0が両閉、1で右開、2で左開、3で両開です。作動トリガーに使ってみて下さい。
……と長々書いてまいりましたが、今回のコードは完全に私の自己流なので、色々拙い点はあるかと思います。 コードの規約がOKな方のスクリプトを解析したりして研究してみるのも良いかと思います。 (終)
d
助かりました、ありがとうございます!
再度質問させていただきます。
作ったプラグドアのコードを水音車両様の「Minato ltdExp Train A」に組み込んでみたのですが車両選択時にクラッシュします。
スクリプトを送るのでどなたか見ていただけないでしょうか?
ドアのコードの追加削除と、クランプを追加しました。それ以外は変えてません
y
車両選択時と言うことは、null除けが甘かったかも知れませんね。関数の冒頭に
Copy code
js
if(entity == null){
return;
}
みたいなコードを入れて、車両選択画面でその関数が動かないようにしてあげると落ちなくなるかもです
d
クランプの冒頭に入れてもダメでした
y
うーん、ぱっと見たところnull落ちしそうな箇所は無いし、どうしたものか……
h
クラッシュレポートがあれば何が原因で落ちているのかわかるのでそちらも上げると良いと思います(というかクラッシュの調査に必須)
パット見てみたところdoor_L、door_Rが未定義なのでそれで落ちてるかもしれませんね initにはdoor_LF、door_RFといった変数名で定義されています 描画スクリプトはfunction init(~){~}でパーツを変数に格納し、function render(~){~}で描画処理を実行する感じになります
d
直してみたんですけど無理ですね....
クラレポ送ります
The game crashed whilst rendering screen Error: java.lang.RuntimeException: On init script : org_met_ra_n_cA
y
doorMoveXの定義漏れ……?
d
お二人方ありがとうございます。解決いたしました