(旧Wikiからベタ移植。正常に動作しない件は、おそらくFtDまわりの関数。現在の仕様と照らし合わせると修正するべき点が見えてくる、かもしれない by 移植した人)
ミサイル/魚雷系
魚雷安全信管プログラム
単純な魚雷用の信管プログラムです。
※現環境では正常に動作しません。誰か直してくれると作成者は信じています。
前提条件
1.ミサイルPOTにLUAトランスミッタがくっついている
2.ミサイルの構成にLUAレシーバがある
3.メインフレームがある
で,この状態でLuaBoxに以下のコードを書き込む。
-- 自爆システム用の安全距離。これ以上の距離かつ下の時間経過で自爆する seftyRange = 100
--- -- 自爆用の時間。上記同様 seftyOverTime = 20
--- -- 自爆システム -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function seftySystem(I, missileInfo, transceiver, missile) if missileInfo.Range > seftyRange and missileInfo.TimeSinceLaunch > seftyOverTime then I:Log("execute self Detonation") I:Log("Range2:" .. missileInfo.Range) I:Log("Time:" .. missileInfo.TimeSinceLaunch) I:DetonateLuaControlledMissile(transceiver,missile) end end
--- -- メイン. -- @param I FromTheDepthsクラス呼び出し用 function Update(I) transceiverCount = I:GetLuaTransceiverCount() for transceiver = 0,transceiverCount-1,1 do missileCount = I:GetLuaControlledMissileCount(transceiver) for missile = 0,missileCount-1,1 do missileInfo = I:GetLuaControlledMissileInfo(transceiver, missile) seftySystem(I, missileInfo, transceiver, missile) end end end
ロックオン追尾/近接信管
単純な追尾を行い、指定距離で爆発するミサイル・魚雷プログラムです。
垂直ミサイルにするなら、追尾開始を少しずらした方が良いかも。
メインフレームが認識する最寄りの敵へ追尾します。
前提条件
1.ミサイルPOTにLUAトランスミッタがくっついている
2.ミサイルの構成にLUAレシーバがある
3.メインフレームがある
--- -- 魚雷制御ループ -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function lanuncherControl(I, missileInfo, selfPosition,transceiver, missile) targetSystem(I, missileInfo, selfPosition,transceiver, missile) end
--- -- 2点間計測 -- @param target1[1..3]: 開始位置 -- @param target2[1..3]: 終了位置 function calcRange(target1, target2) return math.sqrt((target1[1] - target2[1])^2 + (target1[2] - target2[2])^2 + (target1[3] - target2[3])^2) end
--- -- 近接信管の距離 explodeRange = 0 --- -- 使うメインフレームブロックのIndex useMainFrame = 0 --- -- 追尾/信管システム. -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function targetSystem(I, missileInfo, selfPosition,transceiver, missile) if I:GetNumberOfMainframes() == 0 or I:GetNumberOfTargets(useMainFrame) == 0 then return end
--メインフレームの最優先ターゲットの情報取得 最優先の設定はAIカードで決定されてる target = I:GetTargetInfo(useMainFrame, 0)
-- メインフレームの最優先ターゲットを取得し、ミサイルとの距離を取る targetRange = calcRange(target.Position, missileInfo.Position)
--近接信管 if targetRange < explodeRange then I:Log("execute Detonation System") I:DetonateLuaControlledMissile(transceiver,missile) end --誘導 I:Log("execute targetSystem") I:SetLuaControlledMissileAimPoint(transceiver,missile,target.AimPointPosition[1], target.AimPointPosition[2],target.AimPointPosition[3]) end
--- -- メイン. -- @param I FromTheDepthsクラス呼び出し用 function Update(I) transceiverCount = I:GetLuaTransceiverCount() selfPosition = I:GetConstructCenterOfMass() for transceiver = 0,transceiverCount-1,1 do missileCount = I:GetLuaControlledMissileCount(transceiver) for missile = 0,missileCount-1,1 do missileInfo = I:GetLuaControlledMissileInfo(transceiver, missile) lanuncherControl(I, missileInfo, selfPosition,transceiver, missile) end end end
ロックオン追尾/近接信管/予想誘導(潜水艦VLS対応)
ロックオン追尾、近接信管プログラムに、更にTargetPredictionGuidance機能を追加したもの。
また、潜水艦VLSのミサイルが安定して水上まで出る様になっている。
--- -- ミサイル制御ループ -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function lanuncherControl(I, missileInfo, selfPosition, transceiver, missile) targetSystem(I, missileInfo, selfPosition,transceiver, missile) end
--- -- 2点間計測 -- @param target1[1..3]: 開始位置 -- @param target2[1..3]: 終了位置 function calcRange(target1, target2) return math.sqrt((target1.x - target2.x)^2 + (target1.y - target2.y)^2 + (target1.z - target2.z)^2) end
--- -- ベロシティから速度へ変換 -- @param vel[1..3]: ベロシティ値 function velocityToSpeed(vel) return math.sqrt(vel.x^2 + vel.y^2 + vel.z^2) end
--- -- 衝突予想地点の算出 -- @param missilePos[1..3]: ミサイルポジション -- @param missileVel[1..3]: ミサイルベロシティ -- @param targetPos[1..3]: ターゲットポジション -- @param targetVel[1..3]: ターゲットベロシティ function predict(missilePos, missileVel, targetPos, targetVel) --距離測定 range = calcRange(missilePos,targetPos) --速度差検出 speed = velocityToSpeed(missileVel - targetVel) --衝突予想時間 hitTime = range/speed --衝突予想地点の算出 return targetPos + targetVel*hitTime end
--- -- 近接信管の距離 explodeRange = 0 --- -- 使うメインフレームブロックのIndex useMainFrame = 0 --- -- 予想誘導を開始する距離 (注)あまりに遠距離から予想誘導を開始すると効率の悪い経路になる 0の場合は予想誘導をしなくなる predictionRange = 400 --- -- 潜水艦VLSが誘導を開始する高度。これ以下では海面に向かって垂直に進む (注)0以上は非推奨 guidanceStartAltitude = -20 --- -- 追尾/信管システム. -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function targetSystem(I, missileInfo, selfPosition,transceiver, missile) if I:GetNumberOfMainframes() == 0 or I:GetNumberOfTargets(useMainFrame) == 0 then return end
target = I:GetTargetInfo(useMainFrame, 0) targetRange = calcRange(target.Position, missileInfo.Position)
if missileInfo.Position.y > guidanceStartAltitude then --近接信管 if targetRange < explodeRange then I:DetonateLuaControlledMissile(transceiver,missile) end --予想誘導開始範囲内の場合、予想誘導開始 if targetRange < predictionRange or predictionRange ~= 0 then --衝突予想地点の取得 predictHitPosition = predict(missileInfo.Position, missileInfo.Velocity, target.AimPointPosition, target.Velocity) I:SetLuaControlledMissileAimPoint(transceiver,missile,predictHitPosition.x, predictHitPosition.y, predictHitPosition.z) else I:SetLuaControlledMissileAimPoint(transceiver,missile,target.AimPointPosition.x, target.AimPointPosition.y,target.AimPointPosition.z) end else --海面まで垂直上昇 I:SetLuaControlledMissileAimPoint(transceiver,missile,missileInfo.Position.x, missileInfo.Position.y+10,missileInfo.Position.z) end end
--- -- メイン. -- @param I FromTheDepthsクラス呼び出し用 function Update(I) transceiverCount = I:GetLuaTransceiverCount() selfPosition = I:GetConstructCenterOfMass() for transceiver = 0,transceiverCount-1,1 do missileCount = I:GetLuaControlledMissileCount(transceiver) for missile = 0,missileCount-1,1 do missileInfo = I:GetLuaControlledMissileInfo(transceiver, missile) lanuncherControl(I, missileInfo, selfPosition,transceiver, missile) end end end
複数体同時ロックオン追尾/近接信管/予測誘導(潜水艦VLS対応)
上のプログラムに更に複数体同時ロックオン機能を追加したもの。
自ビークルのLUA Receiverで制御されるミサイルを、LUA Transceiverごとに各ターゲットに対してほぼ均等に分配し誘導します。
ターゲットとする敵を選別するために、使用するミサイルの射程に合わせてコンフィグを設定して使ってください。
また、ミサイルをAIに発射させる場合はLocal Weapon Controllerもコンフィグと同じように設定してください。
このスクリプトはメインコンストラクト(船体)上のコンフィグtransceiverPositionに設定された座標の範囲内にあるLUA Transceiver付きのLaunch Pad、
及びコンフィグsubConstructIdsに設定されたIDのサブコンストラクト(スピンブロックやターレット等)上のLUA Transceiver付きのLaunch Padから発射される
LUA Receiverを搭載したミサイルを制御します。
コンフィグtransceiverPositionもしくはコンフィグsubConstructIdsを適切に設定しないとミサイルが誘導されません!!!
コンフィグのspotlightPositionをtrueにすると、一番最後に設置したspotlightがメインコンストラクタ(船体)上にある場合は座標が、
サブコンストラクト(スピンブロックやターレット等)上にある場合はそのサブコンストラクトのIDが表示されますのでそれを参考に設定してください。
ちなみにFtD(Unity)は左手系の座標なので、ビークルの前方方向を向いて右に行くほどxが、上に行くほどyが、奥に行くほどzが増加し、逆方向へは減少します。
また、Missile InterceptorがついているLUA Receiver搭載ミサイルは制御から外すので迎撃LUAミサイルとも同時使用できると思います。
再配布、改造ともに自由です。使用については自己責任でお願いします。
FtD_MultiLockOnLuaMissile_v1.10..txt
船底攻撃魚雷
少し深めの深度を魚雷が航行した後、一定距離内に近づくと浮上を開始し、船底を狙う魚雷
ミサイルのパーツにBallast tanksが必須。
Float depthを0にし、Buoyancy change に-0.1を入れる必要がある。
また、命中に難が出る為、Finの数も複数必要
ミサイルのパーツにONETURNがあるとなぜか誘導されなくなるので注意
魚雷のサイズによっては結構調整がシビアかも
--- -- ミサイル制御ループ -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function lanuncherControl(I, missileInfo, selfPosition, transceiver, missile) targetSystem(I, missileInfo, selfPosition,transceiver, missile) end
--- -- 2点間計測 -- @param target1[1..3]: 開始位置 -- @param target2[1..3]: 終了位置 function calcRange(target1, target2) return math.sqrt((target1.x - target2.x)^2 + (target1.y - target2.y)^2 + (target1.z - target2.z)^2) end
--- -- 近接信管の距離 explodeRange = 0 --- -- 使うメインフレームブロックのIndex useMainFrame = 0 --- -- 敵船底へ誘導を開始する距離 trackingRange = 150 --- -- 魚雷の巡行深度 0=海面 cruiseAltitude = -50 --- -- 魚雷が通り過ぎる場合は数を負に小さくする 魚雷が手前で浮上してしまう場合は数を正に大きくする 0で補正無し guidanceOffset = -0.5
--- -- 追尾/信管システム. -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function targetSystem(I, missileInfo, selfPosition,transceiver, missile) if I:GetNumberOfMainframes() == 0 or I:GetNumberOfTargets(useMainFrame) == 0 then return end
target = I:GetTargetInfo(useMainFrame, 0) targetRange = calcRange(target.Position, missileInfo.Position)
--近接信管 if targetRange < explodeRange then I:DetonateLuaControlledMissile(transceiver,missile) end
--基本的に回頭の反応が遅いので、目標位置にオフセットをつける if targetRange < trackingRange then velocityOffset = missileInfo.Velocity * guidanceOffset I:SetLuaControlledMissileAimPoint(transceiver,missile,target.AimPointPosition.x + velocityOffset.x, target.AimPointPosition.y - velocityOffset.y, target.AimPointPosition.z + velocityOffset.z) else I:SetLuaControlledMissileAimPoint(transceiver,missile,target.AimPointPosition.x, cruiseAltitude,target.AimPointPosition.z) end end
--- -- メイン. -- @param I FromTheDepthsクラス呼び出し用 function Update(I) transceiverCount = I:GetLuaTransceiverCount() selfPosition = I:GetConstructCenterOfMass() for transceiver = 0,transceiverCount-1,1 do missileCount = I:GetLuaControlledMissileCount(transceiver) for missile = 0,missileCount-1,1 do missileInfo = I:GetLuaControlledMissileInfo(transceiver, missile) lanuncherControl(I, missileInfo, selfPosition,transceiver, missile) end end end
ミサイル及び魚雷の複数体同時ロックオン追尾/近接信管/予測誘導(潜水艦VLS/船底誘導対応)
二つ上のマルチロックオンシステムを魚雷にも適応し、さらに上の船底誘導機能を追加したもの。
自ビークルのLUA Receiverで制御されるミサイル及び魚雷を、LUA Transceiverごとに各ターゲットに対してほぼ均等に分配し誘導します。
ターゲットとする敵を選別するために、使用するミサイル及び魚雷の射程に合わせてコンフィグを設定して使ってください。
また、ミサイル及び魚雷をAIに発射させる場合はLocal Weapon Controllerもコンフィグと同じように設定してください。
このスクリプトはメインコンストラクト(船体)上のコンフィグtransceiverPositionに設定された座標の範囲内にあるLUA Transceiver付きのLaunch Pad、
およびコンフィグsubConstructIdsに設定されたIDのサブコンストラクト(スピンブロックやターレット等)上のLUA Transceiver付きのLaunch Pad、から発射される
LUA Receiverを搭載したミサイル及び魚雷を制御します。
コンフィグtransceiverPositionもしくはコンフィグsubConstructIdsを適切に設定しないとミサイル及び魚雷が誘導されません!!!
コンフィグのspotlightPositionをtrueにすると、一番最後に設置したspotlightがメインコンストラクタ(船体)上にある場合は座標が、
サブコンストラクト(スピンブロックやターレット等)上にある場合はそのサブコンストラクトのIDが表示されますのでそれを参考に設定してください。
コンフィグはミサイル及び魚雷用にそれぞれあるので両方のtransceiverPositionもしくはsubConstructIdsを適切に設定してください。
ちなみにFtD(Unity)は左手系の座標なので、ビークルの前方方向を向いて右に行くほどxが、上に行くほどyが、奥に行くほどzが増加し、逆方向へは減少します。
また、Missile InterceptorがついているLUA Receiver搭載ミサイル及び魚雷は制御から外すので迎撃LUAミサイル及び魚雷とも同時使用できると思います。
再配布、改造ともに自由です。使用については自己責任でお願いします。
FtD_MultiLockOnLuaMissileAndTorpedo_v1.13..txt
地形追従ミサイル(巡行ミサイル向け)
島ばっかりな上、地面に当たってもミサイルが爆発したり壊れない現状だと趣味の域を出ないかも……?
あまりに急な地形が多いと追従が追い付かなる事も。
ミサイルのFinが2個程度必要。VLSに対応。
一応参考程度にミサイルの構成部品のサンプルを
--- -- ミサイル制御ループ -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function lanuncherControl(I, missileInfo, selfPosition, transceiver, missile) targetSystem(I, missileInfo, selfPosition,transceiver, missile) end
--- -- 2点間計測 -- @param target1[1..3]: 開始位置 -- @param target2[1..3]: 終了位置 function calcRange(target1, target2) return math.sqrt((target1.x - target2.x)^2 + (target1.y - target2.y)^2 + (target1.z - target2.z)^2) end
--- -- 使うメインフレームブロックのIndex useMainFrame = 0 --- -- 終端誘導を開始する距離 predictionRange = 300 --- -- 巡行高度 cruiseHight = 15 --- -- スタートフェーズの時間この時間でおおよその敵の方向へ向く startPhaseTime = 2 --- -- 地形高度の確認の試行回数 増やすと遠い地形まで考慮する terrainAltCheckCount = 10 --- -- 追尾/信管システム. -- @param I FromTheDepths用のクラス -- @param missileInfo ミサイル情報クラス -- @param selfPosition 自身の位置情報 -- @param transceiver 使用するLUAレシーバ -- @param missile 制御する対象ミサイル function targetSystem(I, missileInfo, selfPosition,transceiver, missile) if I:GetNumberOfMainframes() == 0 or I:GetNumberOfTargets(useMainFrame) == 0 then return end
target = I:GetTargetInfo(useMainFrame, 0) targetRange = calcRange(target.Position, missileInfo.Position)
--軌道準備フェーズ if missileInfo.TimeSinceLaunch < startPhaseTime then I:SetLuaControlledMissileAimPoint(transceiver,missile, target.Position.x, target.Position.y, target.Position.z) --巡行モード elseif targetRange > predictionRange then --中間誘導目標 適当に距離を50分割くらいで targetDirectionVector = (target.Position - missileInfo.Position) / 50 guidancePosition = missileInfo.Position + targetDirectionVector guidanceHight = 0
for i = 1, terrainAltCheckCount do terrainAltCheck = I:GetTerrainAltitudeForPosition(missileInfo.Position + targetDirectionVector * i) guidanceHight = math.max(guidanceHight, terrainAltCheck + cruiseHight) guidanceHight = math.max(guidanceHight, cruiseHight) end
if missileInfo.Position.y > guidanceHight then --急に下に誘導しない様に適当にcruiseHight程度のオフセットを足す 適当 I:SetLuaControlledMissileAimPoint(transceiver,missile, guidancePosition.x , guidanceHight + cruiseHight, guidancePosition.z) else I:SetLuaControlledMissileAimPoint(transceiver,missile, guidancePosition.x , guidanceHight, guidancePosition.z) end --終端誘導モード else I:SetLuaControlledMissileAimPoint(transceiver,missile, target.AimPointPosition.x , target.AimPointPosition.y, target.AimPointPosition.z) end end
--- -- メイン. -- @param I FromTheDepthsクラス呼び出し用 function Update(I) transceiverCount = I:GetLuaTransceiverCount() selfPosition = I:GetConstructCenterOfMass() for transceiver = 0,transceiverCount-1,1 do missileCount = I:GetLuaControlledMissileCount(transceiver) for missile = 0,missileCount-1,1 do missileInfo = I:GetLuaControlledMissileInfo(transceiver, missile) lanuncherControl(I, missileInfo, selfPosition,transceiver, missile) end end end
迎撃ミサイル多目標同時照準プログラム
AMCCと似たような優先度付けによって迎撃ミサイルを適切な敵ミサイルに誘導するLUAです。
命中率向上のための比例航法誘導付き。
Missile_Interceptor_multi-targeting_LUA_v11.txt
絶対索敵ミサイル
索敵装置なしでも絶対に相手の重心点のワールド座標に向けて飛んでいくミサイルです。ジャミング/デコイを無視します。
最新dev環境下で動作することを確認済み
function Update(I) for i = 0, I:GetLuaTransceiverCount() ,1 do MC = I:GetLuaControlledMissileCount(i) for i2 = 0 , MC-1 , 1 do I:SetLuaControlledMissileAimPoint(i,i2,I:GetTargetInfo(0,0).Position.x,I:GetTargetInfo(0,0).Position.y,I:GetTargetInfo(0,0).Position.z) I:SetLuaControlledMissileInterceptorStandardGuidanceOnOff(i,i2,false) end end end
機動・姿勢制御
フィンスタビライザー
船の傾きを能動的に制御します。
回頭時の横揺れや、推進装置による縦揺れ防止に。
HYDROFOIL=8 pitch_I=0 roll_I=0
-- ピッチ方向 P_Kp=2 P_Ti=1 -- 無限大を設定するにはnilを指定してください P_Td=5
-- ロール方向 R_Kp=0.1 R_Ti=1 R_Td=20
-- PID制御で検索してください -- 船のサイズなどによって適正値は大きく異なります -- Lpが大きいほど強く制御します -- Tiが小さいほど残留偏差の収束が速くなります -- Tdが大きいほど急激な変動へ素早く対応します -- ただし極端に設定すると逆に不安定になります
V0=1 -- コントロールする最低スピードです (0除算防止) V1=10 -- 基準となるスピードです (最大速度や巡航速度を入れればいいんじゃないかな)
-- 翼に角度を入れるとどちらへ回転するのかを指定する関数です function PitchDownFactor(I,index) return 0 end
function RollLeftFactor(I,index) pos=I:Component_GetBlockInfo(HYDROFOIL,index).LocalPositionRelativeToCom
if (pos.x>0) then return 1 else return -1 end end
function Update(I) I:ClearLogs() time=I:GetTimeSinceSpawn() dt = last_time and time-last_time or 0
pitch=I:GetConstructPitch() roll=I:GetConstructRoll() if (pitch>180) then pitch=pitch-360 end if (roll>180) then roll=roll-360 end
pitch_I=pitch_I+pitch*dt roll_I=roll_I+roll*dt
pitch_D=I:GetLocalAngularVelocity().x roll_D=I:GetLocalAngularVelocity().z
if (math.abs(I:GetForwardsVelocityMagnitude())<V0) then vel_factor=0 else vel_factor=V1/I:GetForwardsVelocityMagnitude() end pitch_input=-P_Kp*(pitch+(P_Ti and pitch_I/P_Ti or 0)+pitch_D*P_Td)*vel_factor roll_input=-R_Kp*(roll+(R_Ti and roll_I/R_Ti or 0)+roll_D*R_Td)*vel_factor
pitch_input=math.min(pitch_input,45) pitch_input=math.max(pitch_input,-45) roll_input=math.min(roll_input,45) roll_input=math.max(roll_input,-45)
for i=0,I:Component_GetCount(HYDROFOIL)-1 do local angle=PitchDownFactor(I,i)*pitch_input+RollLeftFactor(I,i)*roll_input; I:Component_SetFloatLogic(HYDROFOIL,i,angle) end last_time=time end
推力偏向+尾翼制御システム
指定したスピブロで推力偏向と尾翼制御を行い、機動力を高めるLUAです。
事前にイルミネーションライトを2つ設置する必要があります。
また、ACBでx軸とy軸用のイルミネーションライトをピッチとロールで右が10、左が5、機首上げが10,下げが5になるよう設定も必要となります。
※カスジェ航空機向け
function Update(I) --可動スピブロ指定動かしたいスピブロの番号を入れてください Tail_L = 22 --左尾翼 Tail_R = 24 --右尾翼 Thur_L = 15 --左スラスター Thur_R = 16 --右スラスター Stop_pos = 0 --初期角度 IL1 = --x軸用イルミネーションライト番号 IL2 = --y軸用イルミネーションライト番号 --可動範囲設定0~180度までが選択可能 TailAngleLim = 30 --尾翼最大角度 ThurAngleLim = 30 --スラスター最大角度 --各コントロール ON/OFF(ON=1,OFF=0) Pitch = 1 --ピッチ時操作するか Roll = 1 --ロール時操作するか Stp = 1 --初期化するか --こっから下はいじらないで! --初期化 function Stop() I:SetSpinBlockRotationAngle(Tail_L,Stop_pos)--左尾翼 I:SetSpinBlockRotationAngle(Tail_R,Stop_pos)--右尾翼 I:SetSpinBlockRotationAngle(Thur_L,Stop_pos)--Lスラスター I:SetSpinBlockRotationAngle(Thur_R,Stop_pos)--Rスラスター end --初期化 --尾翼両上げ function TailDup() I:SetSpinBlockRotationAngle(Tail_L,TailAngleLim)--左尾翼 I:SetSpinBlockRotationAngle(Tail_R,-TailAngleLim)--右尾翼 end --尾翼両上げ --尾翼両下げ function TailDdn() I:SetSpinBlockRotationAngle(Tail_L,-TailAngleLim)--左尾翼 I:SetSpinBlockRotationAngle(Tail_R,TailAngleLim)--右尾翼 end --尾翼両下げ --スラスター両上げ function ThuDup() I:SetSpinBlockRotationAngle(Thur_L,ThurAngleLim)--Lスラスター I:SetSpinBlockRotationAngle(Thur_R,-ThurAngleLim)--Rスラスター end --スラスター両上げ --スラスター両下げ function ThuDdn() I:SetSpinBlockRotationAngle(Thur_L,-ThurAngleLim)--Lスラスター I:SetSpinBlockRotationAngle(Thur_R,ThurAngleLim)--Rスラスター end --スラスター両下げ --尾翼右上げ左下げ function TailRupLdn() I:SetSpinBlockRotationAngle(Tail_L,-TailAngleLim)--左尾翼 I:SetSpinBlockRotationAngle(Tail_R,-TailAngleLim)--右尾翼 end --尾翼右上げ左下げ --尾翼右下げ左上げ function TailRdnLup() I:SetSpinBlockRotationAngle(Tail_L,TailAngleLim)--左尾翼 I:SetSpinBlockRotationAngle(Tail_R,TailAngleLim)--右尾翼 end --尾翼右下げ左上げ --スラスター右上げ左下げ function ThuRupLdn() I:SetSpinBlockRotationAngle(Thur_L,-ThurAngleLim)--Lスラスター I:SetSpinBlockRotationAngle(Thur_R,-ThurAngleLim)--Rスラスター end --スラスター右上げ左下げ --スラスター右下げ左上げ function ThuRdnLdn() I:SetSpinBlockRotationAngle(Thur_L,ThurAngleLim)--Lスラスター I:SetSpinBlockRotationAngle(Thur_R,ThurAngleLim)--Rスラスター end --スラスター右下げ左上げ --保存ステイタス確認 x = I:Component_GetFloatLogic_1(30,IL1,0)--参照先1 y = I:Component_GetFloatLogic_1(30,IL2,0)--参照先2 --保存ステイタス確認 --ピッチ判定 function JudgePitch() if (x == 10) then --機首上げ TailDdn() ThuDup() elseif (x == 5) then --機首下げ TailDup() ThuDdn() else --停止 end end --ピッチ判定 --ロール判定 function JudgeRoll() if (y == 10) then --右ロール TailRdnLup() ThuRdnLdn() elseif (y == 5) then --左ロール TailRupLdn() ThuRupLdn() else --停止 end end --ロール判定 --停止判定 function JudgeStop() if (x==0) then if(y==0) then Stop() end end end --停止判定 --管理用 if(Pitch == 1) then JudgePitch() end if(Roll == 1) then JudgeRoll() end if(Stp == 1) then JudgeStop() end end
Dedicated helibladeによるロール・ピッチ・高度制御PID-LUA
ソースコード
PID_1.txt
サンプルブループリント
Dediblade PID-LUA.blueprint
Dedicated heliblade spinnerの姿勢でロール用・ピッチ用・高度維持用を判別している。
下図の矢印の向きにスピナーの正面を配置することで制御できる。PIDのパラメータは機体に合わせて調整したほうがいいかも?
Motor driveはとりあえず最大で設定して、過剰なようであれば減らしていくとよい。
スピナーの正面方向を艦前方に、推進方向を上方にするとピッチアップ用(艦首に配置する)。
正面方向を艦後方に、推進方向を上方にするとピッチダウン用(艦尾に配置する)。
正面方向を艦左方に、推進方向を上方にするとロールアップ用(左舷に配置する)。
正面方向を艦右方に、推進方向を上方にするとロールダウン用(右舷に配置する)。
正面方向を艦前方に、推進方向を下方に、Upwards force fractionを最大すると高度維持用(重心付近に配置する)。
Ctrl+Gキーでブロックの正面方向をカメラの向きにすることができるのでそうして設置するといい。
UI
HP表示
ゲーム画面にビークルのHPを表示します。
※AI接続は不要です。適当なところにLUAboxを置いて、コードを移すだけで機能します。タブン。
function Update(I)
i=1 while (I.Fleet.Members[i].CenterOfMass~=I:GetConstructCenterOfMass()) do i=i+1 I:Log(i) end
myname = I:GetFriendlyInfoById(I.Fleet.Members[i].Id).BlueprintName myhp = math.floor(I:GetHealthFraction()*100)
I:LogToHud(myname.."HP"..myhp..[[%]])
end
Otome-Plugin(戦闘アシストHUD)
ゲーム画面に次ビークルの残燃料と残弾薬、敵の方角と距離、方向と速度を表示します。
※索敵装置、AIが必要となります。ご注意ください。
--OTOME-Plugin Ver1.0! --起動開始 if I:GetNumberOfTargets(0) > 0 then I:LogToHud('OTOME Plugin System ....Run') I:LogToHud('乙女戦闘アシストプログラム機動!') I:LogToHud('敵までの距離や方位等自艦のガイドを行うわ!') I:LogToHud('しっかりついてきなさい!!') end --起動開始
--最も近い敵との距離 if I:GetNumberOfTargets(0) > 0 then TR = I:GetTargetInfo(0,0).AimPointPosition - I:GetConstructCenterOfMass() I:LogToHud('最接近中の攻撃目標距離まで'..math.floor(TR.magnitude)..'mよ!')
--最も近い敵との方位 enemy = I:GetTargetPositionInfo(0,0) TD = enemy.Azimuth I:LogToHud('最接近中の攻撃目標は方位'..math.floor(TD)..'度よ!!')
--敵艦の速度 TS = I:GetTargetInfo(0,0).Velocity I:LogToHud('最接近中の速度は'..math.floor(TS.magnitude)..'m/sよ!')
end -- --燃料ガイド if I:GetFuelFraction(0) < 0.01 then I:LogToHud('燃料完全喪失!ちょっとぉおおお!これじゃあ只のボートよ!!')
elseif I:GetFuelFraction(0) < 0.2 then I:LogToHud('残り燃料僅か!戦闘機動が困難よ!')
elseif I:GetFuelFraction(0) < 0.5 then I:LogToHud('燃料残り半分よ!気をつけなさい!!')
else FP = I:GetFuelFraction(0) FP = FP*100 I:LogToHud('燃料残量残り'..math.floor(FP)..'%よ!') end --燃料ガイド
--弾薬ガイド if I:GetAmmoFraction(0) < 0.01 then I:LogToHud('弾薬完全損失!このままじゃダメよ!!さっさと補給しなさい!')
elseif I:GetAmmoFraction(0) < 0.1 then I:LogToHud('弾薬欠乏寸前よ!なにやってるの!?')
elseif I:GetAmmoFraction(0) < 0.5 then I:LogToHud('弾薬残り半分よ!気をつけなさい!!')
else AP = I:GetAmmoFraction(0) AP = AP*100 I:LogToHud('弾薬残量残り'..math.floor(AP)..'%よ!') end --弾薬ガイド
--敵判定 if I:GetNumberOfTargets(0) > 0 then enemy = I:GetTargetPositionInfo(0,0) TD = enemy.Azimuth
if TD >= -60 and TD <= 60 then I:LogToHud('敵は正面よ!')
elseif TD >= 120 or TD <= -120 then I:LogToHud('敵は後方よ!')
elseif TD >= 61 and TD <= 119 then I:LogToHud('敵は左舷よ!')
elseif TD >= -121 and TD <= -61 then I:LogToHud('敵は右舷よ!')
else I:LogToHud('敵機は未確認よ')
end end --敵判定
攻撃制御
置くだけ迎撃LUA
ACB置くのがだるい時、対魚雷、対ミサイルの打ち分けがしたい時にどうぞ。
・ミサイル、魚雷用の武器スロット(ALLが0で後は数字通り)
・メインフレーム番号(1個しかないなら0のまま)
・迎撃距離の設定
の編集は各自用途に合わせて設定してネ。
注意:Munition warnerやPassive Sonar 360の配置を忘れずに!
リンク
ガトリング制御LUA
使い方:
1:スピブロやらピストンやらを駆使してガトリング砲を作成する
この際、砲身を1本ずつスピブロやピストンに乗せておく事(ファイヤリングピースにLWCを設置するのを忘れずに!)
2:LUA箱を置いて中心になるスピブロと各砲身が乗ってるサブオブジェクトのIDを登録する
備考:マントルは無しの方が砲身わさわさ動かなくて良いと思うな!
----ガトリング砲用LUAスクリプト ver1.0
--中心になる(回転する)スピンブロックのSubConstructId CENTER_SPINNER = 89
--砲の乗っているSubConstructId(発射する順番で指定) CannonIDs = {92,98,96,94}
--使用する武器スロット(ALLの場合は0) WEAPON_SLOT = 0
----ヨクワカラナイならこっからさわらない
function EulerAngles(q1) local sqw = q1.w*q1.w local sqx = q1.x*q1.x local sqy = q1.y*q1.y local sqz = q1.z*q1.z local unit = sqx + sqy + sqz + sqw --if normalised is one, otherwise is correction factor local test = q1.x*q1.y + q1.z*q1.w local heading, attitude, bank if (test > 0.499*unit) then --singularity at north pole heading = 2 * math.atan2(q1.x,q1.w) attitude = math.pi/2; bank = 0 elseif (test < -0.499*unit) then --singularity at south pole heading = -2 * math.atan2(q1.x,q1.w) attitude = -math.pi/2 bank = 0 else heading = math.atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw) attitude = math.asin(2*test/unit) bank = math.atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw) end return math.deg(heading), math.deg(attitude), math.deg(bank) end
function Update(I) I:ClearLogs()
center = I:GetSubConstructInfo(CENTER_SPINNER)
rotation = center.LocalRotation local Angle = EulerAngles(Quaternion.Inverse(rotation)) Angle = Angle + 180 I:Log(Angle) --I:Log(up.x..","..up.y..","..up.z)
Num = #CannonIDs
oneRot = 360/Num for cNo = 0, Num-1 do if Angle < oneRot * cNo or Angle > oneRot * (cNo+1) then --武器取得 --制限角度 wepinfo = I:GetWeaponInfoOnSubConstruct(CannonIDs[cNo+1],WEAPON_SLOT) v = -wepinfo.CurrentDirection I:AimWeaponInDirectionOnSubConstruct(CannonIDs[cNo+1],0,v.x,v.y,v.z,WEAPON_SLOT) end end end
LuaAI系
FAI1.8 BMC HC
空戦用スクリプト(Fighter AI v1.8)をベースに地形追随機能、AIモード排他処理機能を付け足しました。
装飾系
SpotLight首振り
ExtentDegreeで首振る角度を変更、Elevationを任意の値から0.1,0.2ずらすと首振りのON/OFFを切り替えられます。
(Elevation × 10 を3で割った値が2のとき首を振らない。)
function Update(I) --SearchLightMover v2.0 by kuramubon --change this value to limit the spotlight’s movable degree ExtentDegree = 60
lightNum = I:Component_GetCount(12) - 1; for i = 0, lightNum, 1 do --each spotlight nowaz = I:Component_GetFloatLogic_1(12, i, 1); nowel = I:Component_GetFloatLogic_1(12, i, 2); if Mathf.Floor(nowel * 10) % 3 == 0 then if nowaz >= ExtentDegree then I:Component_SetFloatLogic_1(12, i, 2, nowel + 0.1); else I:Component_SetFloatLogic_1(12, i, 1, nowaz + 0.5); end elseif Mathf.Floor(nowel * 10) % 3 == 1 then if nowaz <= -ExtentDegree then I:Component_SetFloatLogic_1(12, i, 2, nowel - 0.1); else I:Component_SetFloatLogic_1(12, i, 1, nowaz - 0.5); end end end end
スピブロとかピストンとか系
サブコントラクトID取得
適当に名前を付けたサブコントラクトのIDをログに表示します。
SB1とかが名前なんで自分でつけた名前に置き換えてください。
SpinBlocks={ {name="SB1"},--サブコントラクトにつけた名前 {name="SB2"}, {name="SB3"}, } function GetSubConstructsID (I,Table) subconst_table = I:GetAllSubConstructs() for index = 1 ,#subconst_table ,1 do id = subconst_table[index] --現在のインデックスのサブコンストラクトIDを取得 name = I:GetSubConstructInfo(id).CustomName --現在のインデックスのサブコンストラクトの名前を取得 for index = 1 ,#Table ,1 do if name == Table[index].name then Table[index].id = id end end end end function Update(I) I:ClearLogs() GetSubConstructsID(I,SpinBlocks) for i=1,#SpinBlocks do I:Log(SpinBlocks[i].name.." "..SpinBlocks[i].id) end end
(ココにコードをコピペすると動くと思います)
end -- 2018-04-07 (土) 17:09:07