#Camera stuff

1 messages · Page 1 of 1 (latest)

vital fiber
#

so i'm trying to make the camera tilt downwards when the player runs with a tween. i've tried to just simply tilt it downwards but it uses *= and happens every frame. if i store the cframe and do it that way, the player can't move their camera and i can't find a good workaround

vital fiber
# vital fiber so i'm trying to make the camera tilt downwards when the player runs with a twee...

here's the code that ran every renderstepped while the player is running:

    local rotateCFrame = if CameraHandler.GetRotationInput(deltaTime) ~= Vector2.zero then CameraHandler.GetCameraRotationCFrame(deltaTime) else CFrame.identity
    --[[ i stole the math from playermodule and getrotationinput is
    just camerainput (from playermodule)'s getRotation()]]
    task.defer(function()
        CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
            CurrentCFrame,
            CFrame.Angles(math.rad(PrivateSettings.AngleRotate), 0, 0),
            CurrentCameraVelocity,
            PrivateSettings.AngleSpeed,
            nil,
            deltaTime
        )
        Camera.CFrame = (OriginalCFrame.Rotation:ToWorldSpace(CurrentCFrame) + Camera.CFrame.Position) * rotateCFrame
    end)
rugged magnet
# vital fiber here's the code that ran every renderstepped while the player is running: ``` ...

first off, when making code like this, you can set it to highlight lua syntax:
```lua
your code here
```

Looks like this:

local rotateCFrame = if CameraHandler.GetRotationInput(deltaTime) ~= Vector2.zero then CameraHandler.GetCameraRotationCFrame(deltaTime) else CFrame.identity
--[[ i stole the math from playermodule and getrotationinput is
just camerainput (from playermodule)'s getRotation()]]
task.defer(function()
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(PrivateSettings.AngleRotate), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    Camera.CFrame = (OriginalCFrame.Rotation:ToWorldSpace(CurrentCFrame) + Camera.CFrame.Position) * rotateCFrame
end)

second, in line 1 you dont have an end to close the if statements, which you need

local rotateCFrame
if CameraHandler.GetRotationInput(deltaTime) ~= Vector2.zero then
    rotateCFrame = CameraHandler.GetCameraRotationCFrame(deltaTime)
else
    rotateCFrame = CFrame.identity
end
--[[ i stole the math from playermodule and getrotationinput is
just camerainput (from playermodule)'s getRotation()]]
task.defer(function()
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(PrivateSettings.AngleRotate), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    Camera.CFrame = (OriginalCFrame.Rotation:ToWorldSpace(CurrentCFrame) + Camera.CFrame.Position) * rotateCFrame
end)

You also should include the rest of the code. Makes it easier to actually understand what might go wrong

vital fiber
#

lemme yoink some more of the code from it

rugged magnet
#

well you probably missed them putting an "end" at the end tho

vital fiber
#

weird..

#

here's the speed up code

-- This function is called when the player wishes to start sprinting.
function Sprinter.Start()
    Sprinter.IsActive = true
    CurrentAngleGoal = PrivateSettings.AngleRotate
    OriginalCFrame = Camera.CFrame
    
    local TotalTime = 0
    local PreviousMoveDirection = Humanoid.MoveDirection
    Connections.SprintAcceleration = RunService.Heartbeat:Connect(function(deltaTime: number)
        TotalTime += deltaTime
        
        local MoveDirection = RootPart.CFrame:VectorToObjectSpace(Humanoid.MoveDirection)

        local Forward = math.abs(math.clamp(MoveDirection.Z, -1, -0.001))

        if Forward <= 0.5 then
            Sprinter.Stop()
        end
        
        SpeedboostSpeed, SpeedboostVelocity = TweenService:SmoothDamp(
            SpeedboostSpeed, -- current
            0, -- goal
            SpeedboostVelocity, -- velocity (as a number)
            SpeedboostTime, -- time
            nil, -- max speed
            deltaTime
        )
        
        Humanoid.WalkSpeed = FunctionUtils.Math.accelerate(
            Humanoid.MoveDirection, -- the direction you wanna go
            PrivateSettings.SprintingSpeed - StarterPlayer.CharacterWalkSpeed, -- how fast you wanna go (in my case i don't wanna start from 0 so
            -- i'm using a bit of a hacky workaround: still start from 0 but instead subtract the original speed from the wanted speed and then add it
            -- to the walkspeed, not the function.)
            PrivateSettings.AccelerationSpeed, -- the speed. not in any units i know of
            MoveDirection / PrivateSettings.SpeedLossOnRotation, -- the current velocity. idek what how this works but if it ain't broke don't fix it.
            TotalTime -- the amount of time elapsed since u wanted to start accelerating.
        ).Magnitude + StarterPlayer.CharacterWalkSpeed + SpeedboostSpeed
    end)
end
#

i can't think of what other code you would need to help out so uhh

#

also lemme explain some of the variables

#

currentanglegoal should have been used by the camera stuff

echo hatchBOT
#

studio** You are now Level 2! **studio

vital fiber
#

originalcframe is used by the camera function to store the original camera cframe so i don't mess up the rotation

rugged magnet
#

I see an issue

vital fiber
#

?

rugged magnet
#

i see an issue in the code

vital fiber
#

what is the issue in the code

rugged magnet
#

I am typing it

#

wait nvm. i havent eaten dinner yet. I just didnt see you put math.abs there my baddd. I am wondering why you're only checking movedirection.Z. can you only travel one direction?

vital fiber
#

like if ur holding W but i did it this way so it works for other devices

rugged magnet
#

Is this your own code? cause docs say Humanoid.MoveDirection is world space. meaning it doesnt tell you wether you're holding W or not. It tells you wether or nor youre moving towards -Z or not

vital fiber
#

it does though since i didn't use humanoid.movedirection in world space

#

i used rootpart.cframe:vectortoobjectspace(humanoid.movedirection)

rugged magnet
#

wow i dont know how i didnt see that

#

Ill just come back once ive had food

vital fiber
#

yeah...

#

okay

hollow tundra
#

hi

rugged magnet
#

im not sure what your code does at CameraHandler.GetRoationInput, GetCameraRotationCFrame.
but if you've debugged those and made sure they work, then it could perhaps be either that you use RenderStepped (which is old, the new one is PreRender)
you could also alternatively do RunService:BindToRenderStep("Sprint Camera", 201, yourFunction)
Inputs are handled at priority 100. Normal camera is done at 200. So if you do your step at priority 201 then that happens after the normal camera is already updated
Try this. And if not, maybe try and debug the code you use for tilting?

#

@vital fiber

rugged magnet
#

Keep me posted

vital fiber
# rugged magnet Keep me posted

hello i haven't had access to my pc for a while but i've changed the code a little bit and i need to explain what i did with the codebase:
each "mechanic" for the movement system (i'm making a movement system) is stored in a module which has a bunch of functions and boolean values that tell you what functions are meant to be ran (the camera code is meant to go off when the mechanic module's isactive property is on true)
so what i did was i put a "bindname" and a "priority" property in all of those and used those in my movement system handler (the thing that gets all the modules and runs them) and bound all of them to renderstepped as i activate it and then i have a function that handles when the code should be run. i'll send some code snippets here

#
function Handler.UpdateBinds(WillBeBound: boolean)
    Mechanics = Movement:WaitForChild("Mechanics"):GetChildren()
    
    for _, Mechanic in Mechanics do
        local RequiredMechanic: RequiredMovement.Mechanic = require(Mechanic)
        
        local function BoundToPreRender(delta: number)
            RequiredMechanic = require(Mechanic)

            if not RequiredMechanic then
                return
            end

            if not RequiredMechanic.IsActive then
                return
            end

            if not RequiredMechanic.CanActivate then
                return
            end

            RequiredMechanic.Camera(delta)
        end
        
        if not RequiredMechanic.BindName then
            return
        end
        
        if not RequiredMechanic.Priority then
            return
        end
        
        if WillBeBound then
            RunService:BindToRenderStep(RequiredMechanic.BindName, RequiredMechanic.Priority, BoundToPreRender)
        else
            RunService:UnbindFromRenderStep(RequiredMechanic.BindName)
        end
    end
end
vital fiber
#

and i still have the same problem: it doesn't work as intended at all

#

lemme get a clip of it in a second

echo hatchBOT
#

studio** You are now Level 4! **studio

vital fiber
vital fiber
#
-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
end
``` this is the code that ran every frame and it caused that bug 
currentcframe is a feedback value for tweenservice:smoothdamp() and so is currentcameravelocity (i'm pretty sure i'm using it right)
currentanglegoal is a variable that can be changed in runtime and is equal to 15 when the player wants to activate the sprint mechanic (activates when u press W)
all the other stuff should be self explanatory but if something's confusing lmk
rugged magnet
vital fiber
rugged magnet
#

Did you remember to stop the recording or did you just press the stop testing button? that can break the video sometimes

#

Website

#

its what RSC recommends to use for all video you send here

vital fiber
rugged magnet
#

it loaded in now nvm. real slow

#

Okay looks like ur code works halfway. ill take a look

rugged magnet
vital fiber
#

It's being done in the Roblox internal code

#

Ohh wait I think ik why

#

It might be that ur looking down too low

rugged magnet
#

But yeah alot to unpack here tho. I see you call CurrentCFrame, CurrentAngleGoal, CurrentCameraVelocity, and stuff, but i dont see where all these others are used aswell. So first thought is you put the angle wrong. Can you debug by adding, withing sprinter.camera, just add a

-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    print("CFrame before: ", CurrentCFrame)
    print("Target CFrame: ", CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0))
    
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    print("CFrame after: ", CurrentCFrame)
    Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
end
``` then you can see if the angle is what you expect
It also looks like you're having your smoothdamp use only a rotational cframe for target. I imagine CFrame.Angles have a position of (0,0,0)
So its trying to constantly smooth between current cframe angle, and target angle, but also current position and also target position. Hard to know without knowing your system, but this will print out clues
rugged magnet
vital fiber
#

Tysm man I'll get back to you hopefully

#

Also I just realised I type annotated deltatime as a boolean 😭

rugged magnet
#

luckily thats mostly for editing. Luau dont care too much as long as everything works

#

but yeah are you doing anything custom camera? cus it seems if you do that you're using some of the base camera functions and modifying

an alternative is just let roblox do its calculation, and you apply a simple rotation down after at render priotity > 200

#

a simple smoothdamp yeah, cus then the camera cframe will be the normal roblox one everytime and you apply the offset after

#

But alot of unknown variables and you're sending disconnected scripts so its impossible to see how anything works. Big chance what you're sending isnt close to being the culprit

#

usually happens when people want help but are afraid of their hard work getting stolen

#

I must bed now. catch ya tomorrow

vital fiber
vital fiber
vital fiber
rugged magnet
# vital fiber Then I'm not sure at all what to show you

did you try debugging as i showed you? also i did name several variables i did not know what were and would like to know :/
Maybe youre just skipping reading them accidentally. also you didnt say, did you also try debugging what i said in regards to the location data of CFrame.Angles youre using?

vital fiber
rugged magnet
vital fiber
# rugged magnet this edit of your function. here i named all the variables which could be create...

hello so i've lowkey forgotten to do this mb
currentcframe and currentcameravelocity are just values fed back to that function, they aren't changed aside from when i reset them the player stops sprinting (i can send a find all thingy for proof) and currentanglegoal is simply either -15 or 0. i checked it wasn't changing (i printed out the target cframe only and it was the same each time so it's not that), and rn i have it set up so ui elements show the before and after (with prints)
i can send you the output or send a clip of the ui elements, whichever you prefer since i honestly have no idea what is going on. i've tried to debug it but idk what i'm doing. i know what the problem is but idk how to fix it (the problem is that the camera cframe isn't resetting, even after i use bindtorenderstepped with a priority of 200)

#

if u need me to tell u anything lmk

vital fiber
vital fiber
# vital fiber proof that currentanglegoal is either -15 or 0, the cframe is the target cframe ...
-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: number)
    Player.PlayerGui.test.before.Text = "before"..tostring(CurrentCFrame)
    --print(CurrentCFrame)
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    print(CurrentAngleGoal, CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0))
    Player.PlayerGui.test.after.Text = "after"..tostring(CurrentCFrame)
    --print(CurrentCFrame)
    Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
end

code used here

rugged magnet
vital fiber
#

i got off studio i might hop back on later but yk

rugged magnet
#

200

#

more than 200*

#

idk if itll help, but

rugged magnet
#

Okay good

vital fiber
#

i've sent the code of the way i handled it in here

#

there is maybe like a slight delay due to checks and stuff but i think that shouldn't matter

rugged magnet
# rugged magnet But yeah alot to unpack here tho. I see you call CurrentCFrame, CurrentAngleGoal...

But yeah if you could show me what this prints when you sprint thatd might help

-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    print("CFrame before: ", CurrentCFrame.Position, CurrentCFrame.Rotation)
    print("Target CFrame: ", CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0).Position, CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0).Rotation)
    
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    print("CFrame after: ", CurrentCFrame.Position, CurrentCFrame.Rotation)
    Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
    print("CameraFrame: ", Camera.CFrame.Position, Camera.CFrame.Rotation)
end
``` i edited it slightly now to not get the matrix representation of the cframe
vital fiber
#

okay i'll do that tomrrow since i'm honestly a bit tired

rugged magnet
#

yup thats fine. 11pm for me so

vital fiber
#

also i didn't notice any position stuff i remember sending a clip of what would happen so

#

gn

echo hatchBOT
#

studio** You are now Level 5! **studio

rugged magnet
#

its still smart to include everything when debugging if you dont know whats wrong

vital fiber
#

Yeah fair enough

rugged magnet
#

but yeah if all else fails, id think itd be easier to just do custom camera

vital fiber
#

like i don't feel like doing all that math ngl

#

ignore the activate windows

#

btw camerafter and camerabefore are the stuff that is going to be multiplied by cameraframe now so it's a bit weird that math

rugged magnet
#

Its still using the rotation matrix my b, let me be really specific and maybe roblox understands this time...

-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    print("CFrame before: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    print("Target CFrame: ", CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0).Position, CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0):ToEulerAngles())
    
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    print("CFrame after: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    print("CameraFrame before: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
    Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
    print("CameraFrame after: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
end
#

@vital fiber Its just hard for me to understand whats happening with the rotation matrix, but euler angles should probably show whats going on in a way i can see

vital fiber
#

lemme get back onto studio and try that out

rugged magnet
#

🤞

vital fiber
rugged magnet
#

hmm i think i know whats going on??

vital fiber
#

lmk please

rugged magnet
#

hahah aaah i see something wack
so since youre doing current cframe into local space for camera, that means if the camera is point the same way meaning it, relative to the camera, has almost no angle down

just try this:

-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    --print("CFrame before: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    --print("Target CFrame: ", CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0).Position, CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0):ToEulerAngles())
    
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    --print("CFrame after: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    print("CameraFrame before: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
    --Camera.CFrame = Camera.CFrame:ToWorldSpace(CurrentCFrame)
    --print("CameraFrame after: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
end

so i can read and see

And this is something i think will work:

-- this function is called every renderstepped (the function from runservice at whatever priority you did) when you are sprinting
function Sprinter.Camera(deltaTime: boolean)
    print("CFrame before: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    print("Target CFrame: ", CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0).Position, CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0):ToEulerAngles())
    
    CurrentCFrame, CurrentCameraVelocity = TweenService:SmoothDamp(
        CurrentCFrame,
        CFrame.Angles(math.rad(CurrentAngleGoal), 0, 0),
        CurrentCameraVelocity,
        PrivateSettings.AngleSpeed,
        nil,
        deltaTime
    )
    print("CFrame after: ", CurrentCFrame.Position, CurrentCFrame:ToEulerAngles())
    print("CameraFrame before: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
    Camera.CFrame = Camera.CFrame*CurrentCFrame
    print("CameraFrame after: ", Camera.CFrame.Position, Camera.CFrame:ToEulerAngles())
end
vital fiber
#

i'll try it out but

rugged magnet
#

Yeah but now we're debugging with cool prints

#

very specific ones

vital fiber
#

also btw when u do the , it does a space so when u do "blah blah blah: ", (something) it prints as "blah blah blah: (something)

rugged magnet
#

Yup

vital fiber
#

top one prints this

rugged magnet
#

Yeah not changing much, good

#

just wondering how bottom one will be affected

vital fiber
#

i noticed the same issue: it forces me to look in the same direction as before

#

so as far as i can tell nothing's different with simply using *

rugged magnet
#

Well then im confident in saying its somewhere else and not within this function that the error is happening

vital fiber
#

hmm okay

#

so then my guess is i coded in the bindtorenderstepped thingy wrong

#

i'll debug it and when i'm unsure i'll send the code to you

rugged magnet
#

When you say send the code, do you mean try and find another code snippet and send that?

#

Cause the best would just be to send everything related to the camera script. What the sprinting module does, what the camera module does etc

#

So far just feels like i been given a puzzle which doesnt contain the solution

#

Is it out of fear of having your work stolen?

vital fiber
#

if they REALLY wanted to they could easily decomp the game

#

i'll send you some scripts then

vital fiber
# vital fiber

a module script (i use a module loader, it always calls the "start" function

#

this is a module (loaded with module loader) used for the ) _sprint module (the module that contains the Sprinter.Camera( in it

#

also i'll sned the full _sprint module for you for an example of how it works in full

#

lmk if u need me to explain anything or debug something or anything like that

rugged magnet
#

Yeah thank you. It will be some time cause I have to read through most of it. So dont keep up for my sake

vital fiber
#

yeah fair enough

#

tysm for helping!

rugged magnet
#

ofc, i also actually learn by helping so

vital fiber
#

yeah

#

also just a quick question: how did u get that scripter role? i'm just curious (i might not go out of my way to get it, depends if it's annoying to get or not)

rugged magnet
# vital fiber also just a quick question: how did u get that scripter role? i'm just curious (...

I just applied with 4 scripts within #📃︱ranking-tickets . First you open a ticket, then you get a page up. They want at least 4 scripts, and then they will judge you based on how well your script is on several factors.
Stuff like scaleability, readability, and wether its efficient or not
Also good to have proper failsafes ig. I got a lot of feedback of what was bad and then got my rank
If you dont like to hear negative stuff about your scripts (cause many on this server can sound negative) then now you know
I only got it cause someone said I wouldnt be able to get S2 (the 2 arrows) :p

echo hatchBOT
#

studio** You are now Level 6! **studio

vital fiber
#

i'll probably do that eventually but nrn

rugged magnet
#

There is some sort of gimbal lock going on it looks like. Now just trying to figure out why it gets set like that in the first place

#

If you look at the prints, both the X rotation, and Z rotation are a perfect 90 degrees
So a gimbal lock is def happening and would explain the one direction
now to actually figure out why its locked

vital fiber
#

isn't gimbal lock like when u rotate an axis the other axis gets rotate too

rugged magnet
#

so each frame you're just continually dragging the camera to look downwards slightly. Then it hits 90 degrees and reaches gimbal lock
One potential fix is to set the camera cframe back to its original after rendering is over (so like heartbeat)
Might be weird and not work

Another is to keep it at a set tilt, but then the players up/down tilt is locked. But forcing them to tilt down makes it seem you want control over their vision for something so you gotta decide on what you know

another would be to update all the cameras to not use delta in calculating camera, but rather use total rotation. Might have issues tho too and would be a little hassle

#

The base roblox camera is never calculating the current camera frame basically, it just is updating the camera based on inputs current frame
Meaning your script makes it continually look down. Potential bit more complex fix: Create your own x rotation when sprinter starts based on current camera frame.
Every frame you change this x rotation by mousemovement.
Then you use this x rotation and add your offset rotation. Clamp it
this mixed with the current cameras normal cframe X and Z rotation (kinda like CFrame.Angles(customCrotation, Camera.CFrame.Rotation.Y, Camera.CFrame.Rotation.Z))
UserInputService isnt that complicated that you wont be able to do it

vital fiber
rugged magnet
#

Yup i just checked the scripts so

vital fiber
#

but also mousemovement isn't the best approach i wanna add mobile support

rugged magnet
#

maybe we can steal from the base roblox cam then

vital fiber
#

i mean i could use that camerainput function i think?

#

it returns a vector2 iirc

rugged magnet
#

would you use pinching in ur game?

vital fiber
#

pinching?

#

like on mobile?

rugged magnet
#

like for zooming in out on a phone you pinch yea

vital fiber
#

i don't think so?

#

i mean maybe for a zoom out feature

#

as in like the camera does over the shoulder view

rugged magnet
#

cause if u dont it might be simple to add

#

but if 2 fingers are on (excluding thumbstick) it might be harder ukno

vital fiber
#

I thought Roblox would handle that

#

Like I'm quite literally requiring the active player module and doing it like that

#

That's how I tried before but that didn't work but now I know more/a better way to do it, it should work better

rugged magnet
# vital fiber I thought Roblox would handle that

It does in the camera script directly. If you decide you wanna try it with touch inputs, this should be all you need as a starting point. Just connecting those to UIS ofc

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local function isInDynamicThumbstickArea(pos: Vector3): boolean
    local playerGui = player:FindFirstChildOfClass("PlayerGui")
    local touchGui = playerGui and playerGui:FindFirstChild("TouchGui")
    local touchFrame = touchGui and touchGui:FindFirstChild("TouchControlFrame")
    local thumbstickFrame = touchFrame and touchFrame:FindFirstChild("DynamicThumbstickFrame")

    if not thumbstickFrame then
        return false
    end

    if not touchGui.Enabled then
        return false
    end

    local posTopLeft = thumbstickFrame.AbsolutePosition
    local posBottomRight = posTopLeft + thumbstickFrame.AbsoluteSize

    return
        pos.X >= posTopLeft.X and
        pos.Y >= posTopLeft.Y and
        pos.X <= posBottomRight.X and
        pos.Y <= posBottomRight.Y
end

local touchBegan, touchChanged, touchEnded, resetTouchState do
    -- Use TouchPan & TouchPinch when they work in the Studio emulator

    local touches: {[InputObject]: boolean?} = {} -- {[InputObject] = sunk}
    local dynamicThumbstickInput: InputObject? -- Special-cased 
    local lastPinchDiameter: number?
    local touchState = {
        Move = Vector2.new(),
    }
    function touchBegan(input: InputObject, sunk: boolean)
        assert(input.UserInputType == Enum.UserInputType.Touch)
        assert(input.UserInputState == Enum.UserInputState.Begin)

        if dynamicThumbstickInput == nil and isInDynamicThumbstickArea(input.Position) and not sunk then
            -- any finger down starting in the dynamic thumbstick area should always be
            -- ignored for camera purposes. these must be handled specially from all other
            -- inputs, as the DT does not sink inputs by itself
            dynamicThumbstickInput = input
            return
        end

        -- register the finger
        touches[input] = sunk
    end

    function touchEnded(input: InputObject, sunk: boolean)
        assert(input.UserInputType == Enum.UserInputType.Touch)
        assert(input.UserInputState == Enum.UserInputState.End)

        -- reset the DT input
        if input == dynamicThumbstickInput then
            dynamicThumbstickInput = nil
        end

        -- unregister input
        touches[input] = nil
    end

    function touchChanged(input, sunk)
        assert(input.UserInputType == Enum.UserInputType.Touch)
        assert(input.UserInputState == Enum.UserInputState.Change)

        -- ignore movement from the DT finger
        if input == dynamicThumbstickInput then
            return
        end

        -- collect unsunk touches
        local unsunkTouches = {}
        for touch, sunk in pairs(touches) do
            if not sunk then
                table.insert(unsunkTouches, touch)
            end
        end

        -- 1 finger: pan
        if #unsunkTouches == 1 then
            if touches[input] == false then
                local delta = input.Delta
                touchState.Move += Vector2.new(delta.X, delta.Y) -- total touch pan movement (reset at end of frame)
            end
        end
    end

    function resetTouchState()
        touches = {}
        dynamicThumbstickInput = nil
    end
end
#

took and cleaned up from the base cameras

vital fiber
#

Okay

rugged magnet
#

Touch does seem funky tho. But yeah this uses how roblox ignores the thumbstick