How do I make the explosion effect always appear on the surface

Alright so I made a fire ball ability and it works pretty well but what I want to achieve is so the explosion effect/cracks appears on any surface so walls, ground, ceilings, etc. I hope you get what I mean.

So here is what happens right now:

So I thought about casting a ray towards the surface and put the explosion effect position where the ray hits, but I don’t know how to make it work. and how can I know if it hits a wall or the ground or the ceiling.

Anyways I hope you understand what I mean and you can help me.

2 Likes

when you release, you should get Mouse.Target, then get Instance.Position.Y , then you will place your vfx via Position = TargetPosY + (VfxModelSize*.5)

ok but will it still work if the fireball doesn’t hit mouse.Target

Set the CFrame like this:

CFrame.new(Raycast.Position, Raycast.Position + Raycast.Normal)

This positions the ray where it hit and rotates it so that the texture points correctly.

Of course, this doesn’t work if the ray doesn’t hit anything (Let’s say the ability is used towards the sky), then you’d have to position it wherever the ray ends.

local Origin -- The origin/starting point of the ray
local Direction -- The direction of the ray
local Length -- The length of the ray (direction * length)

local RayEndPosition = Origin + (Direction * Length)

I think I get what you mean, but could you tell me a little bit more about how I would rotate it?

1 Like

Alright, I’ll write an example of how to create bulletholes for a simple client-sided gun (Same principle as for your project)

-- Client
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

local Character = Player.Character or Player.CharacterAdded:Wait()

-- Tool-related stuff
local Tool = script.Parent
local Handle = Tool.Handle

-- Raycast parameters 
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Character}	

-- Fires when the gun is fired (clicked)
Tool.Activated:Connect(function()
	-- Variables used to cast a ray
	local Origin = Handle.Position -- Where the ray starts, in this case, the handle of the gun
	local Direction = CFrame.new(Origin, Mouse.Hit.Position).LookVector -- The direction the ray should take
	local Length = 100 -- The length of the ray
	
	-- Raycast
	local GunRay = workspace:Raycast(Origin, Direction * Length)
	
	-- Target finding
	if GunRay then
		local HitPosition = GunRay.Position -- The position where the ray hit something
		local Normal = GunRay.Normal -- Basically the direction the face of the 3D object is pointing towards (I think)
		
		-- Bullethole stuff & basic properties
		local BulletholePart = Instance.new("Part")
		
		-- Appearance and behaviour
		BulletholePart.Anchored = true
		BulletholePart.CanCollide = false
		BulletholePart.Transparency = 1
		BulletholePart.Size = Vector3.new(0.25, 0.25, 0)
		
		-- THIS IS THE IMPORTANT CFRAME
		-- Basically, you set the position of this part where it hit,
		-- and set the orientation so that it points in the right direction
		-- The right direction being HitPosition + Normal
		BulletholePart.CFrame = CFrame.new(HitPosition, HitPosition + Normal) 
		
		BulletholePart.Parent = workspace
		
		-- Decal
		local BulletholeDecal = Instance.new("Decal", BulletholePart)
		BulletholeDecal.Texture = "http://www.roblox.com/asset/?id=4804824547" -- Just a texture I found in the toolbox
		
	end
	
end)

This example showcases how to cast a ray, as well as how to correctly position & orient a part depending on the surface it hit.

1 Like

And the reason I use CFrame to get the ray direction is, if you didn’t know or if it wasn’t clear in the example, because the second Vector3 of a CFrame

CFrame.new(Position, Position oriented towards)

is what the object will look towards, it will be oriented in such a way that it points in the direction of that Vector3.new()

And to get the actual direction of that CFrame, you need to get the LookVector.

The LookVector is then multiplied by whatever the length of the ray should be.
(You probably already knew this, but once again, it’s better to be clear)

1 Like

Oh yeah, thank you for this script. I learned not to long ago about normals and had totally forgotten about it. I think it’s a really good way to do this and yeah Thank You again!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.