We need more context in order to help you out. What code is responsible for the mortar’s functionalities? I know it is embedded in the model, but adding it to the topic makes it easier for other people to understand the situation.
Ok, good idea! Here is all the code used for the Mortar:
--Made by Its4Realzies
local sP = script.Parent
--Attack settings
local projectileSpeed = 75
local attackDamage = script.AttackDamage.Value
local attackRate = script.AttackRate.Value
local attackRange = script.AttackRange.Value
--For rotating Mortar
local base = sP.RotateBase
local baseCFrame = base.CFrame
--For angleing Mortar
local heart = sP.Heart
local heartCFrame = heart.CFrame
--Aims the Mortar toward player
local function aimMortar(player)
print("Aiming Mortar")
local playerCharacter = player.Character
--Faces mortar towards player
local charTorso = player.Character.Torso
base.Gyro.CFrame = CFrame.new(base.Position, charTorso.Position)
--Angles mortar towards player
local origin = heart.Position
local targetPosition = charTorso.Position
local gravity = Vector3.new(0, -game.Workspace.Gravity, 0)
local velocity = (targetPosition - origin - 0.5 * gravity)
heart.Gyro.CFrame = CFrame.new(heart.Position, heart.Orientation + velocity)
end
--Finds nearest Player
local function findNearestPlayer()
local lastDistance = math.huge
local toReturn
for _,plr in ipairs(game.Players:GetChildren()) do
local plrCharacter = plr.Character
if (plrCharacter ~= nil) and plrCharacter.PrimaryPart ~= nil then
local currentDistance = (plrCharacter:GetPrimaryPartCFrame().p - heart.Position).Magnitude
if currentDistance < lastDistance then
toReturn = plr
lastDistance = currentDistance
end
end
end
return toReturn, lastDistance
end
--Shoots projectile where the barrel is facing
local function fireProjectile()
local newProjectile = Instance.new('Part', sP)
newProjectile.Name = "Projectile"
newProjectile.TopSurface = 0
newProjectile.BottomSurface = 0
newProjectile.Color = Color3.fromRGB(140, 255, 148)
newProjectile.CanCollide = false
newProjectile.Reflectance = -0.5
newProjectile.Shape = 'Ball'
newProjectile.Size = Vector3.new(3, 3, 3)
newProjectile.Position = heart.Position
newProjectile.Orientation = heart.Orientation
newProjectile.Velocity = newProjectile.CFrame.lookVector * projectileSpeed
newProjectile.Touched:Connect(function(part)
if part ~= heart and part ~= sP.Stripe and part ~= sP.Barrel and part ~= sP.HingedSupport then
local particleHolder = Instance.new("Attachment", sP.AnchorBase)
particleHolder.Name = "ParticleHolder"
particleHolder.Position = newProjectile.Position
particleHolder.WorldPosition = newProjectile.Position
local newParticle = script.SplashEffect:Clone()
newParticle.Parent = particleHolder
newProjectile:Destroy()
wait(1)
newParticle.Enabled = false
wait(3)
newParticle:Destroy()
particleHolder:Destroy()
end
end)
end
local RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(function()
local targetingPlayer, playerDistance = findNearestPlayer()
if targetingPlayer ~= nil and playerDistance < attackRange then
aimMortar(targetingPlayer)
else
base.Gyro.CFrame = baseCFrame
heart.Gyro.CFrame = heartCFrame
end
end)
while wait(1) do
local targetingPlayer, playerDistance = findNearestPlayer()
if targetingPlayer ~= nil and playerDistance < attackRange then
fireProjectile()
end
end
Edit for some reason the mortar lags a bit, but that could just be my low-end computer. There are no errors, It just the mortar is not angling the barrel in the way demonstrated in the photo above.
I would try to avoid BasePart.Orientation
, cause it sometimes acts weird. You can set both the position and rotation by setting the CFrame.
This is the problem, cause you are firing it in the wrong direction. The rest of the code looks fine to me.
Ok, how do I fix this? I cant do heart.Oreintation because of its body gyro
I think this should work:
-- Setting it to heart.Gyro.CFrame would look unrealistic
newProjectile.CFrame = heart.CFrame
Now it should fire the projectile perpendicular to ‘heart’. If it does not solve your problem, then local function aimMortar(player)
is responsible for that.
Hearts.CFrame is always the same due to gyro though right?
Its still missing the player in most cases why is that??? Edit: what’s wrong with my math?
Well, not exactly, cause this is what your mortar is actually aiming at, rather than its aiming goal.
Your mortar is not aiming correctly.
Do you know how I could get the effect I intended?
It involves quite a bit of maths, so will just give you an article on this topic: Projectile Motion Tutorial for Arrows and Missiles in Unity3D – Volkan Ilbeyli – Graphics Programmer.
The idea is that you need to find the initial velocity vector for your projectile. You can then aim your cannon in the direction of that vector and finally fire the projectile with the magnitude of that vector.
How do I get the launch angle???
I am having problems applying just about everything. Here is what I have so far:
–Start and end of projectiles path
local startPosition = sP.Position
local targetPosition = target.Position
–We don’t care about the y-component of the initial and target position.
local projectileXZPos = Vector3.new(heart.Position.X, nil, heart.Position.Z)
local targetXZPos = Vector3.new(targetPosition.Position.X, nil, targetPosition.Position.Z)
--Shorthands for the formula
local R = Vector3.Distance(projectileXZPos, targetXZPos)
local G = workspace.Gravity
local tanAlpha = math.Tan(LaunchAngle * math.Deg2Rad)
local H = targetPosition.Y - startPosition.Y
--Calculate the local space components of the velocity
--Required to land the projectile on the target object
local Vz = Mathf.Sqrt(G * R * R / (2.0f * (H - R * tanAlpha)) );
local Vy = tanAlpha * Vz;
Can you help me get the velocity?
Alright, so what you are trying to solve is a parabolic arc. @EgoMoose made a great article covering parabolic arcs and it should help you. You should check it out, as it’s a great tutorial.
A less complicated way of doing this is rotating the motor so it’a facing the player, calculating the magnitude of the motor and the player. (For example if the player X and Z axis is negative - then rotate the motor a little backwards by * the magnitude. You will have to play around to see which orientation is most accurate) Then add a VectorForce straight up into the sky and destroying the VectorForce a second later.
I am aware. In fact, I have posted that exact article as a source I was trying to use in my previous post trying to fix this Mortar. How do I angle a projectile to hit a player I don’t how to apply that logic to the angle of the Mortar.
You don’t. You apply it to the projectile and then get the angle using the projectile position and direction.
Could you give me example of code (I suck at math)
Yes. I am currently working on it but I am having trouble setting up the parabolic equation. However, I should have something done by today.
Alright, I have completed it. Note that this is really more of a proof-of-concept for you to work off of and not a fully capable model.