ここは PlayerArea を Model 化したからこそ実現できる “ローカル座標 API” を、OS レイヤーとしてきれいに定義しておくと後々すごく効いてきます。
Studio OS → Client OS → Server OS のどこでも同じ API で扱えるように、PlayerArea 自体にメソッドを生やす形で設計するのが最も美しい。
以下は 完全に自立した PlayerArea 空間 API。
あなたの「OS の物理ページ」思想に合わせて、worldToLocal / localToWorld を OS レイヤーとして提供する。
🧭 PlayerArea LocalSpace API(OS 層)
PlayerArea は Model で、PrimaryPart(Origin)を持つ。
この Origin を「ページの base address」として扱う。
🧱 API の全体像
PlayerArea:WorldToLocal(worldPos) → Vector3
PlayerArea:LocalToWorld(localPos) → Vector3
PlayerArea:WorldCFrameToLocal(worldCf) → CFrame
PlayerArea:LocalCFrameToWorld(localCf) → CFrame
これだけで PlayerArea 内のすべての座標変換が OS 的に統一される。
🧩 実装:PlayerArea にメソッドを生やす
ModuleScript ではなく、Model にメタテーブルを付与する方式が最も自然。
(あなたの OS 設計では「PlayerArea はオブジェクトであり OS のページ」なので、オブジェクト指向が合う)
📦 PlayerAreaLocalSpace.lua(ModuleScript)
local LocalSpace = {}
-- PlayerArea にメソッドを付与する
function LocalSpace.Attach(area)
assert(area.PrimaryPart, "PlayerArea must have a PrimaryPart (Origin)")
-- world → local
function area:WorldToLocal(worldPos)
return self.PrimaryPart.CFrame:PointToObjectSpace(worldPos)
end
-- local → world
function area:LocalToWorld(localPos)
return self.PrimaryPart.CFrame:PointToWorldSpace(localPos)
end
-- world CFrame → local CFrame
function area:WorldCFrameToLocal(worldCf)
return self.PrimaryPart.CFrame:ToObjectSpace(worldCf)
end
-- local CFrame → world CFrame
function area:LocalCFrameToWorld(localCf)
return self.PrimaryPart.CFrame:ToWorldSpace(localCf)
end
return area
end
return LocalSpace
🏗️ PlayerArea 生成時に Attach する
local LocalSpace = require(path.to.PlayerAreaLocalSpace)
local function createPlayerArea(player, offset)
local area = Instance.new("Model")
area.Name = tostring(player.UserId)
area.Parent = workspace.PlayerAreas
-- 原点
local origin = Instance.new("Part")
origin.Name = "Origin"
origin.Size = Vector3.new(4,1,4)
origin.Anchored = true
origin.Position = offset
origin.Parent = area
area.PrimaryPart = origin
-- サブフォルダ
for _, name in ipairs({"Work", "Temp", "UIObjects"}) do
local folder = Instance.new("Folder")
folder.Name = name
folder.Parent = area
end
-- ローカル座標 API を付与
LocalSpace.Attach(area)
return area
end
🧪 使用例(Spider-beam / InteriorOS で即使える)
world → local
local localPos = area:WorldToLocal(hit.Position)
local → world
local worldPos = area:LocalToWorld(Vector3.new(0, 10, 0))
world CFrame → local CFrame
local localCf = area:WorldCFrameToLocal(part.CFrame)
local CFrame → world CFrame
local worldCf = area:LocalCFrameToWorld(CFrame.new(0, 5, 0))
🧠 あなたの OS 設計との整合性
| PlayerArea | OS 概念 |
|---|---|
| Model | 物理ページ |
| PrimaryPart | base address |
| WorldToLocal | 仮想アドレス → 物理アドレス |
| LocalToWorld | 物理アドレス → 仮想アドレス |
| Attach() | ページに OS API をロード |
完全に OS のページングモデルと一致している。
🌱 次に進める方向
- PlayerArea 内で Spider-beam のアンカーをローカル座標で管理
- InteriorOS の「部屋」を PlayerArea 内のローカル空間に配置
- PlayerArea の「ページ番号」管理(Allocator と統合)
- PlayerArea の GC(PlayerRemoving 時の安全な解放)
次はどの OS レイヤーを強化したい?