Nature2D - 2D Physics Engine for UI Elements

Sure, I’ll clean up the code and make it uncopylocked soon

1 Like

You should add a swept physics mode or a constant frame rate mode to get rid of some of the inconsistencies when objects collide (pushing into each other etc) however this late into the engines development might make it a real pain to get working

1 Like

alright, thanks.
image

I’m getting an error when making any type of constraint:
image

local engine = require(game:GetService("ReplicatedStorage"):FindFirstChild("Nature2D"))
local GAME = script.Parent
local Scenes = GAME.Scenes
local GameScene = Scenes.GAME
local Plugins = require(game:GetService("ReplicatedStorage"):FindFirstChild("Nature2D"):FindFirstChild("Plugins"))
local Categories = GameScene.ITEM_UI.Categories
local Items = GameScene.ITEMS

local physics = engine.init(GAME)
local Dragger = Plugins.MouseConstraint(physics,10)
local Canvas = physics:CreateCanvas(Vector2.new(0,0),workspace.CurrentCamera.ViewportSize, GameScene)



local ground = physics:Create("RigidBody",{
	Object = GameScene.GROUND,
	Collidable = true,
	Anchored = true
})

local Box = physics:Create("RigidBody",{
	Object = GameScene.Cube,
	Collidable = true,
	Anchored = false
})

--Initialize Categories--


--Ragdolls
local Ragdolls_Category = Items.Ragdolls
local Ragdoll_Names = {"Default"}

for index,item in pairs(Ragdoll_Names) do
	local ragdoll = Ragdolls_Category:FindFirstChild(item)
	if ragdoll then
		local head_visual = ragdoll:FindFirstChild("Head")
		local root_part_visual = ragdoll:FindFirstChild("RootPart")
		
		local head = physics:Create("RigidBody",{
			Object = head_visual,
			Collidable = true,
			Anchored = false
		})
		
		local root_part = physics:Create("RigidBody",{
			Object = root_part_visual,
			Collidable = true,
			Anchored = false
		})

		
		local head_root_constraint = physics:Create("Constraint",{
			Type = "Rod",
			Point1 = head:GetVertices()[3],
			Point2 = root_part:GetVertices()[1],
			Visible = true,
			Thickness = 3,
			Color = Color3.new(1,1,1)
		})
	end
end

physics:Start()

This area:

local head_root_constraint = physics:Create("Constraint",{
			Type = "Rod",
			Point1 = head:GetVertices()[3],
			Point2 = root_part:GetVertices()[1],
			Visible = true,
			Thickness = 3,
			Color = Color3.new(1,1,1)
		})

I don’t see any problems in your code, can you show the full error?

all my braincells are focused AND I UNDERSTOOD (!!), I will now begin the development of a collection of arcade games adapted to Roblox thanks to your plugin! I look forward to the next update !!
( and to some of the patches too )

check out the website btw… helps a lot

Wrote a blog on a Nature2D project I had been working on last week. Trusses with Nature2D! Check it out here on my website: jaipack17.github.io/voyage/trusses



6 Likes

Dang that’s almost like PolyBridge, but 2D really like the hydraulic thing… you just used a tween size right? i especially like how the engine will do the trick in this case !

How to Keep the velocity after collision

Dear jaipack17 or Roblox User,

Of the many methods you scripted, the one I like the most is RigidBody:ApplyForce(). However, I’ve been stumbling upon a problem recently. While trying to calculate the new velocity after collision seems nice in theory it seems the force is reset due to the CollisionResponse defined in the Runner file. Even after removing the Friction, the air friction and the Gravity, the forces applied to the RigidBody seem to simply disappear.

Is there a way to Add up the Forces? or a calculation which would work in my case?

PS: I experimented with a ball colliding and accelerating in an empty box

kinda reminds me of David Baszucki’s interactive physics

1 Like

Whenever I try to create stuff I keep getting this error:

ReplicatedStorage.EngineClient.Packages.Nature2D.Physics.RigidBody:315: attempt to index nil with 'Dot' 

Game Physics Manager:

-- // Engine

local CanaryEngine = require(game:GetService("ReplicatedStorage"):WaitForChild("CanaryEngineFramework").CanaryEngine)
local EngineClient = CanaryEngine.GetEngineClient()

local Packages = EngineClient.Packages
local Media = EngineClient.Media

-- // Constants

local GameGui = EngineClient.PlayerGui:WaitForChild("Game")

local Nature2D = require(Packages.Client.Nature2D)
local Engine = Nature2D.init(GameGui)

-- // Variables

-- // Functions

local function myFunction()
	print("Hello, function!")
end

-- // Connections

-- // Actions

for index, value in GameGui:GetChildren() do
	for _, ground in value.GameViewport:GetChildren() do
		if ground.Name == "Ground" then
			Engine:Create("RigidBody", {
				Object = ground,
				Collidable = true,
				Anchored = true
			})
		end
	end
	
	for _, box in value.GameViewport.Boxes:GetChildren() do
		Engine:Create("RigidBody", {
			Object = box,
			Collidable = true,
			Anchored = false
		})
	end
end

Engine:Start()
1 Like

The same thing happens to me… I haven’t found any solutions yet

Getting the same issue. Did you find anything?

(I’ve noticed that my Anchored false gui’s position is getting set to math.huge somewhere.)

Everything seems to be working fine since I added an engine:CreateCanvas() call.

Please somebody help me make this code allow jumping with enum code w

--player vars

local player = game.Players.LocalPlayer
local Mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local viewport = camera.ViewportSize

local World = script.Parent
local Canvas = World.Canvas

local Elements = Canvas.Elements

local ReplicatedStorage = game:GetService('ReplicatedStorage')
local UserInputService = game:GetService("UserInputService")

local Modules = ReplicatedStorage:FindFirstChild('Modules')

local Nature2d = require(Modules:WaitForChild("Nature2D"))

--main
local keys = {
	W = false,
	A = false,
	S = false,
	D = false,
	Space = false
}

local engine = Nature2d.init(World)

local player_element = engine:Create("RigidBody",{


	Object = Elements.Player,
	Collidable = true,
	Anchored = false

})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform1,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform2,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform3,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform4,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Platform5,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.Button,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.End,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.KillPart,
	Collidable = true,
	Anchored = true
	
})

local platform_element = engine:Create("RigidBody",{


	Object = Elements.box,
	Collidable = true,
	Anchored = false

})

local function respawn()

	player_element:SetPosition(viewport.X/2, viewport.Y/2)

end

UserInputService.InputBegan:Connect(function(input, isTyping)

	if isTyping then return end

	if input.KeyCode == Enum.KeyCode.D and not keys.D then

		keys.D = true

		repeat
			wait()
			player_element:ApplyForce(Vector2.new(1,0))
		until keys.D == false

	elseif input.KeyCode == Enum.KeyCode.A then

		keys.A = true

		repeat
			wait()
			player_element:ApplyForce(Vector2.new(-1,0))
		until keys.A == false
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.D then

		if keys.D then
			keys.D = false
		end
	elseif input.KeyCode == Enum.KeyCode.A then

		if keys.A then
			keys.A = false
		end
	end
end)

player_element.CanvasEdgeTouched:Connect(function(side)
	if side == "Bottom" then
		respawn()
	end
end)

engine:Start()
2 Likes

@2jammers @Neuroticxs @blowup999 here is an older version of the module, if that helps.
Nature2D.rbxm (29.4 KB)

1 Like

Hey, is there a way to use this with SurfaceGuis instead? All the other 2D engines for UIs don’t seem to work and I would like to use this to create PONG!.

I assume all gui instances inherit from the same baseclass, so they should all work?
If not, you can make it a 2D window also unsure why a Pong game needs 2D physics…

1 Like

You’re technically right on that but Nature2D uses the player’s camera viewport for doing operations with a Rigid Body’s properties (size, position, etc, in Vector2) which is why this doesn’t work for SurfaceGuis and I can’t seem to figure out a way to make this work with so.

Not sure what you mean by that, I want the PONG! game to be shown on a TV controllable by 2 players that can be shown to everyone using replication services.

Air friction, ball velocity and Rigid Body hit detection. Nothing more to say I guess.

This’s pretty good module, which can help 2D games. But is it possible to use Scale properties of objects instead of offsets and AbsoluteSize/Positions?

2 Likes

There’s one bug with constraints. If both points will be in the same place, force will be calculated as NaN, NaN, bc of Vector2(0, 0).Unit (Rod, Spring).

2 Likes