i want make shift lock for mobile with point mouse or what ever name (:
i find a script give me a target (fr i forget if i got this from ai or on webside i will just input the script here).
local length = 100
local camera = workspace.CurrentCamera
viewportPoint = camera.ViewportSize / 2
unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
ray = Ray.new(unitRay.Origin, unitRay.Direction * length)
part = workspace:FindPartOnRay(ray)
print(part)
but now i need a TargetSurface i show just this
until now i cant find any thing to help also i dont really know how should this work like what should i do to get targetSurface on camera
and i got this script and its also give me a random surfaces (: someone help what should i do
local function GetEnumNormalFromRay(ray :RaycastResult)
local part: Part = ray.Instance
local Position = ray.Position
local Normal = {
[1] = {Position = part.Position + part.CFrame.RightVector * part.Size.X/2, EnumNormal = Enum.NormalId.Right},
[2] = {Position = part.Position + part.CFrame.RightVector * -part.Size.X/2, EnumNormal = Enum.NormalId.Left},
[3] = {Position = part.Position + part.CFrame.UpVector * part.Size.Y/2, EnumNormal = Enum.NormalId.Top},
[4] = {Position = part.Position + part.CFrame.UpVector * -part.Size.Y/2, EnumNormal = Enum.NormalId.Bottom},
[5] = {Position = part.Position + part.CFrame.LookVector * -part.Size.Z/2, EnumNormal = Enum.NormalId.Front},
[6] = {Position = part.Position + part.CFrame.LookVector * part.Size.Z/2, EnumNormal = Enum.NormalId.Back},
}
local Closest = Normal[1]
for _,Side in pairs(Normal) do
local lookForward = Vector3.FromNormalId(Side.EnumNormal)
local lookToPoint = (Side.Position - Position).unit
local angle = math.deg(math.acos(math.clamp(lookForward:Dot(lookToPoint), -1, 1)))
if (Side.Position - Position).magnitude < (Closest.Position - Position).magnitude then
if angle < 90 then
Closest = Side
end
end
end
return Closest.EnumNormal
end
local length = 1000
local camera = workspace.CurrentCamera
viewportPoint = camera.ViewportSize / 2
unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
raycastResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * length)
if raycastResult then
targetSurface = GetEnumNormalFromRay(raycastResult)
print(targetSurface.Name)
else
print("No object hit by the ray.")
end
also i will never rotate object (: if its should help
you should try using nox7’s roblox luau mouse target surface script on github.
on its own it prints the Enum.NormalId of the TargetSurface (Top, Right, etc)
i would also recommend adding RaycastParams so that the ray doesn’t intersect with the character.
so change the getRayCollisionNormal() function to:
local function getRayCollisionNormal(x,y)
local rayIgnoreParams = RaycastParams.new()
rayIgnoreParams .FilterType = Enum.RaycastFilterType.Exclude
rayIgnoreParams .FilterDescendantsInstances = game.Players.LocalPlayer.Character:GetDescendants()
local cam = workspace.CurrentCamera
local unitRay = cam:ScreenPointToRay(x,y)
local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * maxRayDistance, rayIgnoreParams)
if (rayResult) then
local instance = rayResult.Instance
local normal = rayResult.Normal
-- Get an object-space normal for rotated instance
if (instance) then
normal = instance.CFrame:VectorToObjectSpace(normal)
end
return normal or nil;
end
end
its still give me a random values i dont know but look if i made something wrong
maxRayDistance = 100
viewportPoint = workspace.CurrentCamera.ViewportSize
local function getRayCollisionNormal(x,y)
local rayIgnoreParams = RaycastParams.new()
rayIgnoreParams.FilterType = Enum.RaycastFilterType.Exclude
rayIgnoreParams.FilterDescendantsInstances = game.Players.LocalPlayer.Character:GetDescendants()
local cam = workspace.CurrentCamera
local unitRay = cam:ScreenPointToRay(x,y)
local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * maxRayDistance, rayIgnoreParams)
if (rayResult) then
local instance = rayResult.Instance
local normal = rayResult.Normal
-- Get an object-space normal for rotated instance
if (instance) then
normal = instance.CFrame:VectorToObjectSpace(normal)
end
return normal or nil;
end
end
print(getRayCollisionNormal(viewportPoint.X/2, viewportPoint.Y/2))
your code is close, but the original code has some last minute calculations to get the normal id.
heres a beefy script that’ll hopefully work for you that does those calculations inside of the function
local maxRayDistance = 100
local mouse = game.Players.LocalPlayer:GetMouse()
--------------- Function ---------------
local function getRayTargetSurface(x,y)
local function getRayCollisionNormal()
local rayIgnoreParams = RaycastParams.new()
rayIgnoreParams.FilterType = Enum.RaycastFilterType.Exclude
rayIgnoreParams.FilterDescendantsInstances = game.Players.LocalPlayer.Character:GetDescendants()
local cam = workspace.CurrentCamera
local unitRay = cam:ScreenPointToRay(x,y)
local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * maxRayDistance, rayIgnoreParams)
if (rayResult) then
local instance = rayResult.Instance
local normal = rayResult.Normal
-- Get an object-space normal for rotated instance
if (instance) then
normal = instance.CFrame:VectorToObjectSpace(normal)
end
return normal or nil;
end
end
local hitNormal = getRayCollisionNormal(x, y)
local surface = nil;
if (hitNormal) then
local dotY = hitNormal:Dot(Vector3.new(0,1,0))
local dotX = hitNormal:Dot(Vector3.new(1,0,0))
local dotZ = hitNormal:Dot(Vector3.new(0,0,1))
if (math.abs(dotY) >= 0.9) then
if (dotY < 0) then
surface = Enum.NormalId.Bottom
else
surface = Enum.NormalId.Top
end
elseif (math.abs(dotX) >= 0.9) then
if (dotX < 0) then
surface = Enum.NormalId.Left
else
surface = Enum.NormalId.Right
end
else
if (dotZ < 0) then
surface = Enum.NormalId.Front
else
surface = Enum.NormalId.Back
end
end
end
return surface
end
----------------------------------------
while wait(1) do -- Test by repeating every 1 second
print(getRayTargetSurface(mouse.X, mouse.Y))
end