Cube Rotation Game

Hey guys. I am trying to make a randomly rotating cube as part of a minigame. Right now, the cube rotates, but the player does not “stick” to the cube. If a player stands still, the cube just rotates under them and doesn’t actually move them. I’ve looked for an answer to this online, but haven’t found one. Cube Simulator pulled it off successfully back in 2014, and there’s also a popular Rotating Cube game that exists today. I’ll link the code below. Any help would be appreciated!

local TweenService = game:GetService("TweenService")

local timeToRotate = NumberRange.new(14,15)
local rotateRange = NumberRange.new(-180,180)
local tweenStyle = Enum.EasingStyle.Linear

local Model = script.Parent
local CFrameValue = Instance.new("CFrameValue") 

CFrameValue.Value = script.Parent:GetPrimaryPartCFrame()

CFrameValue.Changed:Connect(function()
	Model:SetPrimaryPartCFrame(CFrameValue.Value)
end)

while true do
	local info = TweenInfo.new(math.random(timeToRotate.Min,timeToRotate.Max),tweenStyle)
	local goal = {Value = Model:GetPrimaryPartCFrame()*CFrame.Angles(
		math.rad(math.random(rotateRange.Min,rotateRange.Max)),
		math.rad(math.random(rotateRange.Min,rotateRange.Max)),
		math.rad(math.random(rotateRange.Min,rotateRange.Max))
		)}
	
	local Tween = TweenService:Create(CFrameValue,info,goal)
	Tween:Play()
	Tween.Completed:Wait()
end

If I understand correctly, you should use AngularVelocity, which will “stick” the players on as you rotate
Here is a simple example
rotate.rbxl (36.2 KB)
Hopefully this helps!

Thank you for the response! I’m not very familiar with AngularVelocity, but I noticed that it only works when the part is unanchored. Do you know if AngularVelocity would work while using CFrame and TweenService to rotate the cube?

This might be a bit of a “Hacky” solution so it’s probably not the best way to to it but I think it’s worth bringing up.

You could have an anchored part somewhere above the cube thats invisible and weld the cube to that invisible part and unanchor the cube.

I’m not entirely sure if it will work, nor is it probably the best solution but it’s worth a shot.

You could probably get AngularVelocity to work with CFrame and TweenService but you would have to calculate the given angular velocity and set the AngularVelocity (this is how the simple conveyor belts work – an anchored block with a set velocity) but another method is to imitate anchoring with a LinearVelocity and AngularVelocity both with high MaxForce/MaxTorque so they effectively can’t be moved (and gravity wouldn’t impact it either) but you’d still be able to set AngularVelocity

Thanks a ton for the reply. I’ve been messing around with the place that you linked and I’m having a really hard time trying to figure out how AngularVelocity is going to be able to make a randomly rotating cube that I can set the speed for. I can only figure out how to rotate the part on one axis, and even then it speeds up fast and throws me off after a while. For reference, here’s how the current cube looks (the gray cube right under spawn): Crazy Cubes - Roblox
I think it looks pretty good, but the only problem with it is that it slides under you. I’m trying to get it rotating like this game (you’ll notice how it rotates you with the cube): [NEW!!] STAY ON THE CUBE! - Roblox
I’m not sure if I’m just not understanding this whole AngularVelocity thing (I’m very new to scripting and developing), but I’m having trouble configuring it to make the cube spin randomly.

It started to stay up by itself without being anchored or welded (still not sure how). Thanks for the suggestion though! Edit: Like yes35go just said, it’s the LinearVelocity combined with the AngularVelocity that makes the part anchored.

1 Like

You could unanchor the part, then on a Heartbeat loop set the LinearVelocity to Vector3.new(0, 0, 0). This way it will keep the part still.

For using CFrame/TweenService, you’re going to have to ditch CFrame and TweenService and move directly to AngularVelocity. You could use TweenService for AngularVelocity, but what I would do instead is constantly set the AngularVelocity every Heartbeat using Perlin noise.

I’ve been playing around with AngularVelocity and just got it to spin. I’ll update more in a bit.

By the way, to create a “noisy” number, use math.noise.

Why not just weld the players HumanoidRootPart to the cube? If I’m correct, welds make the orientation of Part0 as Part1s.

He wants the character to not be pinned to the cube, but able to freely walk around. I’m assuming by the game he has linked, that he wants the player to attempt to use their movement method to not fall off the cube as it’s rotating.

Yes, this right here. The AngularVelocity and LinearVelocity route seems to be working well so far. You mentioned a heartbeat loop a few minutes ago. Not too sure what that fully is, but should I replace the while wait loop with it?

Yes.

local RunService = game:GetService("RunService")

RunService.Heartbeat:Connect(function(deltaTime)
	-- do stuff
end)

Although Heartbeat fires after physics step, so I would use RunService.Stepped instead.

You can also just replace the wait() with RunService.Stepped:Wait() inside your while loop.

Thanks for the help! How does this look? Also, I have the Torque and Force on Linear and Angular Velocity set to inf in the properties. Do you think I should leave it at inf, or change it to something like 1,000,000?

local Velocity = script.Parent.AngularVelocity
local Linear = script.Parent.LinearVelocity
local RunService = game:GetService("RunService")

while RunService.Stepped:Wait(5) do
	Velocity.AngularVelocity = Vector3.new(
		math.random(-30,30)/100,math.random(-30,30)/100,math.random(-30,30)/100)
		Linear.LinearVelocity = Vector3.new(0, 0, 0)
end

Using :Wait() on an RBXScriptSignal (such as RunService.Stepped) does not work as waiting a certain duration when a number is inserted in the first argument. This is why I suggest using math.noise. However, your method here works perfectly find for random linear angular rotation, so just simply use this:

local Part = script.Parent
local RunService = game:GetService("RunService")
RunService.Stepped:Connect(function()
	Part.LinearVelocity = Vector3.new(0, 0, 0)
end)

while task.wait(5) do
	Part.AngularVelocity = Vector3.new(math.random(-30,30)/100, math.random(-30,30)/100, math.random(-30,30)/100)
end

Thanks again for all the help. However, I’m getting an error that says: LinearVelocity is not a valid member of Workspace “Workspace” - Server.

I have a LinearVelocity in Part that is set to VectorVelocity (0,0,0), so I’m not sure why I’m getting this error. Edit: Just realized it was also an error in the code I posted before, but with that code the cube still spun.

I’m assuming the script should go inside a part instance not the ‘Workspace’ contrainer itself.

local Part = script.Parent
local RunService = game:GetService("RunService")
RunService.Stepped:Connect(function()
	Part.LinearVelocity.VectorVelocity = Vector3.new(0, 0, 0)
end)

while task.wait(5) do
	Part.AngularVelocity.AngularVelocity = Vector3.new(math.random(-30,30)/100, math.random(-30,30)/100, math.random(-30,30)/100)
end

This script seems to be working right now. I just set the property I was changing to be more specific for both AngularVelocity and VectorVelocity.

Use the corresponding Assembly provided properties that come shipped with BaseParts. I’ve had bad luck with these, so I’ve had to resort to using Velocity and RotVelocity. Despite being deprecated, they somehow work better as the Assembly properties just don’t work at all for me.

Parent this script in the part you want rotating. It’s also recommended to put this as a server script.

local Part = script.Parent
local RunService = game:GetService("RunService")
RunService.Stepped:Connect(function()
	Part.Velocity = Vector3.new(0, 0, 0)
end)

while task.wait(5) do
	Part.RotVelocity = Vector3.new(math.random(-30,30)/100, math.random(-30,30)/100, math.random(-30,30)/100)
end