I'm making some maps for a game and the buildings are meshes that I imported from Blender, and since collisions are super wacky with meshes I'm making them non-collidable and implementing some invisible hitboxes instead. However since the hitboxes are transparent the Camera can go right through them, meaning players can have their camera go behind walls and such. I already found a fix to this which is changing the canOcclude function in one of the player scripts, but the way I did it involved having to reference each individual part, resulting in a very long string of text. Is there any more efficient way of doing this?
Here's what the function looks like at the moment for reference:
local ch = game.Workspace.Map.Cabin.Hitboxes local cht = { ch.Hitbox1, ch.Hitbox2, ch.Hitbox3, ch.Hitbox4, ch.Hitbox5, ch.Hitbox6, ch.Hitbox7, ch.Hitbox8, ch.Hitbox9, ch.Hitbox10, ch.Hitbox11, ch.Hitbox12, ch.Hitbox13, ch.Hitbox14, ch.Hitbox15, ch.CouchHitbox1, ch.CouchHitbox2, ch.CouchHitbox3, ch.CouchHitbox4, ch.TableHitbox, ch.FireplaceHitbox } local function canOcclude(part) -- Occluders must be: -- 1. Opaque -- 2. Interactable -- 3. Not in the same assembly as the subject if part == cht[1] or cht[2] or cht[3] or cht[4] or cht[5] or cht[6] or cht[7] or cht[8] or cht[9] or cht[10] or cht[11] or cht[12] or cht[13] or cht[14] or cht[15] or cht[16] or cht[17] or cht[18] or cht[19] or cht[20] or cht[21] then return true end if FFlagUserPoppercamLooseOpacityThreshold then return part.Transparency < 0.25 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) and not part:IsA('TrussPart') else return part.Transparency < 1 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) end end
Try this:
local ch = game.Workspace.Map.Cabin.Hitboxes local cht = ch:GetChildren() local function canOcclude(part) -- Occluders must be: -- 1. Opaque -- 2. Interactable -- 3. Not in the same assembly as the subject for i in pairs(cht) do if part == cht[i] then return true end end if FFlagUserPoppercamLooseOpacityThreshold then return part.Transparency < 0.25 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) and not part:IsA('TrussPart') else return part.Transparency < 1 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) end end
I'm not entirely sure this will work.
You should always try to cut down as many if statements as you can when doing any kind of programming if you're going for efficiency. Good news for you, there is a much easier method of handling how to get the parts:
One thing to note: The canOcclude should be run in render stepped or a similar looping function for this to work in real time.
--Assuming this is a local script, then you should be able to get or already have these: local player = game.Players.LocalPlayer local head = player.Character.Head local camera = workspace.CurrentCamera --We can get the part by shooting a ray from the players head towards the player's camera, multiplied by 10 because we want to get an object behind the player's camera function getPart() --second param is direction, and to get direction, we subtract the starting point from the end point local result = workspace:RayCast(head.CFrame.Position, (camera.CFrame.Position-head.CFrame.Position)*10) return result.Instance --returns the part that is behind the camera. end local function canOcclude() local part = getPart() --instead of sending the part to the function, we can get the part with our new function if FFlagUserPoppercamLooseOpacityThreshold then return part.Transparency < 0.25 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) and not part:IsA('TrussPart') else return part.Transparency < 1 and part.CanCollide and subjectRoot ~= (part:GetRootPart() or part) end end