Need help with character attacking

Idk what to name this topic

Hi, Currently I’m working on a tower defense game (not for crashgrab or a simulator) and I want to make a rig or character that throws a bullets or grenades like this:

but the thing is that I don’t have any idea how to acheive this I can only make a simple attacking character like this:


this one is attacking in a straight line which is not what I want.

Any help will be apprecaited and it would be nice if you give an explanation with your reply of how it works because i did found a solution on Youtube but it just gave a script with no explanation which just sucks because i wanna customize more things in my game with any explanation.

Dont mind my drawing please

2 Likes

I’m not sure how to explain this, but you can try making the grenade model go higher on the Y axis the closer it is to the middle of how close it is to the destination on the X axis. Here’s an example:

3 Likes

Here’s a youtube tutorial, hope this helps.

2 Likes

this does help probaly with linear velocity and some scripting i cant make it work.

1 Like

damn this looks good i will mark it as a solution if it works.

1 Like

If you want the grenade part to be anchored and kinda tween position, you’d have to use math.sin() or math.cos()

3 Likes

You don’t have to use physics for this, I’m pretty sure. Imagine that the X axis is the percentage if how close the grenade is to the destination. It starts from 0% and reaches 100% in a certain amount of time. The closer it is to 50%, the higher the grenade model will be.

I don’t know the exact calculations for this, but I hope my point gets across.

2 Likes

I think I know how to calculate it because I use magnitude and distance between parts alot so sure it will work but the problem is now that both @lgotanintendoswitch solution and your solution works so idk which to mark as solution and which one is better to use /:

2 Likes

I managed to create what I meant in Studio. Here’s the place file for it:
Linear Grenade Throw Test.rbxl (45.5 KB)

2 Likes

I suggest not using Roblox physics when the opportunity is given. It requires more resources and client replication can be a mess, especially with exploiters.

2 Likes

yeah it works prefectly fine tysm : D

2 Likes

I know its pretty late but can you also give an explanation of the script if u can?

1 Like
The script with comments
local HEIGHT = 24 -- The peak height of the throw curve.
local TIME = 2 -- Time it takes for the grenade to reach the destination while moving along the curve.

local start_part = workspace.Start -- Part for setting the start position. Not necessary if position is already given
local end_part = workspace.End -- Part for setting the end position. Not necessary if position is already given, too.
local grenade = script.Grenade -- Test grenade part.
grenade.Parent = workspace

local current_time = 0 -- The elapsed time since a throw was initiated. Resets back to 0 every loop.

while true do -- Initate the loop, just for testing purposes.
	local percentage = current_time / TIME -- Divide the current time with the TIME variable, to know how much the grenade has moved along the curve from 0% to 100%.
	
	local direction = end_part.Position - start_part.Position -- Direction vector that points from the start position to the end position.
	local linear_position = start_part.Position + direction * percentage -- The actual linear position of the grenade, from the start position to the end position, without height.
	local height_position = Vector3.new(0, math.sin(percentage * math.pi) * HEIGHT, 0) -- The mere height position of the grenade.
	
	grenade.Position = linear_position + height_position -- Set the grenade part's position to the linear position combined with the height position!
	
	current_time += task.wait() -- Add a delay to the loop for obvious reasons, and increment the elapsed time since the throw was initiated.
	
	if current_time > TIME then -- Check if the elapsed time has reached the end of the throw.
		current_time = 0 -- Reset the elapsed time back to 0, just for testing purposes.
		
		-- boom
		local explosion = Instance.new("Explosion")
		explosion.Position = grenade.Position
		explosion.Parent = workspace
	end
end

Not sure how to explain it well, but the way I imagine it goes like this:

Pretend there is a straight, 3D line that goes from the start position to the end position; that is the direction vector on which the grenade will be moving along. Then, you use the sinus operation to find the current height of the grenade. When the throw is halfway done, the grenade’s height will be at its peak, aka the HEIGHT constant (math.sin(percentage * math.pi) * HEIGHT). All of that happens accordingly to the elapsed time since the throw was initiated while positioning the grenade part on an imaginary curve.

The reasons why it’s better to use these simple physics than using Roblox’s physics or ray-casting are:

  1. It’s not CPU intensive.
  2. More reliable and configurable calculations.
  3. Not exploitable by clients.
  4. it just be easy like dat man

Here’s a visualization that demonstrates what happens:

2 Likes

In addition to that, you can make things like missiles as well!

2 Likes

I didn’t thought you would’ve explain this well I just tested it in my game and it worked like perfection, probaly best explaination i’ve ever seen tysm only one question is i have is that it better to use game:GetService("RunService").PreSimulation:Wait() or task.wait for the loop, probaly pretty dumb question but was just curious. also pretty cool cat you had there

2 Likes

Pretty sure they do the same thing, but honestly I’d go with task.wait() cause it’s just shorter lol. I typed game:GetService("RunService").PreSimulation:Wait() out of tiredness.

2 Likes

Alr thanks again for this amazing explanaition :smiley:

2 Likes