Well, try copying how meguy1 did it with Gravity Shift.
Mygame43 “cheated” with Gravity Shift in that the “down” lookVector always points toward gravity. So no real change to the camera code.
I’d rather have whatever’s possible that can be done, so I can actually use a dynamic camera for my game.
If you just want to be able to look in all 360 degrees, try setting the downVector to always be 90 degrees below the lookVector. It’s an ugly fix but it will absolutely prevent the camera from stopping when it hits the bottom or top of the possible camera angles.
You should quickly realize why the camera is limited like it is currently, when you do.
And just how would I go about doing that?
This topic should get you started in advanced CFrame math. I’m not willing to dive into the scripting it would take to create a 360DOF camera, especially not for free; there are lots of professionally made games which use such technology.
Roblox could implement quaternions under the hood. It would make animating joints probably way easier.
Is that me?
Yessiree!
fascinating!!!
Wait, just a question.
Is there any way it’d be possible to have this same effect, but on terrain ? If there is, please let me know!
Unfortunately with the way I approached the problem terrain isn’t really a possibility.
In most cases I can change the fake humanoid’s fake world to rotate around the player, but with terrain that’s not possible since you can’t rotate it. I can’t make a “fake” terrain out of bricks either because not only would that be inefficient but also we don’t have access to that information atm.
Mind explaining how it works?
I am looking forward to using stuff like this!
I have made a working, turning camera for this character controller!
The way it works is, I played with the options of AlignOrientation
instances, and noticed their new AlignType
property. I played around with this a bit, and found a way to let the Y axis spin freely but keep the X and Z axis relative to the character, using Enum.AlignType.Parallel
. After this, I just made sure the part did not rotate too much by setting it’s RotVelocity
to 0,0,0
every heartbeat and turning on RigidityEnabled
, which is not exactly efficient, and the part rotates minimally, but it works.
I have been playing around with different types of control manipulation for a ControlScript
, but all of the methods I have tried simply don’t play nice with the angles. I think it just has something to do with how the humanoid interprets the Humanoid:Move
method, since it obviously wouldn’t be walking on ceilings and stuff in any normal Roblox game.
This is the .rbxl file with the modified camera changes. Feel free to explore and test the camera, or modify the custom-made CameraScript if you want.
playgroundCamera.rbxl (91.6 KB)
Since I haven’t figured out how to do the controls, moving around can get pretty wonky. I guess, be careful?
Hopefully, this gives the creator of this character controller some out-of-the-box solutions for the next camera or control script he/she implements!
So I reworked my CameraScript to integrate the character controller instead of using an independent part with AlignPosition and AlignOrientation. This required some modifying of the controller’s script to hold a little extra information and place some of its data in some ObjectValue
s, namely the lastHit
and fakeLastHit
values. I made sure to stay organized by commenting the modifications starting in pkg
and ending with an identifier.
pkg LastPart
I created a relationship between one part’s cframe in fakeWorld
and the other one in the real workspace using this formula:
(part.CFrame - part.Position) * (fakePart.CFrame - fakePart.Position):Inverse()
and I used this as the root angle for the camera. Usually, the lastHit
part and its fake counterpart is used, and it falls back to the HumanoidRootPart if the lastHit
part doesn’t exist. This is kept track of using ObjectValues
parented to the controller.
I figured out the ControlScript as well, so have fun moving freely between platforms and not getting frustrated because you’re at some weird angle.
I listed some pros and cons compared to the file in my last post:
Pros:
- The camera now rotates with parts you are standing on that are spinning on their Y-axis
- The controls synchronize perfectly with the camera’s movement, which means no more frustration with moving on spinning platforms.
- No extra part / aligning overhead, if that matters at all
Cons/New Bugs:
- the camera now spins by 180 degrees whenever you switch between a slope pointing towards the X axis and one pointing towards the Z axis and vice versa, but only while upside-down.
– This was what my last implementation was able to fix, by being independent from the character controllers. - This causes the camera to spin on meshes while upside-down as well.
- There is still a camera spin whenever there is a transition between an object staying still and an object spinning on its Y-axis, I think I only saw this while standing upside-down as well.
pkg CameraOffset (doesn’t work, addressing a bug)
I haven’t figured out a fix to this upside-down spin bug, but it will probably have to deal with more CFrame manipulation. I will have to understand how to detect when this spin happens though. I almost solved it inside the controller itself (with this package), but it only corrects itself when the character is completely upside-down.
Here is the playground file with the updated ControlScript:
playgroundCamera.rbxl (361.0 KB)
I have added a few keybinds for convenience, that being Tab for resetting movement and Left Ctrl for flipping gravity, which is a really fun feature by itself.
I also added just a few extra obstacles here and there to test out stuff, like stairs.
the long awaited for…
pkg CameraOffset
So I have fixed this upside-down bug, very proud of myself for this one. Mainly because I now know how to use cross product and dot product better. What I did was:
- I looked in the method for
controller.setPart
, as that is the relevant method - I took the
math.atan2
between the X and Z coordinates ofprivate.lastAxis
, - did the same for the current cross product,
- took the difference,
- made sure that the change in angle was never greater than pi.
- fired an event with this number as the parameter
- CameraScript’s
x
value changed accordingly I also copied this over to anextraRotation
variable so that the humanoid’s movement did not need to catch up with the camera
Whenever the event fired, the value passed in is added to the x
value in the CameraScript, and it makes transitions between slopes nearly seamless.
pkg rPartRot
I have also partially fixed the camera spin bug from rotating parts. It is dependent on the LookVector of the rPart, which means it would be hard to orient these parts correctly if they are asymmetrical, or if the part spins on it’s LookVector. This platform is an example:
Other than this, pkg rPartRot
also works when transitioning between two sets of rotating parts at the same time. This could be useful for obbies if you make the gravity independent of the rotating part when you jump through the setNormal
method.
My method of implementation for this was limited: it uses very similar functions as the code for pkg CameraOffset
. Expansion on this will be next on my to-do list.
Keep in mind that the trigger for this function is dependent on the fact that every rotating part is named “rPart,” just like the autoRotate
function that called it.
Controller Comments:
I annotated the controller quite a bit if you didn’t know how it works, albeit you probably still won’t know when you’ve read over it for 20 minutes straight. So, I’ll give the rundown of what happens in the playground file:
- The controller is instantiated with the character as the parameter.
- A fake, or
phys
,version of the character is created, which controls the physics of the real one. This is known as thephysCharacter
in the script.
– The physics are manipulated through an AlignOrientation
and AlignPosition
object, called forces
in the script, and the real character’s humanoid is placed in the PlatformStand
state.
- A
fake
version of the world is also created atWorldCenter
, which defaults to 5000 studs away in the X direction. This is the internal physics engine that determines the orientation of your character in the real world.
- Every frame, or when
autoRotate
is called:
-
getFilter
is called
– The controller gathers every object in the workspace.World
folder that intersects with a 10 stud length Region3
placed at the center of the character’s HumanoidRootPart
. This collection of objects is known as a filter
in the script.
-
castFeet
is called.
– This method casts a cylinder of rays below the character’s feet onto this filter
. These rays expose information about the land the character is directly standing on, such as normals, whether it’s complex geometry, etc.
- Based on the info gathered from
castFeet
:
- If there is a new part,
setPart
is called.
– This is the method that sets the cframe of your character relative to the world, and the “cframe of the world” relative to your physCharacter
in the fakeWorld.
-
updateFakeWorld
andupdateCharacter
are unconditionally called.
– updateFakeWorld
makes sure to acknowledge any parts that were picked up by the filter, and places any new ones in the fakeWorld
, and destroying any old ones.
-
updateCharacter
is called
– This sets the Attachment1
property’s CFrame of the AlignPosition
and AlignOrientation
that is applied to your character. It also makes the physCharacter
move in the same direction you are moving
Hopefully, this betters your understanding of what the controller does, along with the existing comments.
Here is the normal file:
playgroundCamera.rbxl (96.4 KB)
This is the debug file:
playgroundCamera.rbxl (106.2 KB)
I don’t understand how these files are different sizes… all I did was change two variables and move the spawn location…
Since it is now possible to walk on spheres and other nice things with good camera and character stability, it might be a cool idea to create some kind of game with planetary gravity mechanics.
Holy smokes dude this is absolutely amazing! I really appreciate that you put the time into making this all the better. Mad respect!
Thanks for the praise!
Honestly, I can see something big coming from this character controller if it gets optimized enough. It could be some big game in the future, or maybe it could inspire something in the Roblox development pipeline.
Even more honestly, it’s all thanks to you for creating this. I have never seen something like this ever on Roblox, and I just want to see someone use it in their game.
…
Speaking of, I realized I posted that playgroundCamera file in a sort of debug state. I was bit too excited… I will update the post to have that fixed, I guess along with the debug version if anyone is curious, like right now.
Hello! Wanted to ask about the possibility of making a Pathfinders off it. What I mean is that the play can be followed by a mob on a sphere and such.