and I wanted to ask, how can I prevent this from happening? Is there a way to like add the decal to one part of the wall?
Code:
local Tool = script.Parent
local enabled = true
local THROW_FORCE = math.random(40, 180)
local MIN_THROW_DELAY = 1
local DECAL_ID = "rbxassetid://13510998982"
local IMPACT_SOUND_ID = "rbxassetid://8595980577"
local canThrow = true
local players = game:GetService("Players")
local MouseUpdate = Instance.new("RemoteEvent")
MouseUpdate.Name = "MouseUpdate"
MouseUpdate.Parent = Tool
local currentMousePosition = Vector3.new(0,0,0) --Default position
MouseUpdate.OnServerEvent:Connect(function(player, mousePos)
currentMousePosition = mousePos
end)
local function onActivated()
if not enabled or not canThrow then
return
end
enabled = false
canThrow = false
local character = Tool.Parent
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then return end
local torso = character:FindFirstChild("Torso") or character:FindFirstChild("HumanoidRootPart")
if not torso then return end
local handle = Tool.Handle:Clone()
handle.Anchored = false
handle.CanCollide = true
handle.Parent = workspace
handle.CFrame = Tool.Handle.CFrame
-- Apply throwing force using the *latest* mouse position
local throwDirection = (currentMousePosition - handle.Position).Unit
handle:ApplyImpulse(throwDirection * THROW_FORCE * handle:GetMass())
handle:SetNetworkOwner(nil)
Tool.Enabled = false
if Tool.Handle:FindFirstChild("BiteSound") then
Tool.Handle.BiteSound:Play()
end
local function applyImpactEffects(hit)
if hit and hit:IsA("BasePart") then -- Checks if the hit object is a Part, MeshPart, or UnionOperation
-- Check if the hit part is not an ancestor of the character throwing the tool
local character = Tool.Parent
local isAncestor = false
local current = hit
while current do
if current == character then
isAncestor = true
break
end
current = current.Parent
end
if not isAncestor then
print(hit)
local decal = Instance.new("Decal")
decal.Texture = DECAL_ID
decal.Face = Enum.NormalId.Front
decal.Parent = hit
game.Debris:AddItem(decal, 5)
-- Particle effect
local emitter = Instance.new("ParticleEmitter")
emitter.Parent = hit
emitter.Rate = 10
emitter.Lifetime = NumberRange.new(0.5, 1)
game.Debris:AddItem(emitter, 1)
-- Impact sound (on hit object)
local sound = Instance.new("Sound")
sound.SoundId = IMPACT_SOUND_ID
sound.Parent = hit
sound.Volume = 0.5
sound:Play()
-- Impact sound (only if a humanoid root part exists and is a descendant of the hit part)
if hit.Parent and hit.Parent:FindFirstChild("HumanoidRootPart") then
local sound2 = Instance.new("Sound")
sound2.SoundId = IMPACT_SOUND_ID
sound2.Parent = hit.Parent.HumanoidRootPart
sound2.Volume = 0.5
sound2:Play()
end
end
end
end
local connection = handle.Touched:Connect(applyImpactEffects)
-- Fix: Compare the number of players with a number, not the players service itself
if #players:GetPlayers() >= 6 then
game.Debris:AddItem(handle, 3)
else
game.Debris:AddItem(handle, 3000)
end
wait(0.5)
local player = game.Players:GetPlayerFromCharacter(Tool.Parent)
if player then
local backpack = player.Backpack
if backpack then
if Tool then
Tool:Destroy()
end
end
end
wait(MIN_THROW_DELAY)
if connection then connection:Disconnect() end
Tool.Enabled = true
enabled = true
canThrow = true
end
local function onEquipped()
if Tool.Handle:FindFirstChild("EquipSound") then
Tool.Handle.EquipSound:Play()
end
end
Tool.Activated:Connect(onActivated)
Tool.Equipped:Connect(onEquipped)
You could probably make a part with the decal appear where the tomato gets thrown. Bonus is that you can use Debris to make it disappear after a certain amount of time too.
Looks like the decal is fitting itself to the part, and in this case that is that whole wall. Maybe create a smaller transparent part that the decal is in for the hit.
Okay, it works now but one more issue, I can see the decal through players like myself
local Tool = script.Parent
local enabled = true
local THROW_FORCE = math.random(40, 180)
local MIN_THROW_DELAY = 1
local DECAL_ID = "rbxassetid://2884584"
local IMPACT_SOUND_ID = "rbxassetid://8595980577"
local canThrow = true
local players = game:GetService("Players")
local MouseUpdate = Instance.new("RemoteEvent")
MouseUpdate.Name = "MouseUpdate"
MouseUpdate.Parent = Tool
local currentMousePosition = Vector3.new(0, 0, 0)
MouseUpdate.OnServerEvent:Connect(function(player, mousePos)
currentMousePosition = mousePos
end)
-- Function to create a SurfaceGui decal at hit position + normal
local function applyImpactEffects(hitPosition, hitNormal, character)
local sizeX = math.random(2, 4) -- Random size between 2 and 4
local sizeY = math.random(2, 4) -- Random size between 2 and 4
local part = Instance.new("Part")
part.Size = Vector3.new(sizeX, sizeY, 0.1) -- Make the part thin
part.Anchored = true
part.CanCollide = false
part.Transparency = 1
part.CFrame = CFrame.new(hitPosition, hitPosition + hitNormal)
part.Parent = workspace
local surfaceGui = Instance.new("SurfaceGui")
surfaceGui.Face = Enum.NormalId.Front
surfaceGui.AlwaysOnTop = true
surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
surfaceGui.PixelsPerStud = 50
surfaceGui.Adornee = part
surfaceGui.Parent = part
local image = Instance.new("ImageLabel")
image.Image = DECAL_ID
image.Size = UDim2.new(1, 0, 1, 0)
image.BackgroundTransparency = 1
image.Parent = surfaceGui
-- Impact sound
local sound = Instance.new("Sound")
sound.SoundId = IMPACT_SOUND_ID
sound.Volume = 0.5
sound.Parent = part
sound:Play()
-- Optional: Particle effect
local emitter = Instance.new("ParticleEmitter")
emitter.Rate = 20
emitter.Lifetime = NumberRange.new(0.3, 0.6)
emitter.Speed = NumberRange.new(2, 4)
emitter.SpreadAngle = Vector2.new(360, 360)
emitter.Parent = part
game.Debris:AddItem(emitter, 1)
-- Disable collision with the character who threw it
if character then
local PhysicsService = game:GetService("PhysicsService")
local partCollisionGroupName = tostring(part) -- Unique collision group name
-- Register the collision group
PhysicsService:RegisterCollisionGroup(partCollisionGroupName)
-- Set the collision group to not collide with itself
PhysicsService:CollisionGroupSetCollidable(partCollisionGroupName, partCollisionGroupName, false)
-- Function to recursively set collision group for parts and their descendants
local function setCollisionGroupRecursive(obj, groupName)
if obj:IsA("BasePart") then
obj.CollisionGroup = groupName
end
for _, child in ipairs(obj:GetChildren()) do
setCollisionGroupRecursive(child, groupName)
end
end
-- Set collision group for the part
setCollisionGroupRecursive(part, partCollisionGroupName)
-- Set collision group for all parts in the character
for _, partInCharacter in ipairs(character:GetChildren()) do
setCollisionGroupRecursive(partInCharacter, partCollisionGroupName)
end
end
game.Debris:AddItem(part, 10)
end
local function onActivated()
if not enabled or not canThrow then return end
enabled = false
canThrow = false
local character = Tool.Parent
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then return end
local torso = character:FindFirstChild("Torso") or character:FindFirstChild("HumanoidRootPart")
if not torso then return end
local handle = Tool.Handle:Clone()
handle.Anchored = false
handle.CanCollide = true
handle.Parent = workspace
handle.CFrame = Tool.Handle.CFrame
local throwDirection = (currentMousePosition - handle.Position).Unit
handle:ApplyImpulse(throwDirection * THROW_FORCE * handle:GetMass())
handle:SetNetworkOwner(nil)
if Tool.Handle:FindFirstChild("BiteSound") then
Tool.Handle.BiteSound:Play()
end
-- Perform raycast from handle's position in the direction of throw
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character, handle}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.IgnoreWater = true
local raycastResult = workspace:Raycast(handle.Position, throwDirection * 100, raycastParams)
if raycastResult then
applyImpactEffects(raycastResult.Position, raycastResult.Normal, character)
end
-- Clean up the thrown handle
if #players:GetPlayers() >= 6 then
game.Debris:AddItem(handle, 3)
else
game.Debris:AddItem(handle, 3000)
end
wait(0.5)
local player = players:GetPlayerFromCharacter(character)
if player then
local backpack = player:FindFirstChild("Backpack")
if backpack then
Tool:Destroy()
end
end
wait(MIN_THROW_DELAY)
Tool.Enabled = true
enabled = true
canThrow = true
end
local function onEquipped()
if Tool.Handle:FindFirstChild("EquipSound") then
Tool.Handle.EquipSound:Play()
end
end
Tool.Activated:Connect(onActivated)
Tool.Equipped:Connect(onEquipped)