Hey @Bjarnos !!
That’s so funny that the support plugins system in the editor popped multiple times this week. I’m releasing a new version tomorrow. After it’s released, I’ll actively finish the support for plugins so you’ll be able to plug everywhere in the editor and you’ll be able to use UI components.
Following the link you shared for the existing Quixel plugin, it has been moved to the official Babylon.js Editor repository here: Editor/quixel at master · BabylonJS/Editor · GitHub which is now compatible with the version 5. You can browse the sources for instance in order to prepare your plugin until I released an official documentation. The entry point is here: Editor/quixel/src/index.ts at master · BabylonJS/Editor · GitHub (main and close functions are called by the editor, the rest deserves the plugin)
I also plan to support Fab.com as a plugin to directly import assets from Fab libraries.
My plan is called “babyLua” (definitely need to work on that name), Lua language support for one of the biggest engines natively in browser environment JavaScript. I already have it working with a decent translation layer, but it would be fun to add as a plugin because I could make extra features to it (e.g. precompiling code within export).
Example code that already works (Editor format with classes or functions isn’t supported yet):
local scene = Scene.new(engine) -- the engine is initialized in TS and injected as global
local ground = Mesh.CreateGround("ground", 100, 100, 2, scene)
local groundMat = StandardMaterial.new("groundMat", scene)
groundMat.diffuseTexture = Texture.new("https://assets.babylonjs.com/environments/valleygrass.png", scene)
groundMat.specularColor = Color3.new(0, 0, 0)
ground.material = groundMat
local body = MeshBuilder.CreateCapsule("player", { height = 2, radius = 0.5 }, scene)
body.position.y = 1
local bodyMat = StandardMaterial.new("bodyMat", scene)
bodyMat.diffuseColor = Color3.new(0.2, 0.2, 0.9)
body.material = bodyMat
local cam = FollowCamera.new("cam", Vector3.new(0, 6, -12), scene)
cam.lockedTarget = body
cam.radius = 12
cam.heightOffset = 3
cam.rotationOffset = 180
cam.cameraAcceleration = 0.05
cam.maxCameraSpeed = 10
cam.lowerRadiusLimit = 5
cam.upperRadiusLimit = 20
cam.attachControl()
local light = HemisphericLight.new("light", Vector3.new(0, 1, 0), scene)
light.intensity = 0.9
scene.clearColor = Color4.new(0.7, 0.82, 0.95)
local input = {}
scene.actionManager = ActionManager.new(scene)
scene.actionManager.registerAction(ExecuteCodeAction.new(ActionManager.OnKeyDownTrigger, function(e) input[e.sourceEvent.key:lower()] = true end))
scene.actionManager.registerAction(ExecuteCodeAction.new(ActionManager.OnKeyUpTrigger, function(e) input[e.sourceEvent.key:lower()] = false end))
scene.actionManager.registerAction(ExecuteCodeAction.new(ActionManager.OnKeyDownTrigger, function(e)
if (e.sourceEvent.key == "ArrowUp") then input["w"] = true end
if (e.sourceEvent.key == "ArrowDown") then input["s"] = true end
if (e.sourceEvent.key == "ArrowLeft") then input["a"] = true end
if (e.sourceEvent.key == "ArrowRight") then input["d"] = true end
if (e.sourceEvent.key == " ") then input["space"] = true end
end))
scene.actionManager.registerAction(ExecuteCodeAction.new(ActionManager.OnKeyUpTrigger, function(e)
if (e.sourceEvent.key == "ArrowUp") then input["w"] = false end
if (e.sourceEvent.key == "ArrowDown") then input["s"] = false end
if (e.sourceEvent.key == "ArrowLeft") then input["a"] = false end
if (e.sourceEvent.key == "ArrowRight") then input["d"] = false end
if (e.sourceEvent.key == " ") then input["space"] = false end
end))
local moveSpeed = 3
local jumpVelocity = 0
engine.runRenderLoop(function()
local dt = engine.getDeltaTime() / 1000
local grounded = body.position.y <= 1
if (not grounded) then jumpVelocity = jumpVelocity - 9.8 * dt end
if (input["space"] and grounded) then jumpVelocity = 5 end
local forward = cam.getFrontPosition(1).subtract(cam.position).normalize()
local right = Vector3.Cross(forward, Axis.Y).normalize().negate()
if (input["w"]) then body.position.addInPlace(forward.scale(moveSpeed * dt)) end
if (input["s"]) then body.position.addInPlace(forward.scale(-moveSpeed * dt)) end
if (input["a"]) then body.position.addInPlace(right.scale(-moveSpeed * dt)) end
if (input["d"]) then body.position.addInPlace(right.scale(moveSpeed * dt)) end
body.position.y = body.position.y + jumpVelocity * dt
if (body.position.y < 1) then
body.position.y = 1
jumpVelocity = 0
end
scene.render()
end)
I’ve cloned the quixel plugin and successfully built it using yarn. I can now begin on my own plugin but there’s a small annoying problem, every time I try to remove my plugin and add it again the built-in cache of require activates. Editor’s source code:
I’ve tried to remove this cache using various method, including erasing it entirely (Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })), but the entire cache keeps on coming back. I suspect there’s some library or bundler handling it but I’m not sure. Any insights are appreciated
Edit 2: I’ve managed live reload by watching the plugin’s directory. Still, native support (e.g. a reload button or file watch for live reload) would be cool;
const path = require("path");
const pluginRoot = path.resolve("/home/bjarnos/Downloads/Editor-master/babyLua");
const buildFile = path.join(pluginRoot, "build", "build-id.js");
fs.watch(buildFile, (eventType: any) => {
console.log("New version detected in build");
setTimeout(() => {
for (const key of Object.keys(require.cache)) {
if (key.startsWith(pluginRoot)) {
delete require.cache[key];
}
}
try {
require(join(pluginRoot, "package.json"));
const result = require(pluginRoot);
console.log("Loaded new module!");
result.main(editor);
close();
} catch (err) {
console.error("Error reloading plugin:", err);
}
}, 1000);
});
That’s so awesome !!! I started development when I discovered lua on PSP many years ago, you’ll have the best plugins support ever ahah
I created and started an issue that you can track in case you’de like to follow the progress: Plugins system · Issue #748 · BabylonJS/Editor · GitHub
I plan to finish the plugins system for the next release. Let’s say something like 2 weeks?
Oh wow, you must’ve read my mind because I was just about to ask you when you’d think the plugins system would be done. Thanks for the positive vibes and you’ll see me around with my project
Oh wow, looks like somebody visited my website.
No, I am not the creator of Rumble Rush, but I was the old maintainer of the wiki until the game went in a half-dead state, because of too few updates. I have made many projects (including games) in multiple languages before but I removed them all from my website since I’m not for hire anymore and all my projects are personal now
I actually took a stab at making one…I basically load a mini overlay and then export things to a database that the main engine uses (also babylon).
My setup is I have a base scene with assets loaded and then add scripts to items to decorate extra metadata, then have buttons in a popout window to save/load levels.
One thing I’m bumping into is that my game assumes all units are meters (it’s a webxr game) and I can’t figure out how to do the math to get things in the correct units. I may play with “zoom level” in the preview window.
Anyone else using the editor for VR/Webxr scenes? I know, by definition, the units are arbitrary, but when you’re trying to view/play in a headset “units matter”…
If anyone wants to actually use it, I can walk you through the setup. Very Alpha mode right now, but if you want examples of how to hook into the editor and save “somewhere else” this should give you an idea on how to handle it.