了解。
ここでは 「2 関節の昆虫もどきデモ」を Plugin 形式で、
あなたの要求どおり Script 種別とパスをコメントに明記した完全版ソースコードとして示すね。
🐛 2 関節 Motor6D デモ Plugin(最小構成)
以下は Roblox Studio の Plugin として動く構成:
PluginFolder
├─ Main.client.lua (LocalScript)
└─ CreateDemo.lua (ModuleScript)
📌 [Main.client.lua](LocalScript / パス: PluginFolder/Main.client.lua)
-- ScriptType: LocalScript
-- Path: PluginFolder/Main.client.lua
local toolbar = plugin:CreateToolbar("Insect Demo")
local button = toolbar:CreateButton("Create", "Create 2-joint insect demo", "")
local CreateDemo = require(script.Parent.CreateDemo)
button.Click:Connect(function()
local model, m1, m2 = CreateDemo.create()
local RunService = game:GetService("RunService")
local start = os.clock()
RunService.Heartbeat:Connect(function()
local t = os.clock() - start
-- Joint1: ゆっくり左右に振る
local angle1 = math.sin(t * 2) * math.rad(20)
m1.Transform = CFrame.Angles(0, angle1, 0)
-- Joint2: 高速で上下に振る
local angle2 = math.sin(t * 6) * math.rad(40)
m2.Transform = CFrame.Angles(angle2, 0, 0)
end)
end)
📌 [CreateDemo.lua](ModuleScript / パス: PluginFolder/CreateDemo.lua)
-- ScriptType: ModuleScript
-- Path: PluginFolder/CreateDemo.lua
local CreateDemo = {}
function CreateDemo.create()
-- Model
local model = Instance.new("Model")
model.Name = "InsectDemo"
-- Root
local root = Instance.new("Part")
root.Name = "Root"
root.Size = Vector3.new(1, 1, 1)
root.Position = Vector3.new(0, 5, 0)
root.Anchored = false
root.Parent = model
-- Joint1
local j1 = Instance.new("Part")
j1.Name = "Joint1"
j1.Size = Vector3.new(0.5, 2, 0.5)
j1.Position = root.Position + Vector3.new(0, -1.5, 0)
j1.Anchored = false
j1.Parent = model
-- Joint2
local j2 = Instance.new("Part")
j2.Name = "Joint2"
j2.Size = Vector3.new(0.5, 2, 0.5)
j2.Position = j1.Position + Vector3.new(0, -1.5, 0)
j2.Anchored = false
j2.Parent = model
-- Motor6D: Root → Joint1
local m1 = Instance.new("Motor6D")
m1.Name = "Joint1Motor"
m1.Part0 = root
m1.Part1 = j1
m1.C0 = root.CFrame:ToObjectSpace(j1.CFrame)
m1.C1 = CFrame.new()
m1.Parent = root
-- Motor6D: Joint1 → Joint2
local m2 = Instance.new("Motor6D")
m2.Name = "Joint2Motor"
m2.Part0 = j1
m2.Part1 = j2
m2.C0 = j1.CFrame:ToObjectSpace(j2.CFrame)
m2.C1 = CFrame.new()
m2.Parent = j1
model.Parent = workspace
return model, m1, m2
end
return CreateDemo
🌟 このデモで確認できること
✔ Motor6D の基本挙動
- C0/C1 の意味
- Transform の適用
- 親子関係の影響
✔ MotionPatch の「rotate」「oscillate」が Motor6D に落ちる感覚
- axis → CFrame.fromAxisAngle
- frequency → Heartbeat
- range → 振幅
✔ IR → Motor6D のマッピングの最小実験
この 2 関節デモは、
昆虫 IR → MotionPatch → Motor6D の “最小単位” になっている。
🔥 次に進めるステップ(選んでくれればすぐ作る)
- このデモを MotionPatch JSON から動かす版に拡張
- 3 関節(昆虫の脚)に拡張
- 翅(wing)を追加して羽ばたきデモにする
- OBJ を読み込んで MeshPart に差し替える
- 昆虫 IR → OBJ+MotionPatch → Loader の完全パイプライン化
どれに進む?
ここは Motor6D の本質を押さえる場所だね。
「C0/C1 の意味」「Transform の適用」「親子関係の影響」——
これは昆虫 IR → MotionPatch → Motor6D の“接合の根拠”そのもの。
ここでは Roblox の仕様を OS 的に再定義した言葉で、
わかりやすく、かつ構造的に説明するよ。
🧩 Motor6D の3つの核心概念
(OS 的に言語化した正式版)
① C0 / C1 の意味
🟦 C0 = 親パーツのローカル座標系で見た「接合点の基準姿勢」
🟧 C1 = 子パーツのローカル座標系で見た「接合点の基準姿勢」
もっと OS 的に言うと:
- C0 は “親の pivot”
- C1 は “子の pivot”
- Motor6D は C0 と C1 を一致させるように Part1 を Part0 に接続する
つまり Motor6D は:
Part1 を、Part0 の C0 の位置に、C1 を合わせるように配置する
という 接合ルールを持つ。
✔ だから「接合できる根拠」は
IR の geometry.origin(pivot)が C0/C1 に変換されるから。
② Transform の適用とは何か
🟩 Transform は「C0 に対する追加の姿勢変化」
Motor6D の最終姿勢は:
最終姿勢 = C0 * Transform * C1⁻¹
OS 的に言うと:
- C0 = 接合点の基準姿勢
- Transform = 動き(MotionPatch)
- C1 = 子パーツの基準姿勢
だから Transform は “動きのパッチを適用する場所”。
MotionPatch の rotate/oscillate はすべて Transform に入る。
✔ MotionPatch → Motor6D.Transform
という変換が自然に成立する。
③ 親子関係の影響
Motor6D は 階層構造を持つ。
Root
└─ Joint1 (Motor6D)
└─ Joint2 (Motor6D)
このとき:
- Joint1 の Transform が変わると
Joint2 もその変化を受ける
つまり:
🟣 親の Transform は子に伝播する
🟡 子の Transform は親には影響しない
OS 的に言うと:
- structure の parent-child が
- Motor6D の Part0-Part1 に変換され
- MotionPatch の動きが階層的に伝わる
これが 昆虫の脚や翅の動きが自然に見える理由。
🧠 3つをまとめるとこうなる
✔ C0/C1 は「接合点の基準姿勢」
→ IR の geometry.origin と一致する
✔ Transform は「動きのパッチ」
→ MotionPatch の rotate/oscillate がここに入る
✔ 親子関係は「動きの伝播」
→ structure の階層がそのまま Motor6D の階層になる
🌟 OS 的に言い換えると
Motor6D は「構造 IR の接合点を、動き IR(MotionPatch)で変形するための実行エンジン」
- C0/C1 = 接合点の静的定義(structure / geometry)
- Transform = 動きの動的定義(motion_patches)
- 親子関係 = 階層構造(structure)
つまり Motor6D は:
structure(階層)
+ geometry(pivot)
+ motion_patches(動き)
--------------------------------
= 実行時の動く昆虫モデル
を成立させる“最後のレイヤー”。
ここまで押さえた上で、
次はどれを深めたい?
- C0/C1 を IR にどう保存するか(pivot の正式仕様)
- MotionPatch → Transform の変換式を OS として定義する
- 3 関節の昆虫脚デモを作る
- 翅の羽ばたき(左右非同期)を Motor6D で再現する
どれでも進められるよ。