https://linen.dev logo
カスタムボタンで放送を
# forum
i
タイトルの通りカスタムボタンに複数の文字を入れその文字にあった列車の放送を再生できるようにしたいです
h
カスタムボタンの取得は通常、 dataMap.getInt("Button0")やdataMap.getInt("Button1")といったようにして取得します。 返り値は0から始めるインデックス番号なので、それを考慮して条件分岐を設定する形になります。 ボタンの表示内容を文字列として取得したいという感じでしょうか
Copy code
js
    var isOldVer = Packages.jp.ngt.rtm.RTMCore.VERSION.indexOf("1.7.10") !== -1;

    var entity = su.getEntity();
    var dataMap = entity.getResourceState().getDataMap();
    var config = null;
    if (isOldVer) config = entity.getModelSet().getConfig();//configを取得(1.7.10)
    else config = entity.getResourceState().getResourceSet().getConfig();//configを取得(1.12)

    var customButtons = Java.from(config.customButtons);//jsonのcustomButtonsを取得 & Java配列からjs配列に変換

    //Button0の中身(jsonでの定義)を取得する
    var button0 = customButtons[0];

    //現在表示しているボタンの内容をbutton0から取得する
    var button0Index = dataMap.getInt("Button0");//現在選択してるボタンのインデックスを取得
    var announceData = button0[button0Index];//配列とインデックスから内容を取得
動作実証はしてませんがおそらくこんな感じかなと思います。
i
いえ、そうでわなくてただ単に音声ファイルを流す仕組みを作りたいだけです車内放送みたいな感じの
p
カスタムボタンを使用するならこのようなスクリプトの記述が必須です
h
カスタムボタンで内容を選択+キー入力で放送を再生、という実装をしたい感じですかね。であれば、キー入力→再生部分は https://discord.com/channels/799152792518393917/1346814237493952532/1346836962379567214 を参考に、再生処理の部分で更に条件分岐を設けて実装することでできるかなと思います。 ただ、すでに放送音声を流す仕組みがRTMで用意されているので、わざわざスクリプトで実装する意図はわかりかねますが...
h
実際、カスタムボタンで鳴らすほどなら、車内放送選んでI押すのが早そう どのみちカスタムボタン開いて鳴らすのと労力さして変わらんし アクションパーツとかも面白そうではあるけど、放送鳴らすなら動作の確実生が高い方が良いからなあ
i
このコードはサウンドScriptの方に記述でしょうか?
h
そのとおりです
i
機能としては変わりますがこのカスタムボタンの物を例えば線路の下に検知などを置き自動でアナウンスということは可能でしょうか?
customボタンはjsonになにか変更がいりますか?
h
返信遅くなってすみません ・検知器経由で音を鳴らす方法について やり方は色々ありますが、基本的には地上子で接触検知→DataMap設定→音声スクリプトでDataMapを拾って再生という手順になると思います。 ATSAssistModのIFTTTブロックを使用すれば検知→DataMap設定までをスクリプトを書かずに実装できます。 音声スクリプト側の実装としては、指定のキーで受信を待機、直前まで再生していた音声名と差があれば1度だけ再生を実行という感じの実装になるかなと思います。
Copy code
js
function onUpdate(su) {
    var entity = su.getEntity();
    var dataMap = entity.getResourceState().getDataMap();

    var announceReceive = dataMap.getString("announceReceive");//キー: announceReceive で受信
    var playedAnnounceName = dataMap.getString("playedAnnounceName");//直前に再生した音声
    if (announceReceive !== playedAnnounceName) {//最後に再生した音声名と受信した音声名が違うとき
        dataMap.setString("playedAnnounceName", announceReceive, 0);//保存
        var soundData = announceReceive.split(":");// ":" でドメイン名と音声名を分離 ※dataMapでは "sound_◯◯:soundname" を流す
        su.stopSound(soundData[0], soundData[1]);//すでに再生されてると再生できないので停止する
        su.playSound(soundData[0], soundData[1], 1.0, 1.0, false);//1度だけ再生
    }
}
IFTTT側ではTrainDataMapでDataType:String、Key:announceReceive、Valueに流したい音声の名前をドメイン付きで指定(例えば sound_hi03nex:e259.nexChime )をすれば流れるかなと思います(動作未検証) ・Customボタンのjson登録について 下記のとおりです。ただし、純正RTM1.7.10ではカスタムボタン未実装になります(1.12及びKaizPatchでのみ使用可能)。
Copy code
json
"customButtons": 
  [
    ["Time:MC","Time:Real"],
    ["typeA", "typeB", "typeC", "typeD"]
  ]
getInt("Button◯◯")の返り値は選択しているボタンのインデックス番号(0から数える)になります。
例では各車がIFTTT通過時に音声を鳴らすようにしましたが、先頭車から編成全体で同期再生する場合は先頭車のみ検知で、検知時に先頭車からFormationを回してDataMapを設定していく感じになります。
i
ええっと必要なScriptはどれになるのでしょうか?
CustomぼたんはjsonへScriptはSoundスクリプトに導入でよろしいですか?
h
そうです
i
IFTTブロックの設定はどうなるのでしょうか? あと列車ごとの種別の取得方法も教えて欲しいです
h
IFTTTブロック側では種別の検知する機能がないので、DataMapに識別番号をつけてスクリプト側で処理するしかないと思います そもそもRTM自体に種別を設定する機能がないので、何を持って種別を判断するかを考えておく必要があります(方向幕を参照するのか、放送を参照するのか、カスタムボタンを参照するのかなど) ・IFTTT側の設定 IFに単純列車検知[全車]もしくは指向性をもたせる場合はTrainDirection(Yaw) THENにTrainDataMapでDataType:String、Key:announceReceive、Valueに再生する音声のドメイン名:音声名:識別番号、例) sound_hi03nex:e259.nexChime:0 スクリプト側の設定
Copy code
js
function onUpdate(su) {
    var entity = su.getEntity();
    var dataMap = entity.getResourceState().getDataMap();

    var announceReceive = dataMap.getString("announceReceive");//キー: announceReceive で受信
    var playedAnnounceName = dataMap.getString("playedAnnounceName");//直前に再生した音声
    var soundData = announceReceive.split(":");// ":" でドメイン名/音声名/識別番号を分離 ※dataMapでは "sound_◯◯:soundname" を流す
    var receivedTrainType = soundData[2];//受信した識別番号を取得
    //var trainType = entity.getTrainStateData(8);//方向幕IDをtrainTypeにする
    //var trainType = entity.getTrainStateData(9);//放送IDをtrainTypeにする
    //var trainType = dataMap.getInt("Button0");//カスタムボタン(Button0)をtrainTypeにする
    if (announceReceive !== playedAnnounceName && trainType === receivedTrainType) {//最後に再生した音声名と受信した音声名が違うとき && trainTypeとreceivedTrainTypeが一致したとき
        dataMap.setString("playedAnnounceName", announceReceive, 0);//保存
        
        su.stopSound(soundData[0], soundData[1]);//すでに再生されてると再生できないので停止する
        su.playSound(soundData[0], soundData[1], 1.0, 1.0, false);//1度だけ再生
    }
}
trainTypeのコメントアウトは必要に応じて解除してください それから、スクリプトを書くにも私の時間を割くため、これからは部分的にでもいいので、できればご自身で書いていただければと思います(ここはスクリプトを発注する場では無いので)。 書いていく上でこういう処理をやりたいのだけど、どのように参照したらいいか?とか、こういう機能はありますか?とか、スクリプトがうまく動作しないので見てほしい、とかそういった質問であれば歓迎です。
i
わかりました。
5 Views