Over-The-Shoulder Camera System

Beautiful object oriented programming!
Your error messages are perfect!
Overall 10/10 module. Thank you!

1 Like

Hey Arbeiters,
So sorry your account got banned- we can follow up somewhere else

But I noticed a SMALL issue with the :SetCharacterAlignment(true).
If you don’t disable AutoRotate in the humanoid, you get a little funny behavior when strafing as demonstrated here:


AutoRotate Enabled

I went ahead and added a bit to your code that disables the AutoRotate so the UX is a little more polished. This was the end result:


AutoRotate Disabled

As you can see, it’s a lot easier to keep the front of the weapon in-line with the cursor.

I went ahead and made a pull request on GitHub:

Again, good job on this module! I absolutely love it!

5 Likes

ayo, probably missing something but

https://gyazo.com/58d836efc554f4dcdb4cacc82ef2c082

how do i get rid of this hideous player movement, only happens when im zoomed in-

oh. the post literally above me explains what the issue is. lol

1 Like

Yeah! The fork to fix that issue was merged Nov 30, 2020. Feel free to update the module from GitHub!
Also, you might want to adjust your offsets in the module.

X = R (+X) / L (-X),
Y = U (+Y) /D (-Y),
Z = IN (+Z) / OUT (-Z)

1 Like

This is nice but this would even be better if you can lock-on temporarily or permanently on an enemy. (For sick skills and such)

1 Like

I happen to be able to do this by adding this in Line 201:

if script.Parent:FindFirstChild("MoveCamera") then
	currentCamera.CFrame = script.Parent:FindFirstChild("MoveCamera").Value
	script.Parent:FindFirstChild("MoveCamera"):Destroy()
	self:Disable()
	wait()
	self:Enable()
	self:SetCharacterAlignment(true)
	return
end

I know this is not the best method but that’s how I was able to make it.

so basically only enabling and disabling would be much more great if there was a bit of documentation for it

That would be sick update! atleast give an option to people to enable it or disable it.

@Arbeiters @BenMactavsin Hello. I found this useful but the freaking error wont let me do it. I don’t know what to do with this.


Can you help me lol.

According to that script, the module should be named EXACTLY “OTS Camera System” and be a child of the LocalScript you are editing. It would help if you were showing how the camera system is implemented in your explorer.

2 Likes

Thank you. it really worked. The Topic Owner should make sure so it isnt confusing. just like you said that it aint on the tutorial on the topic.

This is what I’ve been looking for! However does anyone know how to fix this glitch? I don’t think it’s his script, and my model’s CanCollide is off, can anyone help?

Where do i put the Module? I’ve never done any enable stuff or kinds like that.

I have a problem with camera collisions. How would I make it so the camera goes through parts that have CanCollide on false? Compared to the default camera behavior, also collides even with fully transparent parts as well. (issue demonstrated in the video, the orange beam is actually a transparent part, made it visible for clarity)
https://streamable.com/ah1a3b

You should use this!

I don’t exactly understand it. How would I be able to automatically filter out uncancollided or fully invisible parts with this?

You would need to edit the code, if you go into the ‘OTS Camera System’ script and find the section:

	
		--// Raycast for obstructions //--
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {character}
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
		local raycastResult = workspace:Raycast(
			humanoidRootPart.Position,
			newCameraCFrame.p - humanoidRootPart.Position,
			raycastParams
		)
		----
		
		--// Address obstructions if any //--
		if (raycastResult ~= nil) then
			local obstructionDisplacement = (raycastResult.Position - humanoidRootPart.Position)
			local obstructionPosition = humanoidRootPart.Position + (obstructionDisplacement.Unit * (obstructionDisplacement.Magnitude - 0.1))
			local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = newCameraCFrame:components()
			newCameraCFrame = CFrame.new(obstructionPosition.x, obstructionPosition.y, obstructionPosition.z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
		end

You would need to track any obstructions derived as ‘raycastResult’, check if they’re not CanCollide and/or transparent, then add them to an ignore list. Ideally, you would reiterate the raycast with the updated ignorelist on that frame, but it would do just as well to then alter the ‘raycastParams.FilterDescendantsInstances = {character}’ to include the new ignore list as well as the character on the next :update cycle. Obviously if you do the latter, you’ll need to iteratively clean the ignore list of parts that weren’t touched in a while through some dirty set key method.

That jump in frame from a far away position to a closer one upon finding an obstruction is quite jarring though, highly recommend you interpolate between frames.

You could feature request this from OP if you can’t do it. If I get the time and OP hasn’t done it, I’ll post the updated code here.

3 Likes

OP is banned. I can’t really do it because I’m not at home right now.

Mouse.TargetFilter ignores an element in workspace from the camera (or thats how I understand it at least). Here’s an example of how it would work

local Ignore = game:GetService("Workspace").IgnoreFolder
local Player = game:GetService("Players").LocalPlayer

local Mouse = Player:GetMouse()

Mouse.TargetFilter = Ignore

every descendants inside the folder “IgnoreFolder” in workspace will be ignored in current camera.
Here’s a gif showing an example where the red outline part is in workspace and green outline part is in the IgnoreFolder.
https://gyazo.com/751a8105eaf79560eb0d61633c4bfb77

1 Like

I’ll look into this when I get back home.

1 Like