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?