Nature2D - 2D Physics Engine for UI Elements

v0.3.6 - Basic Collision Filtering

Implemented basic collision filtering API for RigidBodies! You can now specify other RigidBodies a body collides with, if not all!

  • Added Collision Filtering to Engine
  • Added new Methods to RigidBodies
    • Engine:FilterCollisionsWith(otherRigidBody: RigidBody)
    • Engine:UnfilterCollisionsWith(otherRigidBody: RigidBody)
    • Engine:GetFilteredRigidBodies()

New documentation example for collision filtering will be updated on the site shortly.

Example:


Updated Roblox Asset & Github

Documentation Updated

Updated Wally Package - 0.3.4 → 0.3.5 → 0.3.6


3 Likes

This is amazing! I got really excited when I saw the 2d boxes getting thrashed all over the place, reminded me of People Playground. This is actually incredible… I have no words.

1 Like

Hey I have been encountering an issue for a while which is where the gui just goes through the ScreenGui and never to be seen again.

It usually occurs when its too far into the screen’s edges. It’s also ocurring with a spring when set the 2nd point too far.

I probably suck at explaining, I have a video demonstrating here.

Here’s the place file Baseplate.rbxl (58.7 KB)

Thanks! :blush:

2 Likes

Thanks for bringing this up, will be fixed soon! I think I know what the issue is, when solving spring constraints, the force must be resulting to NaN or inf.

It’ll be great if you could open an issue at the repo too https://github.com/jaipack17/Nature2D/issues!

1 Like

This should be fixed now. Turns out the problem wasn’t with spring constraints, it was with how I solve Rod Constraints (used in rigidbodies)! When you pulled the RigidBody far off, the actual structure made with rod constraints would stretch so far that a large force would be applied to it resulting in its points’ positions to be NaN, subsequently causing the spring constraint to break too.

Upgraded the wally package to v0.3.7. You can replace the old roblox model with the new one!

If you encounter this again, lmk!

2 Likes

v0.4 - Refactored Object Creation Completely

Major Release.

  • Removed Engine:CreatePoint()
  • Removed Engine:CreateConstraint()
  • Removed Engine:CreateRigidBody()
  • Added Engine:Create(objectName: string, propertyTable: table)

Creating new Constraints, Points and RigidBodies is much simpler than before! You just need to care about 1 single method - Engine:Create(). This method takes in 2 parameters. The first parameter being the type of instance you are creating. This is either “Point”, “Constraint” or “RigidBody”. The second parameter consists of the properties you wish to assign to the object.

Refer to the property table below! Any property which has a * before it is a must to specify when using Engine:Create()! Some properties don’t need to be specified if not needed, these properties will get the default value specified in the global constants!

Intellisense of VSCode and Studio’s script editor will suggest these properties to you!

Property table:

Object Properties
Point * Position: Vector2
Visible: boolean | nil
Snap: boolean | nil

Constraint * Type: string
* Point1: Point
* Point2: Point
Visible: boolean | nil
Thickness: number | nil
RestLength: number | nil

RigidBody * Object: GuiObject
Collidable: boolean | nil
Anchored: boolean | nil

  • Changed how you require Nature2D.
    • Earlier: require(ReplicatedStorage.Nature2D.Engine)
    • Now: require(ReplicatedStorage.Nature2D)
  • Added “Snap” to be a valid property of Point
  • API cleanup
  • Rewrote commented docs in the source code.
  • Fixed Point:Render() - Set point’s anchor point to 0.5, 0.5
  • Fixed Rod Constraints and how I solve them - See issue #8

Updated Roblox Asset & Github

Updated Documentation

Updated Wally Package - 0.3.7 → 0.4.0 → 0.4.1 → 0.4.2



  • Published Patch v0.4.2 - Fix Nature2D for rojo
1 Like

v0.4.3 - New Valid Properties, API Changes and Improvements

  • Changes to RigidBody:SetPosition(), RigidBody:SetSize() and Point:SetPosition()
    • These methods no longer take in a Vector2 value, rather individual x and y values.
    • Example: RigidBody:SetPosition(100, 100), RigidBody:SetSize(20, 40) and Point:SetPosition(500, 0)
  • Improvement how RigidBody lifespans work. They no longer use os.time(). os.clock() is now used thus high precision values for RigidBody lifespans work too!
  • Fixed Point:Render() and Constraint:Render() - Added checks to see if Engine’s canvas has a frame.
  • Added new Valid properties to Engine:Create(). You can now pass in this properties to Engine:Create().
  • New valid properties for Points
    • KeepInCanvas: boolean | nil
    • Color: Color3 | nil
    • Radius: number | nil
  • New valid properties for Constraints
    • SpringConstant: number | nil
    • Color: Color3 | nil
  • New valid properties for RigidBodies
    • LifeSpan: number | nil
    • KeepInCanvas: boolean | nil
    • Gravity: Vector2 | nil
    • Friction: number | nil
    • AirFriction: number | nil

Updated Roblox Asset & Github

Updated Documentation

Updated Wally Packages - 0.4.2 → 0.4.3



(Thank you for 30 stars on github!)

3 Likes

v0.4.4 - Ability to clone RigidBodies

Another improvement to object creation! Added the ability to clone already existing RigidBodies! By default the clone won’t inherit the original RigidBody’s states, lifespan or filtered RigidBodies. In order to copy those too, pass in the deepCopy parameter as true!

  • Added RigidBody:Clone(deepCopy: boolean | nil)

image


Updated Roblox Asset & Github

Updated Documentation

Wally Package Updated - 0.4.3 → 0.4.4


4 Likes

v0.4.5 - Improvements to :ApplyForce(). New events & methods

  • Added new events to Engine
    • Engine.ObjectAdded - Fires when a new Point, Constraint or RigidBody is created.
    • Engine.ObjectRemoved - Fires when a new Point, Constraint or RigidBody is destroyed.
  • Added new methods to RigidBodies
    • RigidBody:GetTouchingRigidBodies() - Returns all RigidBodies that are in collision with the current RigidBody.
  • API Changes to Point:ApplyForce() and RigidBody:ApplyForce()
    • Added a second optional parameter ‘time’.
    • The time parameter can be used to apply a force for a certain amount of time.
    • Example: Body:ApplyForce(Vector2.new(.4, 0), 3) -- applies the force for 3 seconds

Updated Roblox Asset & Github

Updated Documentation

Updated Wally Package - 0.4.4 → 0.4.5


When I used it, it was… PERFECT, it’s better than my GUI collision system which is just 3 lines of code lol.

1 Like

This is amazing! I was thinking of people playground right when I saw the demos. I am def going to make a people playground type sandbox game now.

1 Like

Created some new tutorials for the API that had not be covered in the documentation. New tutorials cover Collision Filtering for RigidBodies, Handling events for both Engine and RigidBodies as well as State Management/Custom Attribute management!

You can find them over at the documentation website under the tutorials category.

Handling Events
Collision Filtering
RigidBody State Management

I have been developing a new feature lately, which is the support of custom rigidbodies like triangles, irregular quadrilaterals and other polygons. This requires you to provide a structure of Rod Constraints and Points to construct a RigidBody on your own.

I have been puzzled about the creation of custom RigidBodies for some time now. Which creation method would be practical and user friendly?

I lay out some methods here:

Let me know what you think! If you have any other ideas, do share.

v0.5 - Custom RigidBody Support!

Major Release.

  • Fixed Engine:CreateCanvas() - Canvas’ can now be re-initialized.
  • Fixed Constraint:Render() - Prevent support constraints from rendering
  • Added support for custom RigidBodies
  • Added new Valid Property for RigidBodies - Structure: table
  • Updated Collision Detection and Response to work with custom RigidBodies
  • Updated Engine:Create()
  • Restrict certain methods from being used for custom RigidBodies

You can now create more than just rectangles and squares. You can now define your own point-constraint structures like triangles, irregular quadrilaterals and n-sided polygons and then turn them into RigidBodies! Here’s how Custom RigidBodies work and how you can create your own!

In the above image, the green dots are the arbitrary points we chose for our RigidBody, if we pass in a UI element, the 4 dots are automatically placed at its corners, also keeping in mind its rotation. There are 6 lines connecting the points all together. The lines in black are the edges of the RigidBody and the lines in red are “support constraints” which are meant to hold the RigidBody’s structure in place and it prevent it from collapsing into nothingness. It is worth noting that support constraints are not used in collision detection. All constraints are rods.

In order to create custom RigidBodies, you don’t need to specify a UI element/Object when using Engine:Create(). You would pass in a property called “Structure”. This contains a table of constraint data. Here’s how a structure looks like for a rectangle:

-- { Point1: Vector2, Point2: Vector2, Support: boolean }

local struct = {
    { Vector2.new(0, 0), Vector2.new(0, 10) },
    { Vector2.new(0, 10), Vector2.new(10, 10) },
    { Vector2.new(10, 10), Vector2.new(10, 0) },
    { Vector2.new(10, 0), Vector2.new(0, 0) },
    { Vector2.new(0, 0), Vector2.new(10, 10), true },
    { Vector2.new(10, 0), Vector2.new(0, 10), true }
}

You just need to provide the positions of the points of the edges and specify if they are support constraints or not! Note that in order to create custom rigidbodies, you must specify a frame for the Engine’s Canvas. You can then use Engine:Create() to turn this structure into a RigidBody. A simple example of a triangle:

local viewport = workspace.CurrentCamera.ViewportSize

local function MakeTriangle(a: Vector2, b: Vector2, c: Vector2)
	return {
		{ a, b, false }, 
        { a, c, false }, 
        { b, c, false }
	}
end

local triangle = Engine:Create("RigidBody", {
	Structure = MakeTriangle(viewport/2, viewport/2 + Vector2.new(-40, 80), viewport/2 + Vector2.new(40, 80)),
	Collidable = true,
	Anchored = false
})

Custom RigidBodies also support Quadtree collision detection! It is worth noting that not all methods will work for custom RigidBodies since the idea is fairly new. I will add the ability to use them in the future! If you try to use these methods, an error will pop up in the output window.


Updated Roblox Asset & Github

Updated Documentation

Updated Wally Package - 0.4.5 → 0.5.0


cc: @uhi_o

3 Likes

A little demonstration of the same. Custom RigidBodies will remain hollow and I don’t intend to make them have color inside. You are free to script triangulation to fill them :slight_smile:

4 Likes

Is it possible for soft bodies to be added?

With the recent addition of Custom RigidBodies, soft bodies are already possible to make! It requires a bit more work on your hand though. You can do that by combining different RigidBodies structures together to form a softbody. Even connecting multiple RigidBodies with Spring/Rod constraints will do it for you. Glad you brought this up, I’ll try to use my methods to make a softbody tomorrow and share the results with you!

And it’s done! I made a point-constraint structure in a grid like manner and here we have a Softbody!

It may collapse on low frame rates though. And collision detection isn’t the best with this sort of structure :(. Thus, try making softbodies that are smaller in size!

3 Likes

Thats really cool! Thanks! Im gonna try this out

1 Like

I’ve tried implementing character movement and I think I did it kind of? I got a frame that moves based on the user’s input by using ApplyForce not sure if this is the intended purpose of it though. I also couldn’t figure out how to keep the rigid body still it was very bouncy and kept turning around not sure if this is possible to fix though.

1 Like