Phantom forces Script | THIRD PERSON

Created by integerisqt

Features:

  • THIRD PERSON
local keybind = Enum.KeyCode.P;
local hideArms = true; --will hide the arm if u toggle the thirdperson
local thirdPersonDistance = 10;

local camera = workspace.CurrentCamera;
local userInputService = game:GetService("UserInputService");
local replicatedStorage = game:GetService("ReplicatedStorage");
local RunService = game:GetService("RunService")
local localPlayer = game:GetService("Players").LocalPlayer;
local zPercentage = Instance.new("NumberValue");
local robloxRequire = getrenv().require;
local gunModules = replicatedStorage:WaitForChild("GunModules");
local externalModels = replicatedStorage:WaitForChild("ExternalModels");

local thirdPersonEnabled = true;
local localUpdater; --the updater (will be nil when dead)
local thirdPersonStep;
local transparencyFix;
local fakeModel; --the model pf uses for third person
local originalFakeModelData = {};
local originalArmsData = {
    left = {},
    right = {}
};


local lastPosition;
local lastTick;
local currentAngle;


local function setThirdPersonEnabled(enabled)
    for i = enabled and 0 or 1, enabled and 1 or 0, enabled and 1/10 or -1/10 do
        zPercentage.Value = i;
        task.wait();
    end
    zPercentage.Value = enabled and 1 or 0;
end



userInputService.InputBegan:Connect(function(key, gp)
    if gp then return; end
    if key.KeyCode == keybind then
        thirdPersonEnabled = not thirdPersonEnabled;
        setThirdPersonEnabled(thirdPersonEnabled);
    end
end);


local char;
local oldUpdateCharacter;
local network;
local oldSend;
local loadplayer;
local cameraStep;
local oldCameraTask;
local gameLogic;

for i,v in ipairs(getgc(true)) do
    if type(v) == "table" then
        if rawget(v, "send") and rawget(v, "fetch") then
            network = v;
            oldSend = v.send;
        elseif rawget(v, "jump") then
            char = v;
            oldUpdateCharacter = v.updatecharacter;
        elseif rawget(v, "name") and rawget(v, "task") and v.name == "camera" then
            cameraStep = v;
            oldCameraTask = v.task;
        elseif rawget(v, "gammo") then
            gameLogic = v;
        end
    elseif type(v) == "function" then
        if debug.getinfo(v).name == "loadplayer" then
            loadplayer = v;
        end
    end
end


char.ondied:connect(function() --ugly but fuck u
    localUpdater.died();
    thirdPersonStep:Disconnect();
    transparencyFix:Disconnect();
    localUpdater = nil; --shush
    thirdPersonStep = nil;
    transparencyFix = nil;
    lastPosition = nil;
    lastTick = nil;
    currentAngle = nil;
    fakeModel = nil;
    table.clear(originalFakeModelData);
    for i,v in pairs(originalArmsData) do
        table.clear(v);
    end
end);

camera.ChildAdded:Connect(function(child)
    if child.Name == "Left Arm" or child.Name == "Right Arm" then
        local type = child.Name == "Left Arm" and "left" or "right";
        for i,v in pairs(child:GetDescendants()) do
            if v:IsA("BasePart") or v:IsA("Texture") or v:IsA("Decal") and v.Transparency < 1 then
                originalArmsData[type][v] = {
                    trans = v.Transparency
                };
            end
        end
        child.DescendantAdded:Connect(function(v)
            if v:IsA("BasePart") or v:IsA("Texture") or v:IsA("Decal") and v.Transparency < 1 then
                originalArmsData[type][v] = {
                    trans = v.Transparency
                };
            end
        end);
    end
end);


function char.updatecharacter(spawnPosition)
    oldUpdateCharacter(spawnPosition);
    --call loadplayer on localPlayer
    debug.setupvalue(loadplayer, 1, "");
    localUpdater = loadplayer(localPlayer);
    debug.setupvalue(loadplayer, 1, localPlayer);
    --spawn it retard
    localUpdater.spawn(spawnPosition);

    --maybe fix the spring? lmfao retard
    local positionSpring;
    local anglesSpring;
    for i,v in pairs(debug.getupvalues(localUpdater.step)) do
        --check if its a spring
        if type(v) == "table" then
            if rawget(v, "update") and rawget(v, "accelerate") then
                if v._s == 32 then
                    positionSpring = v;
                elseif v._s == 12 then
                    anglesSpring = v;
                end
            elseif rawget(v, "makesound") ~= nil then
                v.makesound = false; --stfu
            end
        end
    end
    for i,v in pairs(debug.getupvalues(localUpdater.spawn)) do
        if typeof(v) == "Instance" and v:IsA("Model") and v.Name == "Player" then
            fakeModel = v;
            break;
        end
    end
    if fakeModel then
        for i,v in pairs(fakeModel:GetDescendants()) do
            if v:IsA("BasePart") or v:IsA("Texture") or v:IsA("Decal") and v.Transparency < 1 then
                originalFakeModelData[v] = {
                    trans = v.Transparency
                };
            end
        end
        fakeModel.DescendantAdded:Connect(function(v)
            if v:IsA("BasePart") or v:IsA("Texture") or v:IsA("Decal") and v.Transparency < 1 then
                originalFakeModelData[v] = {
                    trans = v.Transparency
                };
            end
        end);
    else
        print("yo retard u didnt get the fake model");
    end
    if positionSpring and anglesSpring then
        positionSpring.s = 100; --change this to something higher if u want ur thirdperson to move faster, default is 32
    else
        print("yo retard u didnt get the position spring");
    end
    thirdPersonStep = RunService.RenderStepped:Connect(function()
        if localUpdater and currentAngle then
            anglesSpring.t = Vector2.new(currentAngle.x, currentAngle.y); --my brain is out of this world
            localUpdater.step(3, true);
        end
    end);
    transparencyFix = RunService.Heartbeat:Connect(function()
        if localUpdater and fakeModel then
            for part,data in pairs(originalFakeModelData) do
                part.Transparency = zPercentage.Value == 0 and 1 or data.trans;
            end
            for i,v in pairs(originalArmsData) do
                for part,data in pairs(v) do
                    part.Transparency = not hideArms and data.trans or (thirdPersonEnabled and 1 or data.trans);
                end
            end
        end
    end);
end

function networkConfusedend(name, ...)
    local args = {...};
    if localUpdater then
        if name == "repupdate" then
            currentAngle = args[2];
            local velocity = (args[1] - (lastPosition or args[1]))/(args[3] - (lastTick or args[3]));
            localUpdater.receivedFrameTime = args[3];
            localUpdater.receivedPosition = args[1];
            localUpdater.receivedLookAngles = args[2];
            localUpdater.receivedVelocity = velocity == velocity and velocity or Vector3.new();
            localUpdater.receivedDataFlag = true;
            lastTick = args[3];
            lastPosition = args[1];
        elseif name == "stance" or name == "sprint" or name == "aim" then
            localUpdater["set" .. name](args[1]);
        elseif name == "equip" then
            if gameLogic.currentgun and gameLogic.currentgun.name then
                local data = robloxRequire(gunModules[gameLogic.currentgun.name]); --this should NOT error unless pf is retarded
                local model = externalModels[gameLogic.currentgun.name];
                localUpdater[gameLogic.currentgun.knife and "equipknife" or "equip"](data, model);
            end
        end
    end
    if name == "state" and args[1] == localPlayer then
        return;
    end
    return oldSend(self, name, unpack(args));
end

function cameraStep.task(...)
    oldCameraTask(...);
    local originCframe = camera.CFrame;
    if localUpdater then
        local finalDistance = thirdPersonDistance*zPercentage.Value;
        originCframe = originCframe * CFrame.new(0, 0, finalDistance);
    end
    camera.CFrame = originCframe;
end

ENJOY!

Warning: DO NOT DOWNLOAD anything from this page, you’re only here to copy the script!

Share This Post

Share on facebook
Share on linkedin
Share on twitter
Share on email