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?
COMMUNITY QUESTION
How do I make parts act like they're welded without using welds?
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.
