How would I make a wheel spin reward system?

I can handle the server side, which includes adding items, daily system, etc

but how would I have the client spin, and have the arrow on the wheel land directly on the item I would need it to land on? Seems more difficult compared to just a simple case open GUI system.

I don’t even see a YT video on this, there are some but not to where I could have it land on the item needed.

A basis or anything that could guide me would be appreciated, thanks in advanced.

Start spin and fire server
Keep spinning, server does the stuff
Server tells client where to land
Slow spin and stop on correct one. ← making this look nice is probably the hardest bit.

Do you have a circular gui that is rotating?
or is it a linear perspective one that just runs right to left?

2 Likes

I currently have two variations:

  • 3D opening
  • Linear perspective and it does indeed, slowly spin toward the item. It randomly generates 50 frames, spin, and I always it land on the 20th frame, which I have the item that the player recieves at.

Now looking back and reading this:

Should I just have a module that store the reward and CFrame position, if you know, for example:

local Module = {
 ["Reward1"] = {Reward = "100 coins", Position = CFrame.new(0,0,0)}
}

But I noticed that i’d be sacrificing that “randomness.” I’ve never done much with wheels or anything circular for that matter.

While typing this, maybe I could store a specific position like and check if it’s inbetween a certain frame. Don’t know if this is possible to store in a dictionary though.

local Module = {
 ["Reward1"] = {Reward = "100 coins", Position = CFrame.new(0,0,0)}
}
return Module

-- local script
for i, v in pairs(Module) do
   if RewardPosition then
      -- Check if any of the Reward Position within the certain radius of v.Position;
      -- which I don't even know how to accomplish lol it just sounds nice
   end 
end
1 Like

Sorry, had to do something, but to add to this, would there be any way I could somehow get a specific radius of an area, so i can detect what reward to give?

1 Like

What I would do is get a random prize first then spin a wheel and make it land on the prize you already won. Here is a tutorial for a Weighted Chance System if you are interested.

2 Likes

I scripted one for one of my games. Here’s how I did it:

-- This table contains all the prize data. Stars is the prize, MinPos and MaxPos is the rotation value of the arrow in the gui for that prize segment of the wheel. (you will probably need to adjust these values to match your own prize segments)
local Fortune={{Stars=1000, MinPos=1352, MaxPos=1393}, {Stars=300, MinPos=1172, MaxPos=1214}, 
               {Stars=150, MinPos=1127, MaxPos=1169}, {Stars=100, MinPos=1037, MaxPos=1078}, 
               {Stars=50, MinPos=1082, MaxPos=1123}, {Stars=50, MinPos=1263, MaxPos=1300},
               {Stars=25, MinPos=1219, MaxPos=1259}, {Stars=25, MinPos=1308, MaxPos=1348} }

-- The following just determines which prize the player is going to win.
local Rnd=math.random(1, 100) -- Choose a random number to determine prize
local WinningLine
if Rnd>95 then WinningLine=Fortune[1]--1000 Stars
elseif Rnd<96 and Rnd>85 then WinningLine=Fortune[2] -- 300 Stars
elseif Rnd<86 and Rnd>69 then WinningLine=Fortune[3]-- 150 Stars
elseif Rnd<70 and Rnd>49 then WinningLine=Fortune[4]-- 100 Stars
elseif Rnd<50 and Rnd>25 then local r=math.random(1, 2) if r==1 then WinningLine=Fortune[5] else WinningLine=Fortune[6] end -- 50 Stars
elseif Rnd<26 then local r=math.random(1, 2) if r==1 then WinningLine=Fortune[7] else WinningLine=Fortune[8] end -- 25 Stars
	end

-- This line decides the final landing position of the arrow (I used min and max pos so the arrow didn't land on the 
-- exact same spot of each segment every time)
local RandPos=math.random(WinningLine.MinPos, WinningLine.MaxPos)

-- Added the winner to a table including what their prize is so when they click a claim button on their gui I can refer
-- to this table and give them their winnings.
table.insert(FortuneWheelWinners, {Player.UserId, WinningLine.Stars})

-- Fire the client to show the fortune wheel gui, passing the Rotation Value of the arrow so the wheel knows where to stop.
UpdateClient:FireClient(Player, "FortuneWheel", RandPos)

Client Gui Code Segment:

-- This is the tween setup that spins the arrow for 5 seconds and lands on the passed Rotation Value from the above code
local tweenInfo =  TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
local tween = TweenService:Create(Wheel, tweenInfo, {Rotation = FinalRot}) 
tween:Play()
7 Likes

Thanks so much, ill use this as refrence!

This was actually how I was thinking of doing it, but my brain couldn’t execute it right lol

1 Like

One question though, for

What was for your finalRot? I’m not too fond in Tweening CFrames, I used:

local FinalPos = Wheel.CFrame * Vector3.new(0, 2500 --[[Position]],0)

To test 2500,
It spins on the Y axis but has this weird little twist that doesn’t align with the spinning decal I have.
image

Not to mention when I put one value for rotation, it gives me an error saying that it’s vector3 is needed

Edit: Ohhh nvm, this was a tween for the GUI, I was needing one for the model

1 Like