Загрузка данных
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
--------------------------------------------------
-- SETTINGS
--------------------------------------------------
local FIRST_PERSON_FOV = 70
local THIRD_PERSON_FOV = 60
local CAMERA_HEIGHT = 1.45
local THIRD_PERSON_DISTANCE = 7
local THIRD_PERSON_HEIGHT = 2
local MOUSE_SENSITIVITY = 0.0025
local TOUCH_SENSITIVITY = 0.004
local CAMERA_SMOOTHNESS = 14
local MIN_PITCH = math.rad(-85)
local MAX_PITCH = math.rad(85)
local TOGGLE_KEY = Enum.KeyCode.F
--------------------------------------------------
-- VARIABLES
--------------------------------------------------
local character
local humanoid
local rootPart
local head
local camera
local firstPerson = true
local targetYaw = 0
local targetPitch = 0
local currentYaw = 0
local currentPitch = 0
local cameraTouch = false
local lastTouchPosition = Vector2.zero
local hiddenObjects = {}
--------------------------------------------------
-- CAMERA
--------------------------------------------------
local function getCamera()
camera = workspace.CurrentCamera
return camera
end
--------------------------------------------------
-- HIDE FIRST PERSON OBJECTS
--------------------------------------------------
local function hideFirstPersonObjects()
if not character then
return
end
hiddenObjects = {}
for _, object in ipairs(character:GetDescendants()) do
--------------------------------------------------
-- PARTS
--------------------------------------------------
if object:IsA("BasePart") then
-- Head
if object == head then
object.LocalTransparencyModifier = 1
table.insert(hiddenObjects, object)
-- Upper torso
elseif object.Name == "UpperTorso" then
object.LocalTransparencyModifier = 1
table.insert(hiddenObjects, object)
-- Accessories
elseif object:FindFirstAncestorOfClass("Accessory") then
object.LocalTransparencyModifier = 1
table.insert(hiddenObjects, object)
end
--------------------------------------------------
-- FACE / DECALS
--------------------------------------------------
elseif object:IsA("Decal") then
if head and object:IsDescendantOf(head) then
object.Transparency = 1
table.insert(hiddenObjects, object)
end
end
end
end
--------------------------------------------------
-- RESTORE CHARACTER
--------------------------------------------------
local function showCharacter()
if not character then
return
end
for _, object in ipairs(character:GetDescendants()) do
if object:IsA("BasePart") then
object.LocalTransparencyModifier = 0
elseif object:IsA("Decal") then
object.Transparency = 0
end
end
hiddenObjects = {}
end
--------------------------------------------------
-- SET CAMERA MODE
--------------------------------------------------
local function updateVisibility()
if firstPerson then
hideFirstPersonObjects()
else
showCharacter()
end
end
--------------------------------------------------
-- TOGGLE
--------------------------------------------------
local function toggleCamera()
firstPerson = not firstPerson
local cam = getCamera()
if not cam then
return
end
if firstPerson then
cam.CameraType = Enum.CameraType.Scriptable
cam.FieldOfView = FIRST_PERSON_FOV
if humanoid then
humanoid.AutoRotate = false
end
else
cam.CameraType = Enum.CameraType.Scriptable
cam.FieldOfView = THIRD_PERSON_FOV
if humanoid then
humanoid.AutoRotate = false
end
end
updateVisibility()
end
--------------------------------------------------
-- CHARACTER SETUP
--------------------------------------------------
local function setupCharacter(newCharacter)
character = newCharacter
humanoid = character:WaitForChild("Humanoid")
rootPart = character:WaitForChild("HumanoidRootPart")
head = character:WaitForChild("Head")
local cam = getCamera()
firstPerson = true
cam.CameraType = Enum.CameraType.Scriptable
cam.FieldOfView = FIRST_PERSON_FOV
humanoid.AutoRotate = false
local look = rootPart.CFrame.LookVector
targetYaw = math.atan2(
-look.X,
-look.Z
)
currentYaw = targetYaw
targetPitch = 0
currentPitch = 0
updateVisibility()
end
--------------------------------------------------
-- MOUSE
--------------------------------------------------
UserInputService.InputChanged:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
if not firstPerson then
return
end
if input.UserInputType == Enum.UserInputType.MouseMovement then
local delta = input.Delta
targetYaw -=
delta.X *
MOUSE_SENSITIVITY
targetPitch -=
delta.Y *
MOUSE_SENSITIVITY
targetPitch = math.clamp(
targetPitch,
MIN_PITCH,
MAX_PITCH
)
end
end)
--------------------------------------------------
-- MOBILE TOUCH START
--------------------------------------------------
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
if input.UserInputType == Enum.UserInputType.Touch then
local cam = getCamera()
if not cam then
return
end
local viewport = cam.ViewportSize
-- Right side of screen = camera
if input.Position.X >= viewport.X * 0.45 then
cameraTouch = true
lastTouchPosition = input.Position
end
end
end)
--------------------------------------------------
-- MOBILE TOUCH MOVE
--------------------------------------------------
UserInputService.InputChanged:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
if not firstPerson then
return
end
if input.UserInputType == Enum.UserInputType.Touch
and cameraTouch then
local position = input.Position
local delta =
position -
lastTouchPosition
lastTouchPosition = position
targetYaw -=
delta.X *
TOUCH_SENSITIVITY
targetPitch -=
delta.Y *
TOUCH_SENSITIVITY
targetPitch = math.clamp(
targetPitch,
MIN_PITCH,
MAX_PITCH
)
end
end)
--------------------------------------------------
-- MOBILE TOUCH END
--------------------------------------------------
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch then
cameraTouch = false
end
end)
--------------------------------------------------
-- MOBILE BUTTON
--------------------------------------------------
local function createMobileButton()
if not UserInputService.TouchEnabled then
return
end
local playerGui = player:WaitForChild("PlayerGui")
local old =
playerGui:FindFirstChild("CameraToggle")
if old then
old:Destroy()
end
local gui = Instance.new("ScreenGui")
gui.Name = "CameraToggle"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.Parent = playerGui
local button = Instance.new("TextButton")
button.Name = "Toggle"
button.Size = UDim2.fromOffset(45, 45)
button.Position = UDim2.fromOffset(20, 20)
button.BackgroundColor3 =
Color3.fromRGB(40, 40, 40)
button.BackgroundTransparency = 0.25
button.BorderSizePixel = 0
button.Text = "1"
button.TextColor3 =
Color3.new(1, 1, 1)
button.TextScaled = true
button.Parent = gui
local corner = Instance.new("UICorner")
corner.CornerRadius =
UDim.new(0, 12)
corner.Parent = button
button.Activated:Connect(function()
toggleCamera()
if firstPerson then
button.Text = "1"
else
button.Text = "3"
end
end)
end
--------------------------------------------------
-- KEYBOARD
--------------------------------------------------
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
if input.KeyCode == TOGGLE_KEY then
toggleCamera()
end
end)
--------------------------------------------------
-- CAMERA UPDATE
--------------------------------------------------
RunService:BindToRenderStep(
"MainFirstPersonCamera",
Enum.RenderPriority.Camera.Value + 1,
function(deltaTime)
if not character
or not humanoid
or not rootPart
or not head then
return
end
if humanoid.Health <= 0 then
return
end
local cam = getCamera()
if not cam then
return
end
cam.CameraType =
Enum.CameraType.Scriptable
--------------------------------------------------
-- SMOOTH ROTATION
--------------------------------------------------
local alpha =
math.clamp(
deltaTime * CAMERA_SMOOTHNESS,
0,
1
)
currentYaw +=
(targetYaw - currentYaw)
* alpha
currentPitch +=
(targetPitch - currentPitch)
* alpha
--------------------------------------------------
-- FIRST PERSON
--------------------------------------------------
if firstPerson then
--------------------------------------------------
-- CAMERA AT HEAD POSITION
--------------------------------------------------
local cameraPosition =
head.Position
local rotation =
CFrame.Angles(
0,
currentYaw,
0
)
*
CFrame.Angles(
currentPitch,
0,
0
)
cam.CFrame =
CFrame.new(cameraPosition)
*
rotation
cam.FieldOfView =
FIRST_PERSON_FOV
--------------------------------------------------
-- BODY ROTATES ONLY HORIZONTALLY
--------------------------------------------------
local look =
rotation.LookVector
local flatLook =
Vector3.new(
look.X,
0,
look.Z
)
if flatLook.Magnitude > 0 then
rootPart.CFrame =
CFrame.lookAt(
rootPart.Position,
rootPart.Position +
flatLook.Unit
)
end
--------------------------------------------------
-- THIRD PERSON
--------------------------------------------------
else
local rotation =
CFrame.Angles(
0,
currentYaw,
0
)
*
CFrame.Angles(
currentPitch,
0,
0
)
local direction =
rotation.LookVector
local position =
rootPart.Position
- direction * THIRD_PERSON_DISTANCE
+ Vector3.new(
0,
THIRD_PERSON_HEIGHT,
0
)
cam.CFrame =
CFrame.lookAt(
position,
rootPart.Position +
Vector3.new(0, 1.5, 0)
)
cam.FieldOfView =
THIRD_PERSON_FOV
end
end
)
--------------------------------------------------
-- START
--------------------------------------------------
if player.Character then
setupCharacter(player.Character)
end
player.CharacterAdded:Connect(function(newCharacter)
task.wait(0.1)
setupCharacter(newCharacter)
end)
createMobileButton()