What do you want to achieve?
A building system that enables you to build horizontally (or any direction other than vertical) by having your mouse hover over another part.
What is the issue?
Normally, people would use ray normals to achieve this, but i would like it to also work on rotated parts (which results in a long string of decimals for its normal).
What solutions have you tried so far?
I have spitballed some random math and such and tried completely different systems, but they do not work properly.
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local RunService = game:GetService('RunService')
local Server = {} Server.__index = Server
local Client = {} Client.__index = Client
local function CanculatePos<V: Vector3>(BoxSize: V, origin: V, mouseHit: V): Vector3?
local MouseDir = (origin - mouseHit).Unit
local RayResult = workspace:RayCast(origin, MouseDir*50)
if not RayCast and then return end
return RayResult.Position + BoxSize*RayResult.Normal/2
end
function Server:Build(mouseHit: Vector3)
if (self.char.Head.Position - mouseHit).Magnitude > 50 then return end
local Position = CanculatePos(
Vector3.One,
self.char.Head,
mouseHit)
if not Position then return end
local Part = Instance.new('Part')
Part.Size = Vector3.One
Part.Anchored = true
Part.Position = Position
Part.Parent = workspace
end
function Client:Start()
if self.Started then return end
self.Started = true
self.VisualPart.Parent = workspace
self.RenderTheard = RunService.RenderStepped:Connect(function()
self.VisualPart.Position = CanculatePos(
Vector3.One,
self.char.Head,
self.mouse.Hit.Position) or Vector3.zero
end)
end
function Client:Stop()
self.VisualPart.Parent = ReplicatedStorage
self.RenderTheard:Disconnect()
self.Started = false
end
function Client:Build()
self.RemoteEvent:FireServer(self.mouse.Hit.Position)
end
local InitClient = function(Player: Player, OnBuild: RemoteEvent)
local self = setmetatable({}, Constructor)
self.RenderTheard = nil :: RBXScriptSignal
self.plr = Player
self.mouse = plr:GetMouse()
self.char = plr.Character or plr.CharacterAdded:Wait()
self.RemoteEvent = OnBuild
self.Started = false
self.VisualPart = (function()
local Part = Instance.new('Part')
Part.Size = Vector3.One
Part.Anchored = true
Part.Transparency = .5
Part.Parent = ReplicatedStorage
return Part
end)()
return self
end
local InitServer = function(Player: Player, OnBuild: RemoteEvent)
local self = setmetatable({
char = Player.Character or Player.CharacterAdded:Wait()
}, Server)
OnBuild.OnServerEvent:Connect(function(plr: Player, mouseHit: Vector3)
self:Build(mouseHit)
end)
return self
end
return {InitClient = InitClient, InitServer = InitServer}
Thank you for taking the time to write that! Would you mind providing an additional explanation of the code? It is far more advanced than what I am used to, so I would greatly appreciate further elaboration. Thank you! :))