I’m trying to make some kind of 3D crosshair that is always in front of the player and touching the ground (Like in pikmin, for example), but the crosshair is always is always floating. I don’t know how to fix this, please help!
Script (LocalScript)
local cursor = game:GetService("ReplicatedStorage").Cursor:Clone()
cursor.Parent = workspace
cursor.CanCollide = false
cursor.Transparency = 0
local players = game:GetService("Players")
players.LocalPlayer.CharacterAppearanceLoaded:Wait()
local playerchar = players.LocalPlayer.Character
local root = playerchar.HumanoidRootPart
local runservice = game:GetService("RunService")
local high = 10
local function SetCFrame()
cursor.CFrame = root.CFrame * CFrame.new(0, high, -10)
end
local function raycastdown()
local rayOrigin = cursor.Position
local rayDirection = cursor.CFrame.UpVector * -300
-- Build a "RaycastParams" object and cast the ray
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {cursor,
root.Parent
}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
return raycastResult
end
game:GetService("RunService").RenderStepped:Connect(function()
local result = raycastdown()
if result then
high = result.Position.Y
end
SetCFrame()
end)
By the way, If you know how to make the crosshair ignore models with a humanoid inside, that would also be very helpful!
It would be nice if you showed us a screenshot or recording of the problem. We’re not robots and we can’t magically fix your problem with a lack of data.
Oops, I didn’t see that high was actually the variable being changed by the Raycast. But the issue still stems from that SetCFrame function.
root is the HumanoidRootPart of the player, which is conveniently also always floating above the surface. You can see for yourself by selecting the HumanoidRootPart in the explorer and looking for the blue outline.
Instead of raycasting directly below the player, you should raycast precisely where the crosshair should be. That means offsetting the original rayOrigin to be in front of the player. And then you just need to position the crosshair at exactly where that ray hit and orient it to be perpendicular to the surface normal to align it to the surface.
bro just raycast at where the crosshair should be
I expected protogens to be smart
local offset: CFrame = CFrame.new(0, 50, -10) --we go up just in case the player is on a slope or smth
local rcp: RaycastParams = RaycastParams.new()
rcp.FilderDescendantsInstances = {cursor, root.Parent}
rcp.FilterType = Enum.RaycastFilterType.Blacklist
local down: Vector3 = Vector3.yAxis * -1e2
local angle: CFrame = CFrame.Angles(math.rad(90), 0, 0) --this is probably wrong
local function raycastDown()
local ray: RaycastResult = workspace:Raycast(root * offset, down, rcp)
if ray then
cursor.CFrame = CFrame.lookAt(ray.Position, ray.Position + ray.Normal) * angle
end
end
@KevinElCubo847 he actually showed it right in the picture. You should raycast to the floor from the top, then get touch position and place the cross to there
I thought I mentioned something in my previous reply about aligning the crosshair with the ground? Or is the issue that it is trying to align, just not correctly?
What I meant is that the crosshair has an arrow-like shape, and the arrow is supposed to point the direction the player is facing.
This is what I mean with always facing the same direction:
The extrusion on the cursor always points at the same direction.