How do I Rotate a Projectile?

  1. What do you want to achieve?
    I’m trying to make my projectile rotate 360 degrees (continuously) while it’s traveling towards an NPC. I’ve tried to change the CFrame Angles but it’s not working :confused:

  2. What is the issue?
    Vimeo Link: https://vimeo.com/728213840

  3. What solutions have you tried so far?
    I’ve tried looking into CFrames, the DevForum & rewriting the code but I haven’t had any luck.

Script w/in “Fire” RemoteEvent:
Screen Shot 2022-07-08 at 12.37.18 PM

function tagHumanoid(humanoid, player)
	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = player
	creator_tag.Name = "creator"
	creator_tag.Parent = humanoid
end

function untagHumanoid(humanoid)
	if humanoid ~= nil then
		local tag = humanoid:findFirstChild("creator")
		if tag ~= nil then
			tag.Parent = nil
		end
	end
end


script.Parent.OnServerEvent:Connect(function(plr)
	local Alive = true
	local Projectile = game.ReplicatedStorage.Bazooka.Bazooka2.Shot:Clone()
	Projectile.Parent = workspace
	Projectile.CanCollide = false
	Projectile.Anchored = false
	Projectile.CFrame = plr.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,0) * CFrame.fromEulerAnglesXYZ(0,360,0)
	Projectile.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= plr.Name then
			local HitEffect1 = game.ReplicatedStorage.Bazooka.Bazooka2.HitFX1:Clone()
			local HitEffect2 = game.ReplicatedStorage.Bazooka.Bazooka2.HitFX2:Clone()
			local HitEffect3 = game.ReplicatedStorage.Bazooka.Bazooka2.HitFX3:Clone()
			local VCharacter = game.Workspace:FindFirstChild(plr.Name)
	        local vPlayer = game.Players:GetPlayerFromCharacter(VCharacter)
			HitEffect1.Parent = workspace
			HitEffect1.CFrame = hit.Parent.HumanoidRootPart.CFrame
			HitEffect1.CanCollide = false
			HitEffect1.Anchored = true
			HitEffect2.Parent = workspace
			HitEffect2.CFrame = hit.Parent.HumanoidRootPart.CFrame
			HitEffect2.CanCollide = false
			HitEffect2.Anchored = true
			HitEffect3.Parent = workspace
			HitEffect3.CFrame = hit.Parent.HumanoidRootPart.CFrame
			HitEffect3.CanCollide = false
			HitEffect3.Anchored = true
			hit.Parent.Humanoid:TakeDamage(30 + plr.Data.Gun.Value)
			tagHumanoid(hit.Parent:FindFirstChild("Humanoid"),vPlayer)
			Projectile:Destroy()
			wait(0.05)
			untagHumanoid(hit.Parent:FindFirstChild("Humanoid"))		
			for i = 1,18 do
				wait(.05)
				HitEffect1.Size = HitEffect1.Size + Vector3.new(0.5,0.5,0.5)
				HitEffect1.Transparency = HitEffect1.Transparency + 0.1
				HitEffect2.Size = HitEffect2.Size + Vector3.new(0.5,0.5,0.5)
				HitEffect2.Transparency = HitEffect2.Transparency + 0.1
				HitEffect3.Size = HitEffect3.Size + Vector3.new(0.5,0.5,0.5)
				HitEffect3.Transparency = HitEffect3.Transparency + 0.1
				
			end	
			HitEffect1:Destroy()
			HitEffect2:Destroy()
			HitEffect3:Destroy()
			
		end
	end)
	local BV = Instance.new("BodyVelocity",Projectile)
	BV.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
	BV.Velocity = plr.Character.HumanoidRootPart.CFrame.LookVector * 65
	for i = 1,20 do
				wait(.025)
				Projectile.Transparency = Projectile.Transparency + 0.05
			end
    Projectile:Destroy()
    end)

Local Script w/in tool:
Screen Shot 2022-07-08 at 12.40.44 PM

local Tool = script.Parent

Tool.Equipped:Connect(function()
	Tool.Equip.Value = true
end)

Tool.Unequipped:Connect(function()
	Tool.Equip.Value = false
end)

local UIS = game:GetService("UserInputService")
local plr = game.Players.LocalPlayer
local Mouse = plr:GetMouse()
local Debounce = true
Player = game.Players.LocalPlayer
Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://5175015910"


local Sound = script:WaitForChild("SoundTest")
local function Text(hit,Damage)
	local UIDamage = Instance.new("Part",game.Workspace) UIDamage.Name = "TagDamage"
	UIDamage.Transparency = 1
	UIDamage.Anchored = true UIDamage.CanCollide = false
	UIDamage.CFrame = hit.Head.CFrame * CFrame.new(math.random(-3,3),math.random(1,3),math.random(-3,3))
	local UI = Instance.new("BillboardGui",UIDamage) UI.MaxDistance = 50
	local Text = Instance.new("TextLabel",UI)
	Text.BackgroundTransparency = 1
	Text.Font = Enum.Font.Cartoon
	Text.TextScaled = true
	Text.TextColor3 = Color3.fromRGB(255,0,0)
	Text.Text = "-" ..Damage
	Text.TextStrokeTransparency = 1
	UI.Size = UI.Size + UDim2.new(0,200,0,50)
	Text.Size = Text.size + UDim2.new(0,200,0,50)
	game.TweenService:Create(Text,TweenInfo.new(2),{TextTransparency = 1}):Play()
	game.TweenService:Create(UIDamage,TweenInfo.new(2),{CFrame = UIDamage.CFrame * CFrame.new(math.random(-3,3),math.random(3,5),math.random(-3,3))}):Play()
	game.Debris:AddItem(UIDamage,2)
end
UIS.InputBegan:Connect(function(Input)
	if Input.UserInputType == Enum.UserInputType.MouseButton1 and Debounce == true and Tool.Equip.Value == true and Tool.Active.Value == "None" then
		Debounce = false
		Sound:Play()
		Tool.Active.Value = "Pistol"
		wait(0.05)
		Track1 = Player.Character.Humanoid:LoadAnimation(Animation)
		Track1:Play()
		wait(0.15)
		script.Fire:FireServer(plr)
	local hum =  Player.Character.Humanoid
	for i = 1,30 do
		wait()
		hum.CameraOffset = Vector3.new(
			math.random(0,0),
			math.random(0,0),
			math.random(0,0)
		)
	end
	hum.CameraOffset = Vector3.new(0,0,0)
		Tool.Active.Value = "None"
		Debounce = true
	end
end)

I also tried putting a script in the part for it to spin:
Screen Shot 2022-07-08 at 12.38.28 PM

while true do
for a=0,990,.5 do
script.Parent.CFrame=CFrame.new(script.Parent.Position)*CFrame.fromEulerAnglesXYZ(math.rad(0),math.rad(a),math.rad(0))
wait(0)
end
end

If the projectile is not anchored, you can try using :ApplyAngularImpulse(Vector3). You can also just set the AssemblyAngularVelocity of the part.

If you’re really desperate, you can look into an older solution, which is using a BodyAngularVelocity. I wouldn’t recommend this as it is deprecated, but it does work.

You can use AlignOrientation to set the CFrame rotation of a BasePart as well, without having any snappiness.

1 Like

here is a demo project
SpinningProjectile.rbxl (35.0 KB)

this is the code in the project

local position1 = workspace:WaitForChild("From").Position
local position2 = workspace:WaitForChild("To").Position

local direction = position2 - position1
local duration = math.log(1.001 + direction.Magnitude * 0.01)

local force = direction / duration + Vector3.new(0, game.Workspace.Gravity * duration * 0.5, 0)

while true do
	task.wait(1)
	local clone = game.ReplicatedStorage.Projectile:Clone()
	clone.CFrame = CFrame.new(position1, position2)
	clone.Parent = workspace
	
	clone:ApplyImpulse(force * clone.AssemblyMass)
	
	local rotate = clone.CFrame:VectorToWorldSpace(Vector3.new(0, 0, 10))
	clone:ApplyAngularImpulse(rotate * clone.AssemblyMass)
end

and here is a video explaining how it works

3 Likes