How to make a projectile (arrow) fly face-first towards the enemy

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I’m creating a Tower Defense game, I have a tower and a mob. I want the arrow to fly face-first towards the enemy

  2. What is the issue? Include screenshots / videos if possible!
    The arrow for some reason changes its rotation flying sideways to the RootPart, although its rotation is not spelled out anywhere.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I looked at the documentation, tried to read the posts on the forums, but none of this helped me. I also thought a lot about CFrame.lookAt thinking that it might help, but it didn’t help

local function FireProjectile(tower, target)
    local projectile = Instance.new("Part")
    
    projectile.Size = Vector3.new(1,1,1)
    projectile.CFrame = tower.Head.CFrame
    projectile.Anchored = true
    projectile.CanCollide = false
    projectile.Transparency = 0.5
    projectile.Parent = workspace.Camera
    
    local arrow = tower.Bow.Arrow:Clone()
    arrow.CFrame = tower.Head.CFrame
    arrow.Anchored = true
    arrow.CanCollide = false
    arrow.Transparency = 0
    arrow.Parent = projectile
    
    local projectileTween = TweenService:Create(arrow, TweenInfo.new(0.1), {Position = target.HumanoidRootPart.Position)})
    projectileTween:Play()
    Debris:AddItem(projectile, 0.1)
end
1 Like

Try changing {Position = target.HumanoidRootPart.Position} to {CFrame = target.HumanoidRootPart.CFrame}

Full code:

local projectileTween = TweenService:Create(projectile, TweenInfo.new(0.1), {CFrame = target.HumanoidRootPart.CFrame)})
Reminder

You prolly already know but setting something’s CFrame to another CFrame accounts for both position AND rotation

2 Likes

This simply turns the arrow to the side where the HumanoidRootPart is turned.

Best solution I’ve found with TweenService is to set the arrow’s CFrame to look at the enemy from it’s origin (a great way to do this is to use CFrame.lookAt(Origin : Vector3, Target : Vector3)!), then tween it’s position.

3 Likes

Alright, I just fixed this by changing CFrame parameters and adding distance using LookVector

local function FireProjectile(tower, target)
	local arrow = tower.Bow.Arrow:Clone()
	arrow.CFrame = CFrame.new(tower.Head.Position, target.HumanoidRootPart.Position)
	arrow.Anchored = true
	arrow.CanCollide = false
	arrow.Transparency = 0
	arrow.Parent = workspace

	local distance = (tower.Head.Position - target.HumanoidRootPart.Position).Magnitude
	local projectileTween = TweenService:Create(arrow, TweenInfo.new(0.1), {CFrame = arrow.CFrame + (arrow.CFrame.LookVector * distance)})
	projectileTween:Play()
	Debris:AddItem(arrow, 0.1)
end

Hope this helps others.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.