Attempting to spawn a Kart with custom colors

Recently, I’ve forked EgoMoose’s Circular Color Palette GUI and modified it to use it on a model. The model has a VehicleSeat in it.

However, I had no luck in doing this, and I attempted to solve it in two different ways.

  1. Spawn it via the client, however, a player cannot get into the VehicleSeat despite showing the colors, as seen here:

  1. Spawn it via the server using a RemoteEvent, however, only spawns the default colors of the model but the player can get into the VehicleSeat, as seen here:

The code below shows that I am attempting to spawn the kart via the server.

Code

Main Color Selector Script (LocalScript):

local dragger = require(script:WaitForChild("dragger"));

local slider = script.Parent:WaitForChild("Slider")
local slide = slider:WaitForChild("Slide")

local wheel = script.Parent:WaitForChild("Wheel");
local ring = wheel:WaitForChild("Ring");

colour = script.Parent:WaitForChild("Colour");

local kartbody = script.Parent.Parent.Parent.ViewportFrame.Kart.Body

--

local function toPolar(v)
	return math.atan2(v.y, v.x), v.magnitude;
end

local function radToDeg(x)
	return ((x + math.pi) / (2 * math.pi)) * 360;
end

--

local hue, saturation, value = 0, 0, 1;

local function update()
	colour.BackgroundColor3 = Color3.fromHSV(hue, saturation, value);
	for i, v in ipairs(kartbody:GetChildren()) do
		v.Color = colour.BackgroundColor3
	end
end

-- dragger

local slideDrag = dragger.new(slide);
local ringDrag = dragger.new(ring);

function slideDrag:onDrag(guiElement, input, delta)
	local rY = input.Position.y - slider.AbsolutePosition.y;
	local cY = math.clamp(rY, 0, slider.AbsoluteSize.y - slide.AbsoluteSize.y);
	guiElement.Position = UDim2.new(0, 0, 0, cY);
	
	value = 1 - (cY / (slider.AbsoluteSize.y - slide.AbsoluteSize.y));
	guiElement.BackgroundColor3 = Color3.fromHSV(0, 0, 1-value);
	
	update();
end

function ringDrag:onDrag(guiElement, input, delta)
	local r = wheel.AbsoluteSize.x/2
	local d = Vector2.new(input.Position.x, input.Position.y) - wheel.AbsolutePosition - wheel.AbsoluteSize/2;

	if (d:Dot(d) > r*r) then
		d = d.unit * r;
	end
	
	guiElement.Position = UDim2.new(0.5, d.x, 0.5, d.y);
	
	local phi, len = toPolar(d * Vector2.new(1, -1));
	hue, saturation = radToDeg(phi)/360, len / r;
	slider.BackgroundColor3 = Color3.fromHSV(hue, saturation, 1);
	
	update();
end

Firing the Remote Event Script (LocalScript):

local Kart = script.Parent.Parent.Parent.ViewportFrame.Kart
local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent

script.Parent.MouseButton1Click:Connect(function()
	SpawnKartEvent:FireServer()
end)

ServerScript (Script):

local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent
local Kart = game.StarterGui.ColorChanger.Frame.ViewportFrame.Kart
local color = game.StarterGui.ColorChanger.Frame.ScrollingFrame.ColourSelector.Colour.BackgroundColor3

SpawnKartEvent.OnServerEvent:Connect(function()
	local clone = Kart:Clone()
	clone.Parent = workspace
	for i, v in ipairs(clone.Body:GetChildren()) do
		v.Color = Kart.PrimaryPart.Color
	end
end)

Place file: color changer.rbxl (44.9 KB)

3 Likes

You cannot spawn it on the client and use it because the server does not know it exists.

The reason your server code doesn’t spawn it with the custom colors is because you do not send the color the user chose to the server. You should pass the chosen color as an argument to FireServer and use that argument on the server to determine how to color the Kart.

3 Likes

There’s multiple issues with this 3rd line of code on the ServerScript:

  • StarterGui never changes, so you would never be able to see anything different.
  • Even if you were reading from the PlayerGui, you still wouldn’t see any changes because the changes the player makes to the Gui don’t replecate.

To fix this, your Remote Event Script should pass the new color when Firing the server:

--local Kart = script.Parent.Parent.Parent.ViewportFrame.Kart (you don't need this line: the variable is never used)
local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent 
local color = --put a refrence to the Gui element with the color in here.

script.Parent.MouseButton1Click:Connect(function() 
    SpawnKartEvent:FireServer(color) 
end)

Alternatively, you could put all of the functions in one single script to easily reference the color:

local dragger = require(script:WaitForChild("dragger"));

local slider = script.Parent:WaitForChild("Slider")
local slide = slider:WaitForChild("Slide")

local wheel = script.Parent:WaitForChild("Wheel");
local ring = wheel:WaitForChild("Ring");

colour = script.Parent:WaitForChild("Colour");

local kartbody = script.Parent.Parent.Parent.ViewportFrame.Kart.Body

local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent 

--

local function toPolar(v)
	return math.atan2(v.y, v.x), v.magnitude;
end

local function radToDeg(x)
	return ((x + math.pi) / (2 * math.pi)) * 360;
end

--

local hue, saturation, value = 0, 0, 1;

local function update()
	colour.BackgroundColor3 = Color3.fromHSV(hue, saturation, value);
	for i, v in ipairs(kartbody:GetChildren()) do
		v.Color = colour.BackgroundColor3
	end
end

-- dragger

local slideDrag = dragger.new(slide);
local ringDrag = dragger.new(ring);

function slideDrag:onDrag(guiElement, input, delta)
	local rY = input.Position.y - slider.AbsolutePosition.y;
	local cY = math.clamp(rY, 0, slider.AbsoluteSize.y - slide.AbsoluteSize.y);
	guiElement.Position = UDim2.new(0, 0, 0, cY);
	
	value = 1 - (cY / (slider.AbsoluteSize.y - slide.AbsoluteSize.y));
	guiElement.BackgroundColor3 = Color3.fromHSV(0, 0, 1-value);
	
	update();
end

function ringDrag:onDrag(guiElement, input, delta)
	local r = wheel.AbsoluteSize.x/2
	local d = Vector2.new(input.Position.x, input.Position.y) - wheel.AbsolutePosition - wheel.AbsoluteSize/2;

	if (d:Dot(d) > r*r) then
		d = d.unit * r;
	end
	
	guiElement.Position = UDim2.new(0.5, d.x, 0.5, d.y);
	
	local phi, len = toPolar(d * Vector2.new(1, -1));
	hue, saturation = radToDeg(phi)/360, len / r;
	slider.BackgroundColor3 = Color3.fromHSV(hue, saturation, 1);
	
	update();
end

(put a refrence to the button here).MouseButton1Click:Connect(function() 
    SpawnKartEvent:FireServer() 
end)

Likewise, the ServerScript should be changed as well:

local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent
local Kart = game.StarterGui.ColorChanger.Frame.ViewportFrame.Kart --I would move the kart template to server storage, but this should work.
--local color = game.StarterGui.ColorChanger.Frame.ScrollingFrame.ColourSelector.Colour.BackgroundColor3 (delete this line due to using a faulty color checker)

SpawnKartEvent.OnServerEvent:Connect(function(player, color) --the player who fired the event is always the first argument.
	local clon = Kart:Clone() --Different variable name due to sharing spelling with the Clone() function.
	clon.Parent = workspace
	for i, v in ipairs(clon.Body:GetChildren()) do
		v.Color = color
	end
end)

Hope this helps!

2 Likes

I modified the scripts, however, as shown in the video, it only spawns a kart with a white body:

Code

ColourSelectorScript:

local dragger = require(script:WaitForChild("dragger"));

local slider = script.Parent:WaitForChild("Slider")
local slide = slider:WaitForChild("Slide")

local wheel = script.Parent:WaitForChild("Wheel");
local ring = wheel:WaitForChild("Ring");

colour = script.Parent:WaitForChild("Colour");

local kartbody = script.Parent.Parent.Parent.ViewportFrame.Kart.Body

local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent 


--

local function toPolar(v)
	return math.atan2(v.y, v.x), v.magnitude;
end

local function radToDeg(x)
	return ((x + math.pi) / (2 * math.pi)) * 360;
end

--

local hue, saturation, value = 0, 0, 1;

local function update()
	colour.BackgroundColor3 = Color3.fromHSV(hue, saturation, value);
	for i, v in ipairs(kartbody:GetChildren()) do
		v.Color = colour.BackgroundColor3
	end
end

-- dragger

local slideDrag = dragger.new(slide);
local ringDrag = dragger.new(ring);

function slideDrag:onDrag(guiElement, input, delta)
	local rY = input.Position.y - slider.AbsolutePosition.y;
	local cY = math.clamp(rY, 0, slider.AbsoluteSize.y - slide.AbsoluteSize.y);
	guiElement.Position = UDim2.new(0, 0, 0, cY);
	
	value = 1 - (cY / (slider.AbsoluteSize.y - slide.AbsoluteSize.y));
	guiElement.BackgroundColor3 = Color3.fromHSV(0, 0, 1-value);
	
	update();
end

function ringDrag:onDrag(guiElement, input, delta)
	local r = wheel.AbsoluteSize.x/2
	local d = Vector2.new(input.Position.x, input.Position.y) - wheel.AbsolutePosition - wheel.AbsoluteSize/2;

	if (d:Dot(d) > r*r) then
		d = d.unit * r;
	end
	
	guiElement.Position = UDim2.new(0.5, d.x, 0.5, d.y);
	
	local phi, len = toPolar(d * Vector2.new(1, -1));
	hue, saturation = radToDeg(phi)/360, len / r;
	slider.BackgroundColor3 = Color3.fromHSV(hue, saturation, 1);
	
	update();
end

script.Parent.Parent.TextButton.MouseButton1Click:Connect(function()
    SpawnKartEvent:FireServer(colour) 
end)

ServerScript:

local SpawnKartEvent = game.ReplicatedStorage.SpawnKartEvent
local Kart = game.StarterGui.ColorChanger.Frame.ViewportFrame.Kart --I would move the kart template to server storage, but this should work.

SpawnKartEvent.OnServerEvent:Connect(function(player, colour) --the player who fired the event is always the first argument.
	print(colour.BackgroundColor3)
	local clon = Kart:Clone() --Different variable name due to sharing spelling with the Clone() function.
	clon.Parent = workspace
	for i, v in ipairs(clon.Body:GetChildren()) do
		v.Color = colour.BackgroundColor3
	end
end)

You can take a look from the place file here: color changer.rbxl (44.9 KB)

Try referencing BackgroundColor3 in the ColourSelectorScript instead of in the Server script like this:

script.Parent.Parent.TextButton.MouseButton1Click:Connect(function()
    SpawnKartEvent:FireServer(colour.BackgroundColor3) 
end)
SpawnKartEvent.OnServerEvent:Connect(function(player, colour) 
	local clon = Kart:Clone()
	clon.Parent = workspace
	for i, v in ipairs(clon.Body:GetChildren()) do
		v.Color = colour
	end
end)

Out of curiosity, did the Print statement return nil?

3 Likes

No, it returned Color3 values.

Also, your solution worked! Thanks!

thirty characters… :confused:

1 Like