Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Getting services from Roblox
- local Replicated = game:GetService("ReplicatedStorage")
- local UserInput = game:GetService("UserInputService")
- local PlayerService = game:GetService("Players")
- local RunService = game:GetService("RunService")
- local workspace = game:GetService("Workspace")
- -- Define the server-side remote event for placing objects
- local PlaceServer = Replicated.PlacementSystem.Place
- -- Object list for a specific player (to store objects the player is placing)
- local Objects = Replicated.PlacementSystem:WaitForChild(game.Players.LocalPlayer.Name.."Bugs")
- -- Module for attaching 3D models to UI
- local module3d = require(Replicated.Modules.Module3D)
- -- Spring animation module (used for smooth transitions)
- local Spring = require(script.SpringAnim)
- -- Define the local player and related objects
- local Player = PlayerService.LocalPlayer
- local Character = Player.Character or Player.CharacterAdded:Wait()
- local Mouse = Player:GetMouse()
- -- Client status to track the placing and rotating state
- local ClientStatus = {
- ['Rotating'] = false, -- Whether the player is rotating the object
- ['Placing'] = false, -- Whether the player is placing the object
- }
- -- Button used to cancel the placement process (can be changed to another button if desired)
- local CancelButton = "X"
- -- Listen for when an object is added or removed, and rerun the loop
- Objects.ChildAdded:Connect(function()
- rerunLoop()
- end)
- Objects.ChildRemoved:Connect(function()
- rerunLoop()
- end)
- -- Function to rerun the placement logic
- function rerunLoop()
- ClientStatus.Placing = false -- Reset placing status
- -- Get the list of objects in the "Objects" folder and limit to 5 objects for display
- local objects = Objects:GetChildren()
- local numObjects = math.min(5, #objects)
- -- Loop through the objects and display them in the UI
- for i = 1, 5 do
- local frame = script.Parent.Frame:FindFirstChild("Frame" .. i)
- if frame then
- if i <= numObjects then
- local obj = objects[i]
- frame.Visible = true
- local Button = frame.ViewportFrame:FindFirstChild("Button")
- -- Attach the 3D model of the object to the viewport
- local petModel3d = module3d:Attach3D(frame.ViewportFrame, obj:Clone())
- petModel3d:SetDepthMultiplier(1.6)
- petModel3d.Camera.FieldOfView = 5
- petModel3d.Visible = true
- -- Rotation effect for the model
- RunService.RenderStepped:Connect(function()
- petModel3d:SetCFrame(CFrame.Angles(0, tick() % (math.pi * 2), 0) * CFrame.Angles(math.rad(-10), 0, 0))
- end)
- -- Button click logic to place the object
- Button.MouseButton1Click:Connect(function()
- if ClientStatus.Placing == false then
- ClientStatus.Placing = true
- script.Parent.Frame.Visible = false
- -- Initialization for the object placement process
- local RotInt = 0
- local ObjectClone = obj:Clone()
- local CanPlace = false
- local OrginColor
- -- Store the original color of the object
- if ObjectClone:IsA("Model") then
- OrginColor = ObjectClone.PrimaryPart.Color
- else
- OrginColor = ObjectClone.Color
- end
- local Connection
- local Connection2
- -- Place the object in the workspace initially
- ObjectClone.Parent = workspace
- if ObjectClone:IsA("Model") then
- for _, child in pairs(ObjectClone:GetChildren()) do
- if child:IsA("BasePart") then
- child.CanCollide = false
- end
- end
- else
- ObjectClone.CanCollide = false
- end
- -- Set the initial position of the object
- local CFrameOffset = CFrame.new(0, -2, -5)
- if ObjectClone:IsA("Model") then
- ObjectClone.PrimaryPart.CFrame = Character.HumanoidRootPart.CFrame:ToWorldSpace(CFrameOffset)
- else
- ObjectClone.CFrame = Character.HumanoidRootPart.CFrame:ToWorldSpace(CFrameOffset)
- end
- -- Create a selection box to show potential placement
- local NewBox = Instance.new('SelectionBox', ObjectClone)
- NewBox.Adornee = ObjectClone
- NewBox.Color3 = Color3.fromRGB(113, 255, 61)
- NewBox.LineThickness = 0
- -- Update the placement logic with raycasting
- Connection2 = RunService.RenderStepped:Connect(function()
- local MouseRay = Mouse.UnitRay
- local RayCast = Ray.new(MouseRay.Origin, MouseRay.Direction * 10000)
- local IgnoreIndex = {ObjectClone, Character}
- local Hit, Pos = workspace:FindPartOnRayWithIgnoreList(RayCast, IgnoreIndex)
- if Hit and ((Hit:IsA('Part') or Hit:IsA('UnionOperation')) and Hit:FindFirstChild("CanPlace")) and (Character.HumanoidRootPart.Position - (ObjectClone.PrimaryPart.Position)).magnitude <= 25 then
- CanPlace = true
- Spring.target(ObjectClone.PrimaryPart, 1, 2.5, {Transparency = 0, Color = OrginColor})
- Spring.target(NewBox, 1, 2, {LineThickness = 0, Color3 = Color3.fromRGB(113, 255, 61)})
- else
- CanPlace = false
- Spring.target(NewBox, 1, 2.5, {LineThickness = .15, Color3 = Color3.fromRGB(255, 52, 55)})
- Spring.target(ObjectClone.PrimaryPart, 1, 2, {Transparency = .5, Color = Color3.fromRGB(255, 57, 60)})
- end
- -- Update the CFrame of the object based on mouse position and rotation
- local AnglesCFrame = CFrame.Angles(0, math.rad(RotInt), 0)
- local modelSize = ObjectClone:GetExtentsSize()
- local heightOffset = modelSize.Y / 2
- local NewCFrame = CFrame.new(Pos.X, Pos.Y + heightOffset, Pos.Z)
- ObjectClone.PrimaryPart.CFrame = NewCFrame * AnglesCFrame
- end)
- -- Function to handle input events (rotation and placement)
- local function InputBegan(Input)
- -- Handle rotation with 'R' key
- if Input.KeyCode == Enum.KeyCode.R then
- ClientStatus.Rotating = true
- -- Rotate the object as long as the player holds the key
- while ClientStatus.Rotating == true do
- if ClientStatus.Placing then
- RotInt = RotInt + 5 -- Increment rotation angle
- end
- task.wait()
- end
- end
- -- Handle placement with the left mouse button
- if Input.UserInputType == Enum.UserInputType.MouseButton1 then
- if ClientStatus.Placing then
- if CanPlace == true then
- local SetCFrame = ObjectClone.PrimaryPart.CFrame
- local Response = Replicated.PlacementSystem['Place']:InvokeServer(ObjectClone.Name, SetCFrame)
- if Response == true and Response ~= nil then
- -- Clean up after placement
- Connection:Disconnect()
- Connection2:Disconnect()
- ClientStatus.Placing = false
- ObjectClone:Destroy()
- script.Parent.Frame.Visible = true
- end
- end
- end
- end
- -- Cancel placement with the 'X' key
- if Input.KeyCode == Enum.KeyCode.X then
- if ClientStatus.Placing then
- -- Disconnect connections and clean up the object
- if Connection then Connection:Disconnect() end
- if Connection2 then Connection2:Disconnect() end
- if ObjectClone then
- ObjectClone:Destroy()
- end
- ClientStatus.Placing = false
- script.Parent.Frame.Visible = true
- end
- end
- end
- -- Connect the input event for rotation and placement
- Connection = UserInput.InputBegan:Connect(InputBegan)
- -- Listen for when rotation stops
- UserInput.InputEnded:Connect(function(Input)
- if Input.KeyCode == Enum.KeyCode.R then
- ClientStatus.Rotating = false
- end
- end)
- end
- end)
- else
- -- Hide the frame if no objects are available to display
- frame.Visible = false
- end
- end
- end
- end
- -- Call the rerunLoop function to initialize the placement system
- rerunLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement