scripting camera collisions for a custom camera has got to be the most annoying thing ive ever had to do.
camera:GetLargestCutoffDistance() works most of the time but if you’re almost parallel with a wall and your camera collides into it, the camera still clips into it some. if you simply raycast from like a player’s head to the camera’s target position and position the camera in the hit point, the camera clips into the walls still just slightly. That being said, anyone have a good method to detect camera collisions and position the camera in a suitable way where the camera doesn’t clip into parts at all? I tried looking at the default camera scripts which does a good job at achieving this but I can’t find anything.
You can detect collision by raycasting using this code.
Edit: This gets rid of the clipping issue btw.
local Character = game.Players.LocalPlayer.Character
local Camera = game.Workspace.CurrentCamera
local CameraRay = Ray.new(Character.Head.Position, Camera.CFrame.Position - Character.Head.Position)
local Ignore = {Character}
local HitPart, HitPosition = game.Workspace:FindPartOnRayWithIgnoreList(CameraRay, Ignore)
Camera.CFrame = (Camera.CFrame - (Camera.CFrame.Position - HitPosition)) + (Character.Head.Position - Camera.CFrame.Position).Unit
You could define the HumanoidRootPart’s Position as a centre point and then grab the Camera’s Position by doing local CameraPosition = workspace.CurrentCamera.CFrame.Position
and then you could cast a Ray like this: local Ray = Ray.new(Center, CameraPosition - Center)
local Hit, Position, Normal = workspace:FindPartOnRay(Ray)
and from there you could change the Position by adding the Normal returned and multiplying it by 0.4 which would transform in to the following: Position = Position + Normal * 0.4
and then when changing the Camera’s CFrame you can take in to account the new Position returned.
Edit: Implemented this and here are the end results: https://gyazo.com/11ac42b632fed8a1a73ba0d70b95e6a6
Your results are still clipping very slightly. The code I provided is 100% accurate.
Fixed, just needed to mess around with the multiplier a bit. https://gyazo.com/11ac42b632fed8a1a73ba0d70b95e6a6
where do you put this code? also no renderstep needed?
If you’re still looking, this will work:
local PlayerService = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = PlayerService.LocalPlayer
local character = player.CharacterAdded:Wait()
local camera = game.Workspace.CurrentCamera
RunService.RenderStepped:Connect(function(deltaTime)
local cameraRay = Ray.new(character.Head.Position, camera.CFrame.Position - character.Head.Position)
local Ignore = {character}
local HitPart, HitPosition = game.Workspace:FindPartOnRayWithIgnoreList(cameraRay, Ignore)
camera.CFrame = (camera.CFrame - (camera.CFrame.Position - HitPosition)) + (character.Head.Position - camera.CFrame.Position).Unit
end)
(Just a modification of the above answers.)
This script seems to break when you reset the character.
This might just work:
local PlayerService = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = PlayerService.LocalPlayer
local camera = game.Workspace.CurrentCamera
local function onCharacterAdded(character)
camera.CameraSubject = character:WaitForChild("Head")
end
player.CharacterAdded:Connect(onCharacterAdded)
RunService.RenderStepped:Connect(function(deltaTime)
local character = player.Character
if not character then
return
end
local cameraRay = Ray.new(character.Head.Position, camera.CFrame.Position - character.Head.Position)
local Ignore = {character}
local HitPart, HitPosition = game.Workspace:FindPartOnRayWithIgnoreList(cameraRay, Ignore)
camera.CFrame = (camera.CFrame - (camera.CFrame.Position - HitPosition)) + (character.Head.Position - camera.CFrame.Position).Unit
end)
Where would I put the code? Also LocalScript or Serverscript?
You can put the code in StarterPlayerScripts or StarterCharacterScripts
The script is local
The script still has slight clipping issues.
Bumping this because I need answers for a question, does this work for Enum.CameraType.Scriptable
Because for my game I use a custom camera for the cars and I want to add a feature where you can inspect your car inside your garage from all angles and my struggle may be camera collision through the floor.