How to make cool rocks stuff like gpo

So basically dont you know those coool rock effects you see in games nowadays but no one wants to teach you how to make them because they feel special??? Well I’ll be teaching you how since its pretty easy and shouldn’t be gate kept. So First, You needa define your Services, Those Services will be

First add a part inside your script doesnt matter what its called then add a mesh inside and change the mesh id to a block

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local TweenService = game:GetService("TweenService")

local RunService = game:GetService("RunService")

local Debris = game:GetService("Debris")

image

Thennn you needaa Get ur tween info since we’re gonna be tweening since tweens make everyone happy!

local Tween1 = TweenInfo.new(.2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

You can change it as you see fit

Then we need raycast paramaters so we can make sure its colored :grin:

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {workspace}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist

image

Now we need the amount of rocks the time it takes to make the tween how long the rocks stay for, the amount of rocks and how spaced out it is the max size upwards and where it originates

local Amount,Max = 20, 2.5  ---Amount of rocks and max length upwards
local FirstDuration, RocksLength = .5, 3--- How long it takes to tween and when it goes away
local Cframe,Iteration = workspace.Part.CFrame, 20 --- Where the part spawns and how much it expands outwards

image

Now we do where we want the the rocks to like curve like circular or straightforward

local Angeled360 = 360 / Amount	

Now code that makes it worky

local RockModel = Instance.new("Model", workspace.World.Visuals)
Debris:AddItem(RockModel, RocksLength + .25)
for Index = 1, Amount do
		--// Calculations
	local SizeCalc = math.sin(math.pi / Amount) * Iteration * 2 * 1.01
	local PositionCalc = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration) * CFrame.Angles(math.rad(45), 0, 0)
	local YAndZ = Max * math.random(50, 120) / 100
	local RandomizedForCalc = 5 + Max * 2
	local RaycastToSet = CFrame.new(PositionCalc.Position) * CFrame.new(0, RandomizedForCalc, 0)
	local Target, Position, Surface = workspace:FindPartOnRayWithWhitelist(Ray.new(RaycastToSet.p, RaycastToSet.upVector * (-RandomizedForCalc * 2)), { workspace.World.Map,})

	local InstancedPart = script.Part:Clone()
	InstancedPart.CanCollide = false
	InstancedPart.Size = Vector3.new(SizeCalc, YAndZ, YAndZ)

	if Target then
		InstancedPart.Color = Target.Color
		InstancedPart.Material = Target.Material
		local Mult = 1
		if Position.Y < PositionCalc.Position.Y then
			Mult = -1
		end
		local MagZX = PositionCalc * CFrame.new(0, (PositionCalc.Position - Position).Magnitude * Mult, 0)
		local ToReturn = CFrame.new(Position, Position + Surface) * CFrame.Angles(math.rad(90), 0, 0)

		InstancedPart.CFrame = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration / 2)
		InstancedPart.Parent = RockModel
		local X, Y, Z = Cframe:components()

		local Ax, Ay, Az, A1, A2, A3, A4, A5, A6, A7, A8, A9 = ToReturn:components()

		local Tween = TweenService:Create(InstancedPart,TweenInfo.new(FirstDuration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = CFrame.new(ToReturn.Position, CFrame.new(X, Y, Z, A1, A2, A3, A4, A5, A6, A7, A8, A9).Position) * CFrame.Angles(math.rad(math.random(20, 50)), 0, 0)})
		Tween:Play()
		Tween:Destroy()

		coroutine.resume(coroutine.create(function()
			wait(RocksLength)
			if InstancedPart then
				local Tween = TweenService:Create(InstancedPart.Mesh,TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {["Scale"] = Vector3.new(1, 0, 0)})
				Tween:Play()
				Tween:Destroy()

				local Tween = TweenService:Create(InstancedPart,TweenInfo.new(.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = InstancedPart.CFrame * CFrame.new(0, -Max * 1.25, 0)})
				Tween:Play()
				Tween:Destroy()
			end
		end))
	else
		InstancedPart:Destroy()
	end
end
--|| Services ||--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Debris = game:GetService("Debris")

local Tween1 = TweenInfo.new(.2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {workspace}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
local Amount,Max = 20, 2.5
local FirstDuration, RocksLength = .5, 3
local Cframe,Iteration = workspace.Part.CFrame, 20

local Angeled360 = 360 / Amount	

local RockModel = Instance.new("Model", workspace.World.Visuals)
Debris:AddItem(RockModel, RocksLength + .25)

task.wait(8)

for Index = 1, Amount do
		--// Calculations
	local SizeCalc = math.sin(math.pi / Amount) * Iteration * 2 * 1.01
	local PositionCalc = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration) * CFrame.Angles(math.rad(45), 0, 0)
	local YAndZ = Max * math.random(50, 120) / 100
	local RandomizedForCalc = 5 + Max * 2
	local RaycastToSet = CFrame.new(PositionCalc.Position) * CFrame.new(0, RandomizedForCalc, 0)
	local Target, Position, Surface = workspace:FindPartOnRayWithWhitelist(Ray.new(RaycastToSet.p, RaycastToSet.upVector * (-RandomizedForCalc * 2)), { workspace.World.Map,})

	local InstancedPart = script.Part:Clone()
	InstancedPart.CanCollide = false
	InstancedPart.Size = Vector3.new(SizeCalc, YAndZ, YAndZ)

	if Target then
		InstancedPart.Color = Target.Color
		InstancedPart.Material = Target.Material
		local Mult = 1
		if Position.Y < PositionCalc.Position.Y then
			Mult = -1
		end
		local MagZX = PositionCalc * CFrame.new(0, (PositionCalc.Position - Position).Magnitude * Mult, 0)
		local ToReturn = CFrame.new(Position, Position + Surface) * CFrame.Angles(math.rad(90), 0, 0)

		InstancedPart.CFrame = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration / 2)
		InstancedPart.Parent = RockModel
		local X, Y, Z = Cframe:components()

		local Ax, Ay, Az, A1, A2, A3, A4, A5, A6, A7, A8, A9 = ToReturn:components()

		local Tween = TweenService:Create(InstancedPart,TweenInfo.new(FirstDuration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = CFrame.new(ToReturn.Position, CFrame.new(X, Y, Z, A1, A2, A3, A4, A5, A6, A7, A8, A9).Position) * CFrame.Angles(math.rad(math.random(20, 50)), 0, 0)})
		Tween:Play()
		Tween:Destroy()

		coroutine.resume(coroutine.create(function()
			task.wait(RocksLength)
			if InstancedPart then
				local Tween = TweenService:Create(InstancedPart.Mesh,TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {["Scale"] = Vector3.new(1, 0, 0)})
				Tween:Play()
				Tween:Destroy()

				local Tween = TweenService:Create(InstancedPart,TweenInfo.new(.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = InstancedPart.CFrame * CFrame.new(0, -Max * 1.25, 0)})
				Tween:Play()
				Tween:Destroy()
			end
		end))
	else
		InstancedPart:Destroy()
	end
end

image

There ya go experiment with the stuff as you please :grin:

25 Likes

you use wait() at the bottom of your code, which is bad because task.wait() replaces wait()

6 Likes

yeah didnt think of it Ill edit it so people use it

1 Like

It would be nice to put in a video of the rock effect at the start so people know what they are going to be making. Not all people have played GPO. It would be nice if you added that!

got it! thanks for the recommendation!

Could you make this like a module?

Yeah, I’ll do it later tho at school.

2 Likes

Hi fella where do i put the script?

if you make like more the value like 10 -

starter gui or playerscripts either one works make sure its local

1 Like

i was confuse on what script should i put

Maybe it’s an idea to show the end product here, as I have completely no idea what “gpo” is and “rock effects” sounds completely unknown to me.

It can be that it’s actually everywhere on Roblox (as I don’t play Roblox myself), but it’s still nice to have more context for unfamiliar people (like me).

Gpo is a abbreviation of a games name which is Grand Piece Online

And what is that “cool rocks” effect? How does it relate with “gpo”?

When someone uses an ability like in this gif: https://gyazo.com/acea92aa20437d1404c7ccf41c3d21df.
It just represents an impact on the ground, like a crater of some sort

1 Like

this is very confusing there are multiple scripts I’m confused about where they each go?

3 Likes

I’m pretty sure your supposed to put this script in a part so like if your game has a ground smash then if there was a hitbox maybe with this script it could make a cool rock effect

To clear up some confusion, this is the script you copy and paste into a local script,

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local TweenService = game:GetService("TweenService")

local RunService = game:GetService("RunService")

local Debris = game:GetService("Debris")

local Tween1 = TweenInfo.new(.2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {workspace}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist

local Amount,Max = 20, 2.5  ---Amount of rocks and max length upwards
local FirstDuration, RocksLength = .5, 3--- How long it takes to tween and when it goes away
local Cframe,Iteration = workspace.Part.CFrame, 20 --- Where the part spawns and how much it expands outwards

local Angeled360 = 360 / Amount

local RockModel = Instance.new("Model", workspace.World.Visuals)
Debris:AddItem(RockModel, RocksLength + .25)
for Index = 1, Amount do
		--// Calculations
	local SizeCalc = math.sin(math.pi / Amount) * Iteration * 2 * 1.01
	local PositionCalc = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration) * CFrame.Angles(math.rad(45), 0, 0)
	local YAndZ = Max * math.random(50, 120) / 100
	local RandomizedForCalc = 5 + Max * 2
	local RaycastToSet = CFrame.new(PositionCalc.Position) * CFrame.new(0, RandomizedForCalc, 0)
	local Target, Position, Surface = workspace:FindPartOnRayWithWhitelist(Ray.new(RaycastToSet.p, RaycastToSet.upVector * (-RandomizedForCalc * 2)), { workspace.World.Map,})

	local InstancedPart = script.Part:Clone()
	InstancedPart.CanCollide = false
	InstancedPart.Size = Vector3.new(SizeCalc, YAndZ, YAndZ)

	if Target then
		InstancedPart.Color = Target.Color
		InstancedPart.Material = Target.Material
		local Mult = 1
		if Position.Y < PositionCalc.Position.Y then
			Mult = -1
		end
		local MagZX = PositionCalc * CFrame.new(0, (PositionCalc.Position - Position).Magnitude * Mult, 0)
		local ToReturn = CFrame.new(Position, Position + Surface) * CFrame.Angles(math.rad(90), 0, 0)

		InstancedPart.CFrame = Cframe * CFrame.Angles(0, math.rad(Index * Angeled360), 0) * CFrame.new(0, 0, Iteration / 2)
		InstancedPart.Parent = RockModel
		local X, Y, Z = Cframe:components()

		local Ax, Ay, Az, A1, A2, A3, A4, A5, A6, A7, A8, A9 = ToReturn:components()

		local Tween = TweenService:Create(InstancedPart,TweenInfo.new(FirstDuration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = CFrame.new(ToReturn.Position, CFrame.new(X, Y, Z, A1, A2, A3, A4, A5, A6, A7, A8, A9).Position) * CFrame.Angles(math.rad(math.random(20, 50)), 0, 0)})
		Tween:Play()
		Tween:Destroy()

		coroutine.resume(coroutine.create(function()
			wait(RocksLength)
			if InstancedPart then
				local Tween = TweenService:Create(InstancedPart.Mesh,TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {["Scale"] = Vector3.new(1, 0, 0)})
				Tween:Play()
				Tween:Destroy()

				local Tween = TweenService:Create(InstancedPart,TweenInfo.new(.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out,0,false,0), {CFrame = InstancedPart.CFrame * CFrame.new(0, -Max * 1.25, 0)})
				Tween:Play()
				Tween:Destroy()
			end
		end))
	else
		InstancedPart:Destroy()
	end
end

then put the local script in startergui/