takeyohのおぼえがき

気になったこと、試したことの記録です。

lua scriptを使ってヘリコプターを飛ばす!そしてターボ!

twitterでUtakさん@utak_acから教えていただいた技で、ヘリコプタAIRWOLFを飛ばしてみたので、その覚書です。

ホントに何でもできるのでは?と思うほど、アセットコルサは凄いゲームですが、car mod本体にかかる力の方向も制御できるんですね。

今回はlua scriptを使っています。また、extensionのext_config.iniではなく、data/script.luaとして記述しました。

 

まず、この拡張機能を利用できるようにするため、car.iniの冒頭を書き換えます。

[HEADER]
VERSION=extended-2 ; version number

このバージョン記載は、アセットコルサ単体では認識できません。

ContentManagerとCSP(1.78/1.79preview以降)の導入が必須です。

つぎに、AIRWOLF本体を制御するためのlua scriptです。

data/script.luaの中身です。

function script.update(dt)
  local dataR = ac.accessCarPhysics()
  local rotor = car.extraA and car.gear >= 1
  if rotor then
    ac.addForce(vec3(0.002, 50, 0.093), true, vec3(0, 3300*car.gear, 0), false)
  end


  local dataAB = ac.accessCarPhysics()
  local inputAB = car.extraA
  if inputAB then
    ac.addForce(vec3(0.000, 0, 0.01), true, vec3(0, 0, 3000*car.gas), true)
    ac.addForce(vec3(0.000, 0, 0.01), true, vec3(0, 0, -3000*car.brake), true)
  end

  local dataS3 = ac.accessCarPhysics()
  local inputS3 = car.extraA and car.handbrake > 0.5
  if inputS3 then
    ac.addForce(vec3(0.002, 50, 0.093), true, vec3(-3*car.steer, 0, 0), true)
  end

  local data = ac.accessCarPhysics()
  local jetActive = car.extraD and car.speedKmh > 40
  data.controllerInputs[0] = jetActive and 1 or 0
  if jetActive then
    ac.addForce(vec3(0, 0, -2), true, vec3(0, 0, 80000), true)
  end

end

いくつかのパートに分かれていますが、基本的な構成は同じです。

車の情報を取得し、インプット情報に応じて処理を行っています。

例えば一つ目のパートであれば、extraAキーが押されていて、かつギアが1以上なら、”3300xギアの値”分の上昇(+Y方向)の力が発生する、という感じですね。

addForce関数の引数説明が見当たらないので、詳細が不明ですが、第1引数は本体の角度?vec3(x,y,z)っぽいかな。第3引数は力が加わる方向vec3(x,y,z)でした。

lua-sdkのlib.luaの中に定義がありました。

---Adds force to a car, invalidates current lap.
---@param carIndex integer @0-based car index.
---@param position vec3 @Point of force application.
---@param posLocal boolean|`true`|`false` @If `true`, position is treated like position relative to car coordinates, otherwise as world position.
---@param force vec3 @Force vector in N.
---@param forceLocal boolean|`true`|`false` @If `true`, force is treated like vector relative to car coordinates, otherwise as world vector.


function physics.addForce(carIndex, position, posLocal, force, forceLocal) end

今回の設定では、carIndexが省略されてますが、

  • positionはcar modに力のかかる場所(座標)、
  • posLocalはcar mod(ローカル座標)基準ならtrue、トラック全体(ワールド座標)基準ならfalse
  • forceはcar modにかかる力の向き、
  • forceLocalはposLocalと同じ指標。

ってことですね。

3300としているのは、調整した結果です。今回AIRWOLFは車重を1000kgに設定されていますが、この重さでギアを3速(3300x3)の時、ちょうどホバリング(といってもピタッとは止まらないですが)できるくらいの力になっています。

ですので、この状態だと、1,2速にすると下降(押し上げる力<車重)、4,5速にすると上昇(押し上げる力>車重)という動きになります。

次にターボ(ジェットエンジン)についてです。

CSPのwikiを眺めていたら、

github.com

ここのページに

  • Jet engine activating with Extra A switch when car drives above 40 km/h (regular car script can add audio and particle effects, also [EXTRA_SWITCHES] SWITCH_A_FLAGS = HOLD_MODE in car config might help):

    function script.update(dt)
      local data = ac.accessCarPhysics()
      local jetActive = car.extraA and car.speedKmh > 40
      data.controllerInputs[0] = jetActive and 1 or 0
      if jetActive then
        ac.addForce(vec3(0, 0, -2), true, vec3(0, 0, 5000), true)
      end
    end

という記載がありました。

あれ?ジェットエンジン?加速できるってこと?AIRWOLFって、ターボエンジン積んでて、マッハ1で飛ぶことになってるけど、再現できるんじゃね?

と思って追記したのが、先ほどのscript.luaの最後のパート部分です。

  local data = ac.accessCarPhysics()
  local jetActive = car.extraD and car.speedKmh > 40
  data.controllerInputs[0] = jetActive and 1 or 0
  if jetActive then
    ac.addForce(vec3(0, 0, -2), true, vec3(0, 0, 80000), true)
  end

上のサンプルをそのままコピーしてます。AIRWOLFのキーアサインの都合で、ターボエンジンを有効にするキーをextraDに割り当て、40kmhを超えると、+Z(前方)方向に、80000(これ単位は何なんでしょう?Nm?)を加算するようにしました。

これでAIRWOLFは1280kmhくらい(およそマッハ1)まで加速できます。数字をもっと上げれば、いくらでも速くなりそうでしたが・・・。

それを実装して動かした動画がこちらです。

youtu.be

 

今回実装して思ったのですが、これができるなら、NIGHT2000のターボブーストも可能かも??です。今度考えてみます。

→今度といいながら、サクッと反映してみました。

で、KNIGHT2000もver1.2にアップデートです!

youtu.be

/* -----codeの行番号----- */