Currently, in my roblox real time strategy game in development, I am trying to achieve a system in which players can control units that move across the surface of a globe. The globe will represent a planet, and players should be able to interact with and navigate their units seamlessly across its surface. However, I’m facing some challenges in terms of how to approach the technical aspects of implementing this system effectively.
- How would I make units move in a set speed on the entire time they are moving thru the surface of the sphere,
- Can the units height be always around the sphere relative to the cere
- Is it possible to keep it optimized and not have millions of calculations a second,
- Or even, what are the neccesary mathematical calculations to account in the proccess?
Here is a script that receives the local input of the player with its selected units so the units sent are moved to the desired location, the ‘hitpos’. It uses methods such as linear velocity which I believe wouldnt really work on a sphere if they werent to be set constantly.
-- Dictionary to store active movement loop connections for each unit
local moveLoops = {}
-- Connect to the event triggered when movement needs to be halted
game.ReplicatedStorage.HaltMovement.OnServerEvent:Connect(function(player, unit)
if unit and unit.Parent then
unit:SetAttribute('uHalting', true) -- Set the attribute to indicate that movement should halt
end
end)
-- Connect to the event triggered when a unit needs to be moved
game.ReplicatedStorage.MoveUnit.OnServerEvent:Connect(function(player, hitpos, unit)
-- Disconnect any existing movement loop for this unit, if it exists
if moveLoops[unit] then
moveLoops[unit]:Disconnect()
end
unit:SetAttribute('uHalting', false) -- Reset the attribute to allow movement
-- Calculate and set the new velocity for the unit based on the hit position and speed attribute
unit.PrimaryPart.Vel.PlaneVelocity = Vector2.new(hitpos.X - unit.PrimaryPart.Position.X, hitpos.Z - unit.PrimaryPart.Position.Z).Unit * unit:GetAttribute('Speed')
game.ReplicatedStorage.CreateBeam:FireClient(player, hitpos, unit, false) -- Inform client to create a beam effect
-- Create a new movement loop for the unit
moveLoops[unit] = game:GetService("RunService").Heartbeat:Connect(function()
local distanceToHitPos = (unit.PrimaryPart.Position - Vector3.new(hitpos.X, unit.PrimaryPart.Position.Y, hitpos.Z)).Magnitude
-- Check if the unit should keep moving or if it's close enough to the hit position
if distanceToHitPos > 1 and not unit:GetAttribute('uHalting') then
unit:SetAttribute('uRepeating', true) -- Set attribute to indicate repeating movement
-- Update the velocity for continued movement towards the hit position
unit.PrimaryPart.Vel.PlaneVelocity = Vector2.new(hitpos.X - unit.PrimaryPart.Position.X, hitpos.Z - unit.PrimaryPart.Position.Z).Unit * unit:GetAttribute('Speed')
else
unit:SetAttribute('uRepeating', false) -- Reset attribute indicating repeating movement
unit.PrimaryPart.Vel.PlaneVelocity = Vector2.new(0, 0) -- Stop horizontal movement
game.ReplicatedStorage.CreateBeam:FireClient(player, hitpos, unit, true) -- Inform client to create a beam effect
if unit:GetAttribute('uHalting') then
unit:SetAttribute('uHalting', false) -- Reset halting attribute if movement was halted
else
game.ReplicatedStorage.CreateBeam:FireClient(player, hitpos, unit, true) -- Inform client to create a beam effect
end
moveLoops[unit]:Disconnect() -- Disconnect the movement loop since movement is complete
moveLoops[unit] = nil -- Remove the reference to the disconnected loop
end
end)
end)
Here is a example if anything to clarify what I am seeking. (a really bad example)
I know it is a very hard question and I understand it might not even be achievable, however, if anyone with the understand could spread its knowledge, it would be greatly appreciated.