もう一つ覚書を。
クレーン車を持ち上げるスクリプトの話を書きましたが、同じ車での実装です。
物理制御をする、data/script.luaは表示されているLODに関係なく動作します。
一方、今回の足場の展開やクレーンのアニメーションはextensionのext_config.iniやluaスクリプトで制御します。
lodAのみで作られているcar modは問題ないのですが、今回はlodDまであるので、lodAとlodBの時は、アニメーションが反映されるようにします。
整理すると、lodAとlodBのノードを取得して、それぞれに同じアニメーションの処理を設定していきます。
今回は、ext_config.iniのANIMATIONセクションでの設定ではなく、luaスクリプトで、progressを制御していく方法を使っています。
script.update(dt)の中で、常にアニメーションの設定をし続けている場合は、現在表示されているlodがどれかをチェックして、そのlodにアニメーションを設定するという仕組みでよいのですが、動いていないときはアニメーションの設定をしない作りだと、例えばlodBでアニメーションが終了してから、近づいてlodAに切り替わるとアニメーション前の状態に戻っている、みたいなことが起きます。
ですので、アニメーションの設定自体をlodA、lodB両方にやり続けることで、同期していきます。
クレーン車の足場のアニメーションをcar_stand.ksanimとして作成しました。これはcar modのanimationsフォルダにコピーしておきます。
extensionフォルダに足場のアニメーションを制御するスクリプトとして、car_stand.luaというファイルを作成します。(中身は下に貼ります。)
extension/ext_config.iniを開き、car_stand.luaを実行するSCRIPTセクションを追記します。
[SCRIPT_...]
SCRIPT = car_stand.lua
SKIP_FRAMES = 0
ACTIVE_FOR_UNFOCUSED = 1
ACTIVE_FOR_LOD = B
ACTIVE_FOR_NEAREST = 12
通常SCRIPTセクションでSCRIPTに実行するスクリプトのファイル名を指定するだけですが、それだとlodAしか認識できません。
lodBにもアニメーションを認識させるには、
ACTIVE_FOR_UNFOCUSED = 1
ACTIVE_FOR_LOD = B
が必要です。
続いて、設定したcar_stand.luaの中身を例として記録しておきます。
local parentA = ac.findNodes('{ TRANSMISSION_R_0 & lod:A }'):getParent()
local parentB = ac.findNodes('{ TRANSMISSION_R_0 & lod:B }'):getParent()
local standAnimFront = "../animations/car_stand_front.ksanim"
local progressFront = 0
local standAnimRear = "../animations/car_stand_rear.ksanim"
local progressRear = 0
local craneAnim = "../animations/car_crane.ksanim"
local progressCrane = 0
function script.update(dt)
ac.debug('activeLOD', car.activeLOD)
if car.extraA and car.gear == 0 then
if progressFront < 0.5 then
progressFront = progressFront + dt / 10
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
elseif progressFront < 0.67 then
progressFront = progressFront + dt / 20
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
elseif progressFront < 0.81 then
progressFront = progressFront + dt / 200
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
elseif progressFront < 1 then
progressFront = progressFront + dt / 40
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
end
if progressRear < 0.5 then
progressRear = progressRear + dt / 10
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear < 0.63 then
progressRear = progressRear + dt / 20
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear < 0.67 then
progressRear = progressRear + dt / 200
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear < 0.754 then
progressRear = progressRear + dt / 160
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear < 0.784 then
progressRear = progressRear + dt / 20
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear < 1 then
progressRear = progressRear + dt / 90
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
end
if progressFront >= 1 and car.extraB then
if progressCrane < 1 then
progressCrane = progressCrane + dt / 20
parentA:setAnimation(craneAnim,progressCrane,false)
parentB:setAnimation(craneAnim,progressCrane,false)
end
elseif progressFront >= 1 then
if progressCrane > 0 then
progressCrane = progressCrane - dt / 20
parentA:setAnimation(craneAnim,progressCrane,false)
parentB:setAnimation(craneAnim,progressCrane,false)
end
end
elseif progressCrane <= 0 then
if progressFront > 0.9 then
progressFront = progressFront - dt / 40
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
elseif progressFront > 0.5 then
progressFront = progressFront - dt / 70
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
elseif progressFront > 0.0 then
progressFront = progressFront - dt / 10
parentA:setAnimation(standAnimFront,progressFront,false)
parentB:setAnimation(standAnimFront,progressFront,false)
end
if progressRear > 0.85 then
progressRear = progressRear - dt / 50
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear > 0.6 then
progressRear = progressRear - dt / 100
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear > 0.5 then
progressRear = progressRear - dt / 70
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
elseif progressRear > 0 then
progressRear = progressRear - dt / 10
parentA:setAnimation(standAnimRear,progressRear,false)
parentB:setAnimation(standAnimRear,progressRear,false)
end
end
end
こちらもぐちゃぐちゃといっぱい書いてますが、要は、最初にlodAとlodBの親ノードを取得して置いて(1,2行目)、その後のアニメーション設定をすべて、両方のノードに設定し続ける、これだけです。
これで、アニメーションしていないときに、lodAとBが切り替わっても、アニメーションの進捗が同期しているので表示は問題ありません。
もちろん、lodC, lodDは何も設定していないので、lodCの距離まで離れると、全てのアニメーションは消滅します。
以上です。