Camera Manipulation Scripting Help

Hello,
I need help with scripting the camera movement in my game.
I am trying to make the camera move only between two randomly placed parts and look only in one direction. It will follow the player’s head, so it’s like the closest position to the player’s head on the axis between those two parts.

Here’s an example of what I am trying to achieve through scripting:

Limit1 = First part placed randomly by me.
Limit2 = Second part placed randomly by me.
Head Position = Character head position.
Result = Camera CFrame that I am trying to achieve.

Here are some videos demonstrating it:


^ (video by @Cryoheat)

I know how to achieve that only on 1 straight axis, but I don’t know how to make work with random parts positions. So I only need to know how to get that camera position, I can do everything else on my own.

Thank you in advance!

12 Likes

You can make use of math.clamp, which restricts any numbers from going over or under a certain interval.

Basically, every frame you would check for the cameras movement:

local RS = game:GetService("RunService")
local Camera = workspace.CurrentCamera

local Part1 = -- Part
local Part2 = -- Part

RS.RenderStepped:Connect(function()
    Camera.CFrame = CFrame.new(math.clamp(Camera.CFrame.X, Part1.Position.X, Part2.Position.X), Camera.CFrame.Y, Camera.CFrame.Z)
end)

Keep in mind that this only works for one axis.

There is a better way, though, by setting the camera to Scriptable, but then you would have to customly script the camera movement and then script the limitations, but it’s more efficient and wont cause unwanted bugs.

4 Likes

You can just do this to know the part positions:
local partPosA = game.Worksace.PartA.Position
local partPosB = game.Workspace.PartB.Position

If you need to know how to make the part positions random, use the Random commands:
local Random = Random.new()

PartA.Position = Vector3.new(Random:NextInteger(min,max),Random:NextInteger(min,max),Random:NextInteger(min,max)

PartA.Position = Vector3.new(Random:NextInteger(min,max),Random:NextInteger(min,max),Random:NextInteger(min,max)

1 Like

Explained it on your Twitter replies https://twitter.com/rawblocky/status/1283077610600140800?s=21

‪Average the positions of the Vector3’s. We can do this by adding the X’s together, Y’s together, and Z’s together, then dividing them by two. After that, you can plug them into a Vector3 variable!

<U+202A>Vector3.new((Limit1.X+Limit2.X)/2, (Limit1.Y+Limit2.Y)/2, (Limit1.Z+Limit2.Z)/2)<U+202C>

‪This would return the average.

‪Next, use CFrame to make the camera face the player’s head. We can do this by making the first value of the CFrame to be the average position, and the second value be the player’s head.

<U+202A>CFrame.new(Vector3.new((Limit1.X+Limit2.X)/2, (Limit1.Y+Limit2.Y)/2, (Limit1.Z+Limit2.Z)/2), Character.Head.Position)<U+202C>

‪And there you go, I didn’t test this, but I hoped it worked!

5 Likes

This is what I was going to suggest but after taking another look, it seems like nullxiety wants the camera to move in between these 2 points based on where the character’s root is, which makes this a lot more difficult.

1 Like

Setting the CameraType to Scriptable would work with your code, adding any extra scripts would be unnecessary.

Ok so I tried messaging you through twitter but you don’t seem to look at DM’s (maybe i’m hidden/blocked or smthn?)

Here’s my solution, the most important part here will be the cameras position, the orientation can be a separate thing.

mspaint_MP42sDfko8
let’s start off with a visual demo, we got the red line which is the cameras path, point A and point B.
we also have point C which is the players head position, and we are trying to figure out the position of point D which is our final point that the camera will be positioned at.

we can get this point by projecting the vector AC onto the vector AB

AD = AC:Dot(AB.Unit)

that gives us the vector AD which we can then add to point A so

FinalPosition = A + (AB.Unit * AD)

and since roblox :Dot function returns us a scalar value (a number instead of a vector) we will need to combine AB.Unit and AD
also, might wanna clamp it so it doesn’t exceed the points :slight_smile:

FinalPos = A + AB.Unit * math.clamp(AD, 0, AB.Magnitude)

Camera.rbxl (18.7 KB)
here’s a placefile i quickly mocked up, it has a local script in StarterPlayerScripts with a simple renderstep function with the above code (slightly modified)

hope it helps, message me here or on twitter if you got any questions!

8 Likes

NeonD00m is right, I need this exactly.

2 Likes

There we go! This is the solution I needed :slight_smile:
Thank you for helping!
By the way, I don’t know what happened on twitter, I will check it.

5 Likes