It should be a low angle though? There’s barely a difference in the Y. This is from a linear trajectory’s perspective.

XRotation might not matter much in my mortar, as it would be easier for the player to aim manually. But YRotation would be essential to get a sense of where the projectile was going to land.

I watched a part of the video, I didn’t understand anything lol, I don’t speak English it gets worse

So how could I get the Y rotation?

I probably explained it wrong, I’m sorry,

from what @BurningEuphoria said, maybe you thought I wanted a straight shot, with no gravity etc

idk, I don’t understand anything about angles

I’d take note of how to get the XRotation just in case you’re looking at making the mortar aim itself eventually.

To get YRotation, all you need is some simple trig:

```
local YRotation = math.acos(mortar.CFrame.LookVector:Dot((endPos - startPos).unit))
```

It’s also worth mentioning that both my answers give the angle in radians - if you want the angle in degrees, use math.deg():

```
local YRotation = math.deg(angle in radians)
```

This rotation is how much you have to rotate the mortar from where it currently is to make it face the target. It’s not the rotation from where the mortar would be facing if YRotation started at 0.

This angle is very small, the target is considerably far away.

Code:

```
local dh = target.Position.Y - muzzle.Position.Y
local dx = ((target.Position - target.Position) * Vector3.new(1, 0, 1)).Magnitude
local XRotation = (math.acos(((g * (dx^2) / (200^2)) - dh) / math.sqrt((dh^2) + (dx^2))) + math.atan(dx/dh))/2
local YRotation = math.acos(script.Parent.Parent:GetModelCFrame().LookVector:Dot((target.Position - muzzle.Position).unit))
print(XRotation)
print(YRotation)
```

edit: both initial angles of the mortar were at 0

Another method:

Using the angle of the mortar and the speed, we can easily calculate the velocity by this:

```
function fire(angle, distancearc, g)
local vx = math.sin(angle)
local vy = math.cos(angle)
local speed = 3 -- let's say three for now.
while distancearc > 0 do
distancearc -= 1
part.Position.X += vx * speed
part.Position.Y += vy * speed
vx -= (1-g)*vx*2
vy -= (1-g)*vy*2
wait(0.14)
end
end
```

when 0 < g < 1.

This function, given a said angle, will fire the part in that `angle`

, applying the force `g`

.

The math isn’t VERY accurate, but it’s an example to give you an idea of what you would do in this case.

```
fire(script.Parent.Parent.MantletBase.Rotator.TargetAngle,(target.Position - muzzle.Position).Magnitude,workspace.Gravity)
```

I don’t know if I’m using the correct form

Yes, I get this error a-lot. This error happens when you attempt to set `Position.X`

a value. Instead of this, try creating a new `Vector3.new`

value and setting the `part.Position`

to it.

Honestly, I wasn’t even taking that script seriously because I had thought you already had your answer.

Let me explain it to you:

This website here demonstrates finding the `math.cos`

and `math.sin`

of an angle.

as you can see, the `math.sin()`

represents the y increase if you moved in a 2-dimensional direction of theta (*the angle*) and the same for `math.cos`

. Now, notice of the radius of that circle is ALWAYS 1. Since we know that 1 times any number is always going to be that number, if we just multiply the `vx`

and `vy`

values by `speed`

you’ll increase the size of that circle, and move farther.

These are just simple trigonomic functions. Understanding `math.sin()`

and `math.cos()`

is crucial to any spatial related programming.

Now, all we have to do to implement gravity, is over time, change that angle of movement. There are two ways you can do this, first, the method I used by just subtracting of off the `vx`

and `vy`

, or two, subtracting of the ORIGINAL angle, and from there finding the `math.cos()`

and `math.sin()`

of that angle.

Example:

```
if (math.pi/2) < angle and angle < (3*math.pi/2) then
angle += math.pi /180 -- one degree
else if (math.pi/2) > angle or (3*math.pi.2) < angle then
angle -= math.pi/180 -- one degree
end
```

What this script does, is checks if the current moving angle is greater than 90 degrees and less than 270 degrees (moving down), then it adds a degree to the movement of the angle. Else, if it’s less than 90 degrees, OR greater than 270 degrees, it subtracts a degree from the angle.

The projectile (in this case the Part) when I shoot, it appears, possibly it is setting an unwanted position

```
function fire(angle, distancearc, g)
local vx = math.sin(angle)
local vy = math.cos(angle)
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(5,5,5)
local speed = 3 -- let's say three for now.
while distancearc > 0 do
distancearc -= 1
part.Position += Vector3.new(vx * speed,0,0)
part.Position += Vector3.new(0,vy * speed,0)
vx -= (1-g)*vx*2
vy -= (1-g)*vy*2
print(part.Position)
wait(0.14)
end
end
```

I’ll take a look at that when I’m done. thank you very much for the explanation

This code wasn’t mean’t to handle 3 dimensional gravitation pull.

I suggest creating your own formula like this one, but for your script, since I don’t know how your script is setup.

Oh, this is going to be impossible for me, because I don’t know anything about it

Thank you anyway

```
function fire(angle, distancearc, g)
local vx = math.sin(angle)
local vy = math.cos(angle)
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(5,5,5)
local speed = 3 -- let's say three for now.
while distancearc > 0 do
distancearc -= 1
part.Position += Vector3.new(vx,vy,0)
if (math.pi/2) < angle and angle < (3*math.pi/2) then
angle += math.pi /180 -- one degree
else if (math.pi/2) > angle or (3*math.pi.2) < angle then
angle -= math.pi/180 -- one degree
end
vx -= math.cos(angle) * speed
vy -= math.sin(angle) * speed
wait(0.14)
end
end
```

Consider using this instead

is this in a 2d space?

I don’t know, if it is, I tested it and it was a little wrong xd

yes, this is for 2d.

I can’t currently think of way to do the same thing but for 3d but i’m pretty sure it’s the same thing.

And yes it’ll be a little wrong because it won’t be moving on the z-axis

oh ok, last thing. What is this calculation called? I’ll try to move to 3D as my “great skills”, and I’ll see your explanation in Reply above.

and small mistake here I think:

math.pi.2

Ooh goodie a question I can answer.

A very easy function I used is here

```
function getPredictedPosition(targetPosition: Vector3, targetVelocity: Vector3, projectileSpeed: Number, shooterPosition: Vector3, shooterVelocity: Vector3, gravity: Number)
local distance = (targetPosition - shooterPosition).Magnitude
local p = targetPosition - shooterPosition
local v = targetVelocity - shooterVelocity
local a = Vector3.new() -- Placeholder
local timeTaken = (distance / projectileSpeed)
if gravity > 0 then
local timeTaken = projectileSpeed/gravity+math.sqrt(2*distance/gravity+projectileSpeed^2/gravity^2)
end
local goalX = targetPosition.X + v.X*timeTaken + 0.5 * a.X * timeTaken^2
local goalY = targetPosition.Y + v.Y*timeTaken + 0.5 * a.Y * timeTaken^2
local goalZ = targetPosition.Z + v.Z*timeTaken + 0.5 * a.Z * timeTaken^2
return Vector3.new(goalX, goalY, goalZ)
end
```

I used this when creating archers for my line warefare rts.

This video has a good explanation.

Really you can use the SUVAT equations or Calculus to solve this. (I prefer the calculus so that I don’t have to memorise 100 different formulas lol)

If you only want to get the angle. Then simply you can solve for 2d the hieght of the target relative to the shooter and the distance would be x. Then you can simple use atan2(X and Z) to find the “floor” angle

omg, that’s it, thanks!

thanks also to:

@Den_vers

@RatiusRat

@BurningEuphoria

Thank you for taking the time to help me!

Hey uh… is that your code? Or did you happen to take the source code from some Unity gamedev page?