Brief: We click on an object's front surface, and it applies a ImageLabel centered around the mouse. The size is constant on all different sizes.
Problem 2: I can't apply this to all surfaces, I've already got the Surface's Normal being returned, but from there on, I don't know how to apply this information.
Here is me code:
local player = game.Players.LocalPlayer local mouse = player:GetMouse() local Texture = "http://www.roblox.com/asset/?id=82021756" local Sizer = 20 function Positioning(part,hitpos) local PixelRef = part.CFrame:toObjectSpace(CFrame.new(hitpos))--*CFrame.new(-part.Size.X/2,-part.Size.Y/2,0) local XRef = -PixelRef.p.X-- -math.ceil(PixelRef.X) If we want this to be applied on a stud=pixel scale (Messes up positions) local YRef = -PixelRef.p.Y-- -math.ceil(PixelRef.Y) return XRef,YRef end function click() local target = mouse.Target if target then local mRay = mouse.UnitRay local ray = Ray.new( mRay.Origin, mRay.Direction * 100 ) local part, pos, normal = game.Workspace:FindPartOnRay( ray, player.Character ) if part then print(part.Name,pos,normal) local surface local frame if part:findFirstChild("SurfaceGui") then surface = part:findFirstChild("SurfaceGui") frame = surface.Framey else print("Found none") surface = Instance.new( "SurfaceGui", part) surface.CanvasSize = Vector2.new(part.Size.X*10,part.Size.Y*10) frame = Instance.new("Frame", surface) frame.Name = "Framey" frame.Size = UDim2.new(1,0,1,0) frame.ClipsDescendants = true frame.BackgroundTransparency =1 end local Tex = Instance.new("ImageLabel",frame) Tex.Image = Texture Tex.Size = UDim2.new(0,Sizer,0,Sizer) Tex.BackgroundTransparency = 1 local X,Y = Positioning(part,pos) print(X,Y) Tex.Position = UDim2.new(.5+(X/(part.Size.X)),-Sizer/2,.5+(Y/(part.Size.Y)),-Sizer/2) end end end mouse.Button1Down:connect(click)
I've figured out where I was going wrong with the application, but I don't understand how I need to edit this to apply to other surfaces.
Kept running into problems, but this one works, all Parts (Including wedges and corners, however it will only work on the FLAT parts of this surface, it does not produce a Face value for the slopes)
Hopefully I'll be able to add more things to this, such as removing overlapping pictures and converting them into one big image, similairly, this would be cool for growing puddles. This would look really cool for explosions
I'm also fairly interested in getting these to wrap around corners, or be spread over multiple moving bricks (pretty sure there was a Snack Break problem about this).
In the meantime however, feel free to use the code. First applications I can think of are bullet holes and splats, but I'm sure someone can think of some more interesting applications. Here ya go!
local player = game.Players.LocalPlayer local mouse = player:GetMouse() local Texture = "http://www.roblox.com/asset/?id=82021756"--<Your image or whatever local PicSize = 20 --How many "pixels" the image is (Always square shape) local CanSize = 10 --10 pixels offset, unless replacing the Picture for something made of frames, not necessary to change function Positioning(part,hitpos) local PixelRef return -PixelRef.p end function ReturnNormal(PartCF,RayNorm) if PartCF.lookVector - RayNorm == Vector3.new(0,0,0) then return "Front",5 elseif PartCF.lookVector + RayNorm == Vector3.new(0,0,0) then return "Back",2 else local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = PartCF:components() if Vector3.new(R01,R11,R21) == RayNorm then return"Top", 1 elseif Vector3.new(-R01,-R11,-R21) == RayNorm then return "Bottom",4 elseif Vector3.new(-R00,-R10,-R20) == RayNorm then return "Left",3 elseif Vector3.new(R00,R10,R20) == RayNorm then return "Right",0 end end end function click() local target = mouse.Target if target then local mRay = mouse.UnitRay local ray = Ray.new( mRay.Origin, mRay.Direction * 100 ) local part, pos, normal = game.Workspace:FindPartOnRay( ray, player.Character ) if part then local SizeWidth = part.Size.X local SizeHeight = part.Size.Y local Face,Val = ReturnNormal(part.CFrame,normal) print(Face,Val) if Face == nil then return end if Face == "Top" or Face == "Bottom" then SizeWidth = part.Size.Z SizeHeight = part.Size.X elseif Face == "Right" or Face == "Left" then SizeWidth = part.Size.Z SizeHeight = part.Size.Y end local surface local frame for _,i in pairs(part:GetChildren()) do if i:IsA("SurfaceGui") then if i.Face == Val then surface = part:findFirstChild("SurfaceGui") frame = surface.Framey end end end if surface == nil then surface = Instance.new("SurfaceGui", part) surface.CanvasSize = Vector2.new(SizeWidth*CanSize,SizeHeight*CanSize) surface.Face = Val frame = Instance.new("Frame", surface) frame.Name = "Framey" frame.Size = UDim2.new(1,0,1,0) frame.ClipsDescendants = true frame.BackgroundTransparency =1 end local Tex = Instance.new("ImageLabel",frame) Tex.Image = Texture Tex.Size = UDim2.new(0,PicSize,0,PicSize) Tex.BackgroundTransparency = 1 local Size = -(part.CFrame:toObjectSpace(CFrame.new(pos))).p if Face == "Front" then Tex.Position = UDim2.new(.5+(Size.X/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2) elseif Face == "Back" then Tex.Position = UDim2.new(.5+(-Size.X/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2) elseif Face == "Right" then Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2) elseif Face == "Left" then Tex.Position = UDim2.new(.5+(-Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2) elseif Face == "Top" then Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(-Size.X/(SizeHeight)),-PicSize/2) elseif Face == "Bottom" then Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.X/(SizeHeight)),-PicSize/2) end end end end mouse.Button1Down:connect(click)