Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

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

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?

1 answer

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! :)

This discussion is preserved as it was. New answers, comments, and votes are closed.