Bobbing effect on part

Server script inside a part

local TweenService = game:GetService('TweenService')

local Entity = script.Parent

local tweenInfo = TweenInfo.new(
	1,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	-1,
	true
)

local NewPosition = Entity.Position + Vector3.new(0, -0.5, 0)
 
local Tween = TweenService:Create(Entity, tweenInfo, {Position = NewPosition})

Tween:Play()

while wait() do
	Entity.Orientation = Vector3.new(0, Entity.Orientation.Y + 2, 0)
end

Works, just wondering if there’s a better/cleaner way. Especially if I’m gonna have multiple of these scripts running at once (all entities stored under a folder, and as part of Debris, so they get removed after a set period of time) In particular to remove the while loop. Or if I should convert to client somehow (not sure I wanna do that as then other players won’t see the effects, only the one player)
robloxapp-20191228-1735025

Hey.

I don’t think there is a way to fully remove the while loop without resorting to unanchoring the part and applying other physics handled effects such as RotVelocity, BodyAngularVelocities, etc.

However, the script you have right now shouldn’t be too much of an issue.

To optimize the handling, you can probably compress all of these blobs to a single script, instead of having one new script per each blob.

This is actually not that hard to achieve.

You can either make a folder specifically for Blobs (which is what I believe you’re doing based on what you wrote on your thread), or use the CollectionService (which I would recommend if it wasn’t for the fact you’re deleting them after a set amount of time) to tag each blob and run a loop to handle them.

For any of these methods, you will need to create the blob on the server. I’m assuming you already do this, but if not, you can easily implement this using a RemoteEvent.

Folder Method

This is a really easy one to implement.

All you have to take into count for this one is that all the blobs that have the effect should be parented under the same Folder.

The Tween should be created upon blob creation, although do keep in mind this can create stress on the server with many blobs (> ~100, depends on how much server stress already exists) existing.

All you’d need for this method is a single script, iterating through the Blobs folder and applying the rotation.

This saves you a loop per blob, which can be a lot considering many blobs.

local Folder = workspace -- replace workspace with the Folder's reference

while wait() do
    for i, v in ipairs(Folder:GetChildren()) do
        v.Orientation = Vector3.new(0, v.Orientation.Y + 2, 0)
    end
end

As you can see, this is a relatively easy and fast method to use, and it does help out with the server stress put by having multiple scripts and loops.

Collection Service

The Collection Service is really useful as it lets you quickly tag objects and also get those objects tagged with specific tags.

In this case, we’d be tagging the blobs, so that a Folder is not required.

This is really easy to implement.
When creating the blob (same way as the Folder Method), tag the blob object:

game:GetService('CollectionService'):AddTag(Entity, "Blob")

Now that this is done, we can loop through a table returned by the CollectionService that contains all those blobs, regardless of whatever parent they may have!

local CollectionService = game:GetService('CollectionService')

while wait() do
    for i, v in ipairs(CollectionService:GetTagged("Blob")) do
        v.Orientation = Vector3.new(0, v.Orientation.Y + 2, 0)
    end
end

However, even these methods can cause server lag when too many blobs exist. That’s when I’d propose the next step:

Client Sided Visualization

Right, this most likely won’t be needed if you have a very low amount of blobs. However, when we enter a big amount of blobs being visualized, the lag can be noticed.

The fix for this is to convert the visualization to full client side.

This means firing a remote upon creation of the entity so that clients can run the tween, and handling the rotations in the client.

This is actually also very easy to implement, and the benefits are many.

Sorry for a slightly big post, hopefully it helps you out. :sweat_smile:

2 Likes

Sorry for such a long delay in response! :grimacing: thanks for going into such detail! :smiley: I’ve been working on creating a modular system for this, so it’s cleaner, works with multiple parts, etc.

local EntityControl = {}

local CollectionService = game:GetService('CollectionService')
local Debris = game:GetService('Debris')
local TweenService = game:GetService('TweenService')

local Entites = workspace:WaitForChild('Entities')

local EntityData = {
	['Wood'] = {Color = Color3.fromRGB(86, 66, 54)},
	['Stone'] = {Color = Color3.fromRGB(120, 120, 120)},
}

local Info = TweenInfo.new(
	1,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	-1,
	true
)

function EntityControl:Create(entityType, amount, position)
	for i = 1, amount do
		local Entity = Instance.new('Part')
		Entity.Color = EntityData[entityType].Color
		Entity.Material = Enum.Material.SmoothPlastic
		Entity.Name = entityType
		Entity.Position = position
		Entity.Anchored = true
		Entity.CanCollide = false
		Entity.Size = Vector3.new(1, 1, 1)
		
		Entity.Parent = Entites

		Debris:AddItem(Entity, 5)
		
		local NewPosition = Entity.Position + Vector3.new(0, -0.5, 0)
	 
		local Tween = TweenService:Create(Entity, Info, {Position = NewPosition})
		
		Tween:Play()
		
		spawn(function()
			while wait() do
				Entity.Orientation = Vector3.new(0, Entity.Orientation.Y + 2, 0)
			end
		end)
	end
end

return EntityControl

Few things I’m still trying to figure out/work on

  • Having the entities ‘pop out’ instead of just appear abruptly (they currently just appear and bob up and down), would be cool to have them pop out kinda like minecraft, and have them fall to the ground
  • And having them pop out at a kinda random spot, bob up and down at a random time, instead of being clustered together

Currently what it looks like: (there are 3 entities, however since they all the same positions, etc. they just form into 1)
robloxapp-20191230-1658494