Raycasting help

Wait I think its because of the .Unit, not sure why I added that.

2 Likes

You have to increase the Unit by multiplying it by a number, in which that number is the distance. Because the Ray is only casting 1 stud away, it doesn’t detect that there’s a part and so it says it was not hit.

You should do this:

local distance = 5 -- Change this to the distance
local raycastResult = workspace:Raycast(head.Position, (camera.CFrame.Position - head.Position).Unit * distance, params)
2 Likes

And is the distance variable supposed to be the cameras distance? Or just a random number

1 Like

You can set it to however you want. Make it a constant value though to avoid any issues.

1 Like

Why would I not just get rid of the .Unit

1 Like

You can, but it’s not recommended to do so.

1 Like

Okay but why don’t you recommend it?

1 Like

You can use .unit to convert the Vector into another Vector that points at that same direction but only with a Unit of 1. So you can multiply this by a distance that you can edit.

TL;DR: It’s unpractical to not use it.

1 Like

WRONG > (Okay well I just discovered this isn’t gonna work because for some reason the minimum CameraMaxZoomDistance is 8, so I cannot change that based on the distance of the object and the head.) < WRONG

After thinking logically for 5 seconds, I realised that it was illogical to be able to change the maximum zoom below the minimum zoom.

1 Like

Okay, now a new problem has occurred that I don’t know how to fix.

While yes, the camera will not let me look far into an object, I can still clip the camera slightly into the object making it invisible. To fix this I think I need to move the camera forward slightly, the problem is Idk how to do that.

I believe this is the calculation I would use to move the camera, but I have no experience moving the camera or doing any of this really.

local direction = ((raycastResult.Position - camera.CFrame.Position).Unit * 5)

1 Like

You can find the distance of the RaycastResult, then subtract it by an amount so that the camera is not clipping through an object.

local distance = RaycastResult.Distance - 0.5

Then, we move the camera away by that distance.

Camera.CFrame = CFrame.new(Head.Position) * Camera.CFrame * CFrame.new(-distance, 0, 0)

I’m not really sure if CFrame.new has the correct values.

1 Like

Workspace.AntiNukeYT.Player.LocalScript:16: attempt to perform arithmetic (unm) on nil

1 Like

That only happens if the Raycast did not find an object to hit. Wrap both the distance and the camera changing lines in an if statement if the Raycast did hit something. If it didn’t just set the camera normally.

1 Like

Okay sure this moves the camera forward, but I wanna make it move away from the object its hitting

Edit : I’m not sure this is even working, still doing testing.

Edit 2 : This is not working, it does nothing.

1 Like

I don’t understand. Could you clarify the question, please?

1 Like

This is the issue.

As you can see, even though the camera distance changing IS working, you can still see through the floor.

As a solution, I wanted to just shoot the camera forward a slight bit so it’s not “inside” the wall, so it does not become transparent. Now that I’m thinking of it, I remember some variable being the direction the object is facing. Perhaps we could just move the camera in that direction.

1 Like

Ah yes, it’s called the normal of the raycastResult. The direction the object the raycast hits is facing. We can just slightly move the camera in the direction of the raycastResult.Normal, but idk how to manipulate the camera.

1 Like

Didn’t work, I ended up having to run a loop on renderstepped (I don’t know why this is the case, but its the solution.

To anyone having my problems, take my code for free. This goes in a localscript inside startercharacterscripts.

local runs = game:GetService("RunService")

runs.RenderStepped:Connect(function(deltaTime)
	local player = game.Players.LocalPlayer
	local character = player.Character
	local head = character:WaitForChild("Head")
	local camera = workspace.CurrentCamera

	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {character, camera}
	params.FilterType = Enum.RaycastFilterType.Exclude
	local raycastResult = workspace:Raycast(head.Position, (camera.CFrame.Position - head.Position), params)

	if raycastResult then
		camera.CFrame = (camera.CFrame - (camera.CFrame.Position - raycastResult.Position)) + (character.Head.Position - camera.CFrame.Position).Unit    
	end
end)

Without my script :

With my script :

1 Like

Looks good. One thing you can do is optimized variables that are re-used such as player and params. character, head, and camera are subject to change. And the param’s FilterDescendantsInstances property can be changed inside the function as well.
Another optimization you can do is RunService:BindToRenderStep .
The priority would be 1 more than camera so Enum.RenderPriority.Camera.Value+1 . This makes it so the function runs after the camera update instead of before it. But .RenderStepped:Connect runs functions after all binded functions since it has lowest priority.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.