#Camera stuff
1 messages · Page 1 of 1 (latest)
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)
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
oh thanks for that
i remember seeing on a roblox learn video about smoothdamp: the person put what i put instead of doing it the way u did it
lemme yoink some more of the code from it
well you probably missed them putting an "end" at the end tho
i remember the person there didn't use an end either
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
** You are now Level 2! **
originalcframe is used by the camera function to store the original camera cframe so i don't mess up the rotation
I see an issue
?
i see an issue in the code
what is the issue in the code
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?
yeah u can only run forward
like if ur holding W but i did it this way so it works for other devices
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
i did yoink the idea from a video but the actual code is mine.
it does though since i didn't use humanoid.movedirection in world space
i used rootpart.cframe:vectortoobjectspace(humanoid.movedirection)
hi
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
alright tysm
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
this is the thing that binds the mechanic's Camera function to renderstepped
and i still have the same problem: it doesn't work as intended at all
lemme get a clip of it in a second
** You are now Level 4! **
here's a clip of what happens (it forces me to look in a direction)
i also got the clamp error thingy if u check the output. i've seen that before in other games but idk what it actually means
-- 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
Upload to streamable. This isnt playing for me
Is it a website or an app
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
Oh I just cropped the video length that's probs why
it loaded in now nvm. real slow
Okay looks like ur code works halfway. ill take a look
Just means you set the #3 argument lower than #2 argument. Which isnt good
yeah but I didn't use clamp
It's being done in the Roblox internal code
Ohh wait I think ik why
It might be that ur looking down too low
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
ill look at the line and see whats being fed to it then
Tysm man I'll get back to you hopefully
Also I just realised I type annotated deltatime as a boolean 😭
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
No I'm using the normal one also I'm doing what you said I'm applying a rotate and playing that function at 200 priority with bindtorenderstepped
Then I'm not sure at all what to show you
Since I edited the code to not try to use the Roblox scripts + as far as I can tell it's just returning a vector2 it should still run while the Roblox system is activated (which it is)
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?
Mb if I didn't answer any questions if u have lmk again also I don't remember ur showing the debugging? I could be wrong but you didn't mention how to debug
this edit of your function. here i named all the variables which could be created and updated elsewhere without me knowing, and showed you a debug you could do
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
proof that currentanglegoal is either -15 or 0, the cframe is the target cframe you showed the thing for previously (here it's 15 but the bindtorenderstepped calls stop when i set it to 0 so)
-- 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
Where do you first set the CurrentCFrame when you start sprinting? Can i see the code where you do CurrentCFrame = something? cus at first its probably nil right
no i keep it as cframe.identity
i got off studio i might hop back on later but yk
But yeah ive recommended setting bindtorenderstepped with a priority of +200
200
more than 200*
idk if itll help, but
i have done that though
Okay good
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
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
okay i'll do that tomrrow since i'm honestly a bit tired
yup thats fine. 11pm for me so
also i didn't notice any position stuff i remember sending a clip of what would happen so
gn
** You are now Level 5! **
its still smart to include everything when debugging if you dont know whats wrong
Yeah fair enough
but yeah if all else fails, id think itd be easier to just do custom camera
if i'm gonna be honest i kinda wanna do a custom camera but mobile support would be SO annoying to add
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
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
okay
lemme get back onto studio and try that out
🤞
hmm i think i know whats going on??
lmk please
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
i tried doing simple * and i got the same problem iirc
i'll try it out but
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)
Yup
top one prints this
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 *
Well then im confident in saying its somewhere else and not within this function that the error is happening
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
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?
yeah
not really i don't care too? much if ppl see the code i feel like
if they REALLY wanted to they could easily decomp the game
i'll send you some scripts then
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
Yeah thank you. It will be some time cause I have to read through most of it. So dont keep up for my sake
ofc, i also actually learn by helping so
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)
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
okay tysm
** You are now Level 6! **
i'll probably do that eventually but nrn
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
isn't gimbal lock like when u rotate an axis the other axis gets rotate too
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
the way i thought it would work is like the camera would do it's thing, and then i could apply an incrementing tilt
oh.
Yup i just checked the scripts so
but also mousemovement isn't the best approach i wanna add mobile support
maybe we can steal from the base roblox cam then
would you use pinching in ur game?
like for zooming in out on a phone you pinch yea
i don't think so?
i mean maybe for a zoom out feature
as in like the camera does over the shoulder view
cause if u dont it might be simple to add
but if 2 fingers are on (excluding thumbstick) it might be harder ukno
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
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
Okay
Touch does seem funky tho. But yeah this uses how roblox ignores the thumbstick