The script does the following:
We start at 0 degrees rotation (i.e: character's y-axis rotation is at 0 at the beginning)
1) Player on mobile device
2) Player dragging their finger (touch) to the right
3) While player is doing that, add 1 degree rotations as long as player's character's y rotation is not >= 180 degrees
Scroll down to [HERE] to see the script in question. Also, all scripts can be tested in studio (they are local scripts). Can I get any input as to what's happening here?
This is what a 180 degree rotation looks like in a test:
https://i.imgur.com/44LTv75.png
This is what that script looks like:
wait(.5) local userInputService = game:GetService("UserInputService") local localPlayer = game.Players.LocalPlayer localPlayer.Character.Humanoid.WalkSpeed = 0 --// START: wait(10) localPlayer.Character:SetPrimaryPartCFrame(localPlayer.Character.HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(180), 0)) print("180 degrees rotation applied.")
[HERE] Now this is the actual script that leads to a similar visual effect relatively, but why??? It should go to 180 degrees and then not be able to rotate anymore.
https://i.imgur.com/MlJC71x.png
Local script:
wait(.5) local userInputService = game:GetService("UserInputService") local localPlayer = game.Players.LocalPlayer localPlayer.Character.Humanoid.WalkSpeed = 0 --// START: local touching = false userInputService.TouchStarted:Connect(function(touch) touching = true end) userInputService.TouchEnded:Connect(function(touch) touching = false end) local yRotation = 0 userInputService.TouchMoved:Connect(function(touch) local originalXPos = touch.Position.X - touch.Delta.X local newXPos = touch.Position.X if (touching) then if (newXPos > originalXPos) then -- If we're dragging our touch gesture to the right, do this: if (yRotation < 180) then -- If we're not at 180 degrees yet, allow the rotations to keep incrementing. localPlayer.Character:SetPrimaryPartCFrame(localPlayer.Character.HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(yRotation), 0)) yRotation = yRotation + 1 -- Increment rotation by 1 degree. print(yRotation) -- Output. end else -- Just do nothing if we're dragging to the left. end end end)
At first glance, there's a few things that should be changed. Firstly, your main issue is with the way in which you're setting the angle. Matrix multiplication can be a pretty tricky concept to grasp, so to be concise I'll explain what is wrong in simpler (and not necessarily wrong, just less precise) terms.
localPlayer.Character:SetPrimaryPartCFrame(localPlayer.Character.HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(yRotation), 0))
Here you are attempting to set the angle to yRotation, but instead you are incrementing it by yRotation. To fix this, you'll want to strip the current orientation from the CFrame and then reconstruct it with your desired angle. It's pretty easy to do this, as there is a CFrame.new constructor that accepts one vector, and creates a CFrame with that as the position and no orientation:
CFrame.new(localPlayer.Character.HumanoidRootPart.CFrame.Position) * CFrame.Angles(0, math.rad(yRotation), 0)
The other thing I noticed is that you're using SetPrimaryPartCFrame. Ideally, you should just be setting the CFrame of the HumanoidRootPart directly here. SetPrimaryPartCFrame tends to have a lot of floating point precision problems, so it is better to not use it when you don't have to. In fact, you never really need to use it, because a better solution would be to attach all parts of an assembly to one base part with a Motor6D and then set the CFrame of that base part. Though, sometimes it isn't worth the effort when your code doesn't rely on it.