Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

A question for anyone who develops on Unity and Roblox: How is this code?

Asked by 4 years ago

I watched a youtube video on some gravity simulation, and they let you see the source code, so I had this idea to recreate it in Roblox, but it was created with C# in Unity. Now I was sort of able to figure out what the code does but I wasn't sure so I did a few google searches if I didn't understand something. Now the thing is SOMETHING isn't right with it because the planets just follow each other and speed up over time until you experience floating-point precision errors, so I want to know, how good is my code? Here's the source: https://github.com/SebLague/Solar-System/tree/Episode_01/Assets/Scripts/Planets Here's my code: (I didn't do gravity object because it appeared to do nothing) Universe: (ModuleScript)

local Universe = {
    gravitationalConstant = 0.0001;
    physicsTimeStep = 0.01;
};

Universe.updateProperties = function(G, T)
    Universe.gravitationalConstant = G
    Universe.physicsTimeStep = T
end

return Universe

CelestialBody: (ModuleScript)

local Universe = require(script.Parent.Universe)
_G.CelestialBody = {}

newCelestialBody = function()
    local this = {}

    this.radius = 0
    this.surfaceGravity = 0
    this.initialVelocity = Vector3.new(0, 0, 0)
    this.bodyName = "Unnamed"

    this.velocity = Vector3.new(0, 0, 0)
    this.mass = 0
    this.rb = game.ServerStorage.MeshPart:Clone()
    this.rb.Parent = workspace
    local mv = Instance.new("IntValue", this.rb)
    mv.Name = "mass"

    this.Awake = function()
        this.rb.mass.Value = this.mass
        velocity = this.initialVelocity
    end

    this.UpdateVelocity = function(allBodies, timeStep)
        for i,otherBody in pairs(allBodies) do
            if otherBody ~= this then
                local sqrDst = (otherBody.rb.Position - this.rb.Position).Magnitude
                local forceDir = (otherBody.rb.Position - this.rb.Position).Unit
                local acceleration = forceDir * Universe.gravitationalConstant * otherBody.mass / sqrDst
                velocity += acceleration * timeStep
            end
        end
    end

    this.UpdateVelocity = function(acceleration, timeStep)
        velocity += acceleration * timeStep
    end

    this.UpdatePosition = function(timeStep)
        this.rb.Position += (velocity * timeStep)
    end

    this.OnValidate = function()
        this.mass = this.surfaceGravity * this.radius * this.radius / Universe.gravitationalConstant
        this.rb.Size = Vector3.new(1, 1, 1)* this.radius
        this.rb.Name = this.bodyName
    end

    this.rb.Changed:Connect(this.OnValidate)

    this.RigidBody = function()
        return this.rb
    end

    this.Position = function()
        return this.rb.Position
    end
    table.insert(_G.CelestialBody, this)
    return this
end

return newCelestialBody

NBodySimulation: (ModuleScript)

local Universe = require(script.Parent.Universe)
local Time = {fixedDeltaTime = 0}

function newNBodySimulation()
    local this = {}
    this.bodies = _G.CelestialBody
    this.NBodySimulation = Instance.new("Folder", workspace)

    this.Awake = function()
        this.bodies = _G.CelestialBody
        Time.fixedDeltaTime = Universe.physicsTimeStep
        print("Setting fixedDeltaTime to: "..Universe.physicsTimeStep)
    end

    this.FixedUpdate = function()
        for i = 1, #this.bodies do
            local acceleration = this.CalculateAcceleration(this.bodies[i].Position(), this.bodies[i])
            this.bodies[i].UpdateVelocity(acceleration, Universe.physicsTimeStep)
        end

        for i = 1, #this.bodies do
            this.bodies[i].UpdatePosition(Universe.physicsTimeStep)
        end 
    end

    this.CalculateAcceleration = function(point, ignoreBody)
        local acceleration = Vector3.new(0, 0, 0)
        for i,body in pairs(this.bodies) do
            if body ~= ignoreBody then
                local sqrDst = (body.Position() - point).Magnitude
                local forceDir = (body.Position() - point).Unit
                acceleration += forceDir * Universe.gravitationalConstant * body.mass / sqrDst
                print(acceleration)
            end
        end
        return acceleration
    end

    this.Bodies = function()
        return this.bodies
    end

    this.NBodySimulation = function(instance) 
        if instance == nil then
            instance = this.NBodySimulation
        end
        return instance
    end
    return this
end

return newNBodySimulation

Heres an example script to demonstrate usage:

local CelestialBody = require(script.Parent.CelestialBody)
local NBodySimulation = require(script.Parent.NBodySimulation)
local planet = CelestialBody()
planet.radius = 2.5
planet.surfaceGravity = 10
planet.bodyName = "New planet"
planet.initialVelocity = Vector3.new(0, 0, 0)
planet.OnValidate()
planet.Awake()
local sim = NBodySimulation()
sim.Awake()

wait(10)

while true do
    sim.FixedUpdate()
    wait()
end
0
The scope of this questions really is way too large. We don't have all the details, and seeing as this is translated code from an OOP language to a scripting language, how are we to know if the problem resides in the source's code that you translated it from or with your translated code, or just that roblox's engine can't handle what you are trying to do. SteamG00B 1633 — 4y
0
Instead of asking "How is this code", try to figure out the problem for yourself, and then come back with a few more specific questions. SteamG00B 1633 — 4y
0
It's not the source code, it works just fine in the game. testing34545 12 — 4y
0
The Unity game, I mean. testing34545 12 — 4y

Answer this question