Hello guys.
i recently started doing a cube that throws when your click, the cube start position depends of the mouse position. When the cube hits the ground, it spawns a cage at the impact of the cube.
But it’s quite complicated to aim to players so i tried doing aim assist, i tried curving the cube to the nearest player, spawning the cage near the player but nothing work. Here is the Server script that only throws the cube to the mouse position :
local replicatedStorage = game:GetService("ReplicatedStorage")
local cooldowns = {} -- Table to manage player cooldowns
-- Check or create the RemoteEvent
local remoteEvent = replicatedStorage:FindFirstChild("LaunchObjectEvent")
if not remoteEvent then
remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = "LaunchObjectEvent"
remoteEvent.Parent = replicatedStorage
end
local function getClosestPlayer(position, excludePlayer)
local closestPlayer = nil
local closestDistance = math.huge
-- Find the closest player, excluding the player who launched the object
for _, player in pairs(game.Players:GetPlayers()) do
if player ~= excludePlayer and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local playerPosition = player.Character.HumanoidRootPart.Position
local distance = (playerPosition - position).magnitude
if distance < closestDistance then
closestDistance = distance
closestPlayer = player
end
end
end
return closestPlayer
end
remoteEvent.OnServerEvent:Connect(function(player, position, direction)
local character = player.Character
if not character then return end
local tool = character:FindFirstChildOfClass("Tool")
if not tool then
print("No tool found for player:", player.Name)
return
end
local handle = tool:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then
print("No 'Handle' detected in the tool.")
return
end
-- Check if the player is in cooldown
if cooldowns[player] and tick() - cooldowns[player] < 1.5 then
print("Cooldown active for", player.Name)
return
end
cooldowns[player] = tick() -- Start cooldown
-- Clone the Handle ONLY ONCE
local thrownHandle = handle:Clone()
thrownHandle.Parent = game.Workspace
thrownHandle.Position = position + Vector3.new(0, 2, 0) -- Slightly above the player
thrownHandle.CanCollide = true
thrownHandle.Anchored = false
-- Remove previous attachments (prevents bugs)
for _, child in pairs(thrownHandle:GetChildren()) do
if child:IsA("Weld") or child:IsA("Motor6D") then
child:Destroy()
end
end
-- Prevent uncontrolled rotation
local gyro = Instance.new("BodyGyro")
gyro.P = 5000
gyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
gyro.CFrame = thrownHandle.CFrame
gyro.Parent = thrownHandle
-- Add force to launch the object
local velocity = Instance.new("BodyVelocity")
velocity.Velocity = direction * 60
velocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
velocity.Parent = thrownHandle
-- Remove the force after a while to let physics take over
game:GetService("Debris"):AddItem(velocity, 1.5)
game:GetService("Debris"):AddItem(gyro, 1.5)
-- Check for the closest player, excluding the one who launched the object
local closestPlayer = getClosestPlayer(thrownHandle.Position, player)
if closestPlayer then
print("Trajectory adjusted towards", closestPlayer.Name)
local targetPosition = closestPlayer.Character.HumanoidRootPart.Position
local directionToTarget = (targetPosition - thrownHandle.Position).unit
-- Slightly adjust the trajectory to curve towards the target
velocity.Velocity = velocity.Velocity + directionToTarget * 20 -- Adds a small curve to the direction
end
print("Object cloned and launched by", player.Name)
-- Debounce to prevent multiple cages
local debounce = false
thrownHandle.Touched:Connect(function(hit)
if not debounce and hit and hit:IsA("BasePart") and hit.Position.Y < position.Y then
debounce = true -- Block other triggers
print("Impact detected on the ground!")
-- Destroy the thrown object
thrownHandle:Destroy()
-- Check if the Cage exists in ReplicatedStorage
local cageTemplate = replicatedStorage:FindFirstChild("Cage")
if cageTemplate and cageTemplate:IsA("Model") then
local newCage = cageTemplate:Clone()
newCage.Parent = game.Workspace
-- Find the height of the Cage to place it properly
local cagePrimaryPart = newCage.PrimaryPart or newCage:FindFirstChildWhichIsA("BasePart")
if cagePrimaryPart then
newCage:SetPrimaryPartCFrame(CFrame.new(thrownHandle.Position + Vector3.new(0, 3, 0))) -- Spawn at the impact point
newCage.PrimaryPart.Anchored = false -- The cage falls naturally
print("Cage spawned and falling!")
-- Once the cage is below 3, anchor it after 6 seconds
wait(2)
newCage.PrimaryPart.Anchored = true
print("Cage properly placed on the ground!")
-- Destroy the cage after 5 seconds
wait(5)
newCage:Destroy()
print("Cage successfully destroyed!")
else
print("No PrimaryPart defined for the Cage.")
end
else
print("No 'Cage' object found in ReplicatedStorage")
end
end
end)
end)
Thanks to anyone who are gonna help me !