I am currently working on Paint a Game game but I have some issues on the client code with coloring, for example, when I am walking and painting, it pains different direction or position, but I want 5 studs from player’s feet, how can I fix it, here’s the code:
ServerScript
`
local HttpService = game:GetService(“HttpService”)
local Workspace = game:GetService(“Workspace”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local PlaceIds = {
126884695634066,
79546208627805,
109983668079237
}
local GAS_URL = “https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/exec”
local TARGET_IMAGE_ID = “rbxassetid://78673074540642” – fallback
local TOTAL_CANVAS_SIZE = 72
local GRID_RESOLUTION = 360
– Pravimo RemoteEvent
local canvasEvent = ReplicatedStorage:FindFirstChild(“CanvasSetupEvent”) or Instance.new(“RemoteEvent”)
canvasEvent.Name = “CanvasSetupEvent”
canvasEvent.Parent = ReplicatedStorage
local function InitializePixelCanvas()
local randomPlaceId = PlaceIds[math.random(1, #PlaceIds)]
print("[SERVER] Prevlačim UniverseId za PlaceId: " .. randomPlaceId)
local successHttp, response = pcall(function()
return HttpService:GetAsync(GAS_URL .. "?placeId=" .. tostring(randomPlaceId))
end)Preformatted text
local imageToLoad = TARGET_IMAGE_ID
if successHttp then
local successDecode, decodedData = pcall(function() return HttpService:JSONDecode(response) end)
if successDecode and decodedData.success and decodedData.universeId then
imageToLoad = "rbxthumb://type=GameIcon&id=" .. decodedData.universeId .. "&w=150&h=150"
print("[SERVER] Uspešno dobijen rbxthumb link: " .. imageToLoad)
end
end
-- Kreiramo Part na serveru da ga svi vide
local canvasPart = Workspace:FindFirstChild("PixelArtCanvasPart")
if not canvasPart then
canvasPart = Instance.new("Part")
canvasPart.Name = "PixelArtCanvasPart"
canvasPart.Size = Vector3.new(TOTAL_CANVAS_SIZE, 0.2, TOTAL_CANVAS_SIZE)
canvasPart.CFrame = CFrame.new(0, 0.1, 0)
canvasPart.Anchored = true
canvasPart.Material = Enum.Material.SmoothPlastic
canvasPart.Color = Color3.fromRGB(255, 255, 255)
canvasPart.Parent = Workspace
end
canvasPart:SetAttribute("ImageToLoad", imageToLoad)
canvasEvent:FireAllClients(canvasPart, imageToLoad)
end
InitializePixelCanvas()
game:GetService(“Players”).PlayerAdded:Connect(function(player)
local canvasPart = Workspace:WaitForChild(“PixelArtCanvasPart”, 10)
if canvasPart then
local img = canvasPart:GetAttribute(“ImageToLoad”)
if img then
canvasEvent:FireClient(player, canvasPart, img)
end
end
end)
`
LocalScript
`
–!native
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local AssetService = game:GetService(“AssetService”)
local Players = game:GetService(“Players”)
local player = Players.LocalPlayer
local canvasEvent = ReplicatedStorage:WaitForChild(“CanvasSetupEvent”)
local GRID_RESOLUTION = 360
local COLOR_RADIUS = 4
canvasEvent.OnClientEvent:Connect(function(canvasPart, imageToLoad)
if not canvasPart or not canvasPart:IsA(“BasePart”) then return end
local surfaceGui = canvasPart:FindFirstChildOfClass("SurfaceGui")
if not surfaceGui then
surfaceGui = Instance.new("SurfaceGui")
surfaceGui.Face = Enum.NormalId.Top
surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.FixedSize
surfaceGui.CanvasSize = Vector2.new(GRID_RESOLUTION, GRID_RESOLUTION)
surfaceGui.Parent = canvasPart
end
local imageLabel = surfaceGui:FindFirstChildOfClass("ImageLabel")
if not imageLabel then
imageLabel = Instance.new("ImageLabel")
imageLabel.Size = UDim2.new(1, 0, 1, 0)
imageLabel.BackgroundTransparency = 1
imageLabel.ResampleMode = Enum.ResamplerMode.Pixelated
imageLabel.Parent = surfaceGui
end
local success, sourceEditableImage = pcall(function()
return AssetService:CreateEditableImageAsync(imageToLoad)
end)
if not success or not sourceEditableImage then
warn("[KLIJENT] Neuspešno učitavanje izvorne slike.")
return
end
local targetEditableImage = AssetService:CreateEditableImage({
Size = Vector2.new(GRID_RESOLUTION, GRID_RESOLUTION)
})
imageLabel.ImageContent = Content.fromObject(targetEditableImage)
targetEditableImage:DrawRectangle(Vector2.zero, targetEditableImage.Size, Color3.fromRGB(200, 200, 200), 0, Enum.ImageCombineType.Overwrite)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Include
raycastParams.FilterDescendantsInstances = {canvasPart}
task.spawn(function()
while canvasPart and canvasPart.Parent do
task.wait(0.03)
local character = player.Character
local hrp = character and character:FindFirstChild("HumanoidRootPart")
if hrp then
local rayResult = workspace:Raycast(hrp.Position, Vector3.new(0, -15, 0), raycastParams)
if rayResult and rayResult.Instance == canvasPart then
local localPos = canvasPart.CFrame:PointToObjectSpace(rayResult.Position)
local u = math.clamp((localPos.X / canvasPart.Size.X) + 0.5, 0, 1)
local v = math.clamp((localPos.Z / canvasPart.Size.Z) + 0.5, 0, 1)
local pixelX = math.floor(u * GRID_RESOLUTION)
local pixelY = math.floor(v * GRID_RESOLUTION)
local clickPosition = Vector2.new(pixelX, pixelY)
local sourceSize = sourceEditableImage.Size
local sampleX = math.clamp(math.floor(u * sourceSize.X), 0, sourceSize.X - 1)
local sampleY = math.clamp(math.floor(v * sourceSize.Y), 0, sourceSize.Y - 1)
local colorBuffer = sourceEditableImage:ReadPixelsBuffer(Vector2.new(sampleX, sampleY), Vector2.new(1, 1))
local r = buffer.readu8(colorBuffer, 0) / 255
local g = buffer.readu8(colorBuffer, 1) / 255
local b = buffer.readu8(colorBuffer, 2) / 255
local targetColor = Color3.new(r, g, b)
targetEditableImage:DrawCircle(
clickPosition,
COLOR_RADIUS,
targetColor,
0,
Enum.ImageCombineType.Overwrite,
Enum.AntiAliasing.Disabled
)
end
end
end
end)
end)
`
I think issue is on the client side in while loop. Any idea?