Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do I make parts act like they're welded without using welds? [closed]

Asked by 3 years ago

So I'm trying to make some welded parts move inside of a ViewportFrame, but i realised welds don't work outside of workspace, how would I use CFrames to make them act like they're welded?

Closed as off-topic by JesseSong

This question has been closed by our community as being off-topic from ROBLOX Lua Scripting.

Why was this question closed?

1 answer

Log in to vote
0
Answered by
TGazza 1336 Moderation Voter
3 years ago
Edited 3 years ago

Not sure if this is what your asking but i have made a camera system that uses a ViewportFrame. the script simply clones what the camera sees and uses the viewportframe as a screen.

the code is as follows: It also might give you some idea on how to move something without using welds! :)

Code(LocalScript):

local function CreateRegion3FromLocAndSize(PartBase,Offset, Size)
    local SizeOffset = Size/2
    local CF = PartBase.CFrame*Offset
    local Point1 = (CF - SizeOffset).p
    local Point2 = (CF + SizeOffset).p
    return Region3.new(Point1, Point2)
end

local RegionSize = Vector3.new(250,250,250)
local Camera = workspace.CurrentCamera
local Player = script.Parent.Parent
local PlayerGui = Player.PlayerGui 

local ScreenGui = (function()
    local Screen_Name = "Camera View Port"
    local S = PlayerGui:FindFirstChild(Screen_Name)
    if(S == nil) then
        S = Instance.new("ScreenGui",PlayerGui)
        S.Name = Screen_Name
    end
    return S 
end)()

local Screen = Instance.new("ViewportFrame", ScreenGui)
Screen.Size = UDim2.new(0, 250, 0, 250)
Screen.Position = UDim2.new(0,0,1,-250)
Screen.BackgroundColor3 = Color3.new(1, 1, 1)

local guiCamera = Instance.new("Camera", Screen)
Screen.CurrentCamera = guiCamera
local CameraOffset = CFrame.new(0,0,0)

local ScreenBits = {}

local function IsPartInRegion3(Part,Region3Space)
    local R3Size = Region3Space.Size
    local X1 = Region3Space.CFrame.X - (R3Size.X/2)
    local Y1 = Region3Space.CFrame.Y - (R3Size.Y/2)
    local Z1 = Region3Space.CFrame.Z - (R3Size.Z/2)
    local X2 = Region3Space.CFrame.X + (R3Size.X/2)
    local Y2 = Region3Space.CFrame.Y + (R3Size.Y/2)
    local Z2 = Region3Space.CFrame.Z + (R3Size.Z/2)
    local LowerCorner = Vector3.new(X1,Y1,Z1)
    local UpperCorner = Vector3.new(X2,Y2,Z2)
    return Part.Position.X > LowerCorner.X 
    and Part.Position.X < UpperCorner.X 
    and Part.Position.Y > LowerCorner.Y 
    and Part.Position.Y < UpperCorner.Y 
    and Part.Position.Z > LowerCorner.Z 
    and Part.Position.Z < UpperCorner.Z
end
local function isInView(Camera,Part)

    local function toRot(CF)
        local sx, sy, sz, m00, m01, m02, m10, m11, m12, m20, m21, m22 = CF:components()
        local Y = math.atan2(m02, m22)*(180/math.pi)+180
        local X = math.asin(-m12)*(180/math.pi)+180
        local Z = math.atan2(m10, m11)*(180/math.pi)+180
        return Vector3.new(X,Y,Z)
    end
    local DirCF = CFrame.new(Camera.CFrame.p, Part.Position)


    local Rot = toRot(DirCF)
    local ARot = toRot(DirCF*CFrame.Angles(0,math.rad(180),0))
    local MyRot = toRot(Camera.CFrame)
    local Aim = (ARot.Y)-(MyRot.Y)
    --local b_IsBehindME = math.abs(Aim) > 90
    local b_CanISeeIt = math.abs(Aim) > Camera.FieldOfView
    --print("Can I SEE [",Part,"] = ",b_CanISeeIt)
    return b_CanISeeIt
end 



local RS = game:GetService("RunService")
RS.Heartbeat:connect(function()
    local Offset = CFrame.new(0,0,-15)
    local R3  = CreateRegion3FromLocAndSize(Camera,Offset, RegionSize)

    for OPart,CPart in pairs(ScreenBits) do
        local bisInView = isInView(Camera,OPart)
        local isInR3 = IsPartInRegion3(OPart,R3)
        if(not isInR3 or OPart:IsDescendantOf(workspace) == false) then
            ScreenBits[OPart] = nil
            CPart:Destroy()
        elseif(not bisInView) then
            ScreenBits[OPart] = nil
            CPart:Destroy()
        end

    end
    guiCamera.CFrame = Camera.CFrame*CameraOffset
    for k,v in pairs(workspace:FindPartsInRegion3WithIgnoreList(R3,{},10000)) do
        local Bit = ScreenBits[v]
        if(Bit == nil) then
            local bisInView = isInView(Camera,v)
            if(bisInView == true) then
                Bit = v:Clone()
                Bit.Parent = Screen
                ScreenBits[v] = Bit
                v.Changed:Connect(function(thing)
                    local Orig = v 
                    local Exists,err = pcall(function() return Orig[thing] end, nil)
                    if(Exists) then
                        local MyCne = Bit
                        MyCne[thing] = Orig[thing]
                    end
                end)
            end     
        end
        if(Bit ~= nil) then
            Bit.CFrame = v.CFrame   
        end 

    end
end)

just copy and paste that into a local script inside the PlayerStarterscripts and run the game to see the effect! :)

Ad