Mouse and Tween Problems

I started scripting around 6 months ago, but i have been trying to avoid asking questions thru dev forum, anyways the topic is, i have problems with tweening, specifically related to the mouse. Basically i want to create a tween that faces the mouse but i havent found a proper solution yet.

I did try transferring the mouse via shooting a remote event then creating a tween that was next to the head, i thought it wouldnt have interrupted the part looking at the mouse due to me using position values, not angle values. But it didnt seem to work, it just faced where my character was looking at. ive been trying a bit of modifications but still in vain, so i hope somebody can help me here.

1 Like

Can you please elaborate a bit more on what you mean by this?

2 Likes

It sounds like you’re trying to make a part rotate to face the mouse position. Here’s a simple solution for that, know that it includes using CFrame and not directly tweening:

Roblox scripting uses a data type called CFrame to deal with 3D position and rotation. Part’s CFrame can be set to point in a specific direction.

-- assuming local Mouse and local part are already defined and correct.
part.CFrame = CFrame.lookAt(part.Position, Mouse.Hit.p)

CFrame.lookAt function gives you a CFrame that faces towards a specific point in space.

For building Tween, you can change the transparency gradually for the parts’ appearance

local TweenService = game:GetService("TweenService")

--Here you define start and end position.
local startCFrame = part.CFrame 
local endCFrame = CFrame.lookAt(part.Position, Mouse.Hit.p)

local info = TweenInfo.new(1) -- 1 second duration

-- Here you define how to change the properties of the part.
-- In this case, you're setting CFrame and Transparency
local tween = TweenService:Create(part, info, {CFrame = endCFrame, Transparency = 0.5})

-- Start the tween
tween:Play()

Also pls note that Tweening part.CFrame will not necessarily rotate the part smoothly. Since you are crossing a 3D rotation it might not go exactly the way you expect. Economy of movement will make it look a little bit weird. If you want to avoid such issues you might need to implement your own Tweening solution for rotation.

For continuously updating rotation, you might consider using RenderStepped or Heartbeat event in the RunService.

2 Likes

basically when using a tool, the part is meant to look at the mouse while doing a tween animation

1 Like

i think you misunderstood, i meant that when using a tool, the part will face the mouse while doing a tween animation using position

1 Like

Ah, I see. In that case, you’ll want to use the Tool.Equipped and Tool.Unequipped events to start and stop a loop that continuously updates the part’s CFrame to face the mouse. Here’s a basic example:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local tool = script.Parent -- replace with the path to your tool
local part = tool.Handle -- replace with the path to the part you want to face the mouse

local info = TweenInfo.new(
	2, -- time
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut,
	-1, -- repeat forever
	true, -- reverses
	0 -- delay
)

-- This block runs whenever the tool is equipped
tool.Equipped:Connect(function(mouse)
	local connection
	connection = RunService.RenderStepped:Connect(function()
		local cf = CFrame.lookAt(part.Position, mouse.Hit.p)

		local tween = TweenService:Create(part, info, {CFrame = cf})
        tween:Play()
	end)

	-- This block runs whenever the tool is unequipped
	tool.Unequipped:Connect(function()
		if connection then
			connection:Disconnect()
		end
	end)
end)

Make sure your tool is server-side when using this script. Also, replace ‘tool.Handle’ with the path to your part, if the script is not inside the tool.

1 Like

i do have 1 question, how do i implement the tween in the property table? Do i define the CFrame of the part or the part i set its primary cframe? Example: {CFrame = plr.Head.CFrame * Vector3.new()}, i dont really get it

1 Like

In the example, the tween is created using the TweenService’s Create function. The syntax is:

TweenService:Create(instance, tweenInfo, propertyTable)

The propertyTable is a table where the keys are the names of the properties you want to tween, and the values are the final values you want those properties to have when the tween finishes. For instance:

TweenService:Create(part, info, {Position = Vector3.new(0, 50, 0), Transparency = 1})

In this case, the Position property of part will be tweened to Vector3.new(0, 50, 0) and the Transparency will be tweened to 1.

In your case, you want the CFrame of the part to be tweened to the CFrame that looks at the mouse, so you use:

local cf = CFrame.lookAt(part.Position, mouse.Hit.p)
local tween = TweenService:Create(part, info, {CFrame = cf})

So the CFrame of the part will be tweened to the cf variable, which is set to the CFrame that looks at the mouse’s position.

Now, to your second question

In this context, you are defining the desired CFrame for the tool part to be tweened to. You are effectively saying, “I want the part’s CFrame to become this over a set duration and easing style.”

In the following line:

local cf = CFrame.lookAt(part.Position, mouse.Hit.p)

cf is assigned a CFrame that points from your tool’s position (part.Position) to the mouse’s current 3D position (mouse.Hit.p). The lookAt() function generates a CFrame oriented towards the point you passed in.

You then pass cf to the Tween function like this:

local tween = TweenService:Create(part, info, {CFrame = cf})

This will apply a tween to the part that changes its CFrame such that it smoothly transitions to the CFrame you specified (cf), over the specified time and using the defined easing style. The part’s PrimaryPart CFrame (if the parent is a Model) does not need to be explicitly specified for this operation, as it is automatically calculated by Roblox.

1 Like

pardon for being a hassle, but can anybody make a quick tutorial (text) on how to use this script? (p.s, if you can, pls rework the script a lil and clone the model instead of part and make its primary cframe the head), im kinda getting tired of asking questions here so yeah, im still learning about cframes and math scripts so sorry B(

No problems at all, we’re here to help! Here’s how you would implement this for a model using the head as the primary part:

First, declare your services at the top.

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

Next, define your tool and model.

local tool = script.Parent -- replace with the path to your tool
local model = tool.Model:Clone() -- replace Model with actual model's name.
model.Parent = workspace
model.PrimaryPart = model.Head -- assuming model has a Head, else replace 'Head' with actual part's name.

Here we are cloning your original model from the tool so the tool never directly changes. The cloned model is set in workspace and we set the Head as the PrimaryPart (use the actual part’s name if it’s not ‘Head’).

Now, define your TweenInfo

local info = TweenInfo.new(
    0.1, -- time
    Enum.EasingStyle.Linear,
    Enum.EasingDirection.InOut,
    0, -- repeat times
    false, -- reverses
    0 -- delay
)

This sets the properties of our tween. Setting the time to 0.1 will make the model follow the mouse more closely, but feel free to increase the number if you want some delay in the model’s motion.

Then, by using the equipped and unequipped events, we can create a loop that repeatedly sets the CFrame of our model to look at the mouse’s position. We stop the loop when the tool is unequipped.

tool.Equipped:Connect(function(mouse)
    local connection
    connection = RunService.RenderStepped:Connect(function()
        -- face model to mouse
        local cf = CFrame.lookAt(model.PrimaryPart.Position, mouse.Hit.p)
        local tween = TweenService:Create(model.PrimaryPart, info, {CFrame = cf})
        tween:Play()
    end)

    --stop updating when unequipped
    tool.Unequipped:Connect(function()
        if connection then
            connection:Disconnect()
            model:Destroy() -- remove model from workspace when tool is unequipped.
        end
    end)
end)

Remember to replace any references to ‘Model’ and ‘Head’ with your actual model’s and part’s names for model and model.PrimaryPart as needed. I hope this clarifies! Just copy and paste each step into one script ordered consecutively. Do make sure to replace placeholders with your actual object’s names where suggested.

yo, you got it kinda wrong, i meant set the primary cframe of the model the players head, not primary part. btw, sorry for asking again but its supposed to spawn the part facing the camera then tween for 1 second as it rotates to where the mouse had been clicked (click tool btw) also im gonna afk so once im back il try it so yeah, i hope i didnt disturb you lol
:sweat_smile:

No worries!

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Camera = workspace.CurrentCamera

local tool = script.Parent -- replace with the path to your tool
local model = tool.Model:Clone() -- replace Model with actual model's name.

-- We're assuming your character is the parent of the tool. 
-- If not, you'll need to get the character by another method.
local character = tool.Parent
model.PrimaryPart = model.Head -- set the primary part

tool.Equipped:Connect(function(mouse)
	local connection
	connection = RunService.RenderStepped:Connect(function()
		-- initially set the model's primary part to character's head position
		if character:FindFirstChild("Head") then
			model:SetPrimaryPartCFrame(character.Head.CFrame * CFrame.Angles(0,math.rad(180),0))
		end
	end)
	
	mouse.Button1Down:Connect(function()
		local clickedPosition = mouse.Hit.p
		local tween = TweenService:Create(model.PrimaryPart, TweenInfo.new(1), {CFrame = CFrame.lookAt(model.PrimaryPart.Position, clickedPosition)})
		tween:Play()
	end)
	
	--stop updating when unequipped
	tool.Unequipped:Connect(function()
		if connection then
			connection:Disconnect()
			model:Destroy() -- remove model from workspace when tool is unequipped.
		end
	end)
end)

In this script, CFrame.lookAt(model.PrimaryPart.Position, clickedPosition) creates a CFrame for the model’s primary part that looks at the clicked position. It will tween to this CFrame when the mouse is clicked. The part is spawned facing the camera using CFrame.Angles(0, math.rad(180), 0), which rotates it 180 degrees around the vertical axis.

hm, i tried slight modifications but it didnt work.

  local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local tool = script.Parent -- replace with the path to your tool
local model = tool.Model:Clone() -- replace Model with actual model's name.

-- We're assuming your character is the  parent of the tool. 
-- If not, you'll need to get the character by another method.
game.Players.PlayerAdded:Connect(function(plr)

tool.Equipped:Connect(function(mouse)
	local connection = RunService.Heartbeat:Connect(function()
		-- initially set the model's primary part to character's head position
		if plr:WaitForChild("Head") then
			model:SetPrimaryPartCFrame(plr.Head.CFrame * CFrame.Angles(0,math.rad(180),0))

		end
	end)

	mouse.Button1Down:Connect(function()
		local clickedPosition = mouse.Hit.Position
		local tween = TweenService:Create(model, TweenInfo.new(1), {CFrame = CFrame.lookAt(model.Part.Position, clickedPosition)})
		tween:Play()
	end)

	--stop updating when unequipped
	tool.Unequipped:Connect(function()
		if connection then
			connection:Disconnect()
			model:Destroy() -- remove model from workspace when tool is unequipped.
		end
	end)
end)
end)

basically, whenever i equip the tool the model is still in the tool but visible, the model was not rotating to my mouse when i clicked and it wasnt near my head, (btw i noticed you never used the camera to make the model face where the player is looking, maybe edit that too), heres a screenshot:

Right! Here’s how you can implement this:

variables:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local tool = script.Parent -- replace with path to your tool

create a function that takes mouse as parameter. This function will run every time the tool is equipped:

local function onMouseMove(mouse)
    local character = Players.LocalPlayer.Character
    if character then
        if character:FindFirstChild("Head") then
            local modelInWorkspace = tool.Model:Clone() -- clone model
            modelInWorkspace.Parent = workspace -- set parent to workspace
            modelInWorkspace.PrimaryPart = modelInWorkspace.Head -- set primary part to Head
            
            RunService.Heartbeat:Connect(function()
                --set the model's CFrame to the player's head CFrame if it exists or keep the model at its initial CFrame
                modelInWorkspace.PrimaryPart.CFrame = character.Head.CFrame
            end)
            mouse.Button1Down:Connect(function()
                local cf = CFrame.lookAt(modelInWorkspace.PrimaryPart.Position, mouse.Hit.p)
                local tween = TweenService:Create(modelInWorkspace.PrimaryPart, TweenInfo.new(1), {CFrame = cf})
                tween:Play()
            end)
        end
    end
end

connect this function to the Equipped event of the tool:

tool.Equipped:Connect(onMouseMove)

In this version, whenever you move your mouse the model in the workspace’s Head, which is set as the model’s PrimaryPart, will follow the rotation of your character’s head. If the mouse button is pressed down, the PrimaryPart will tween its CFrame to face the mouse’s 3D position in the workspace. Rename ‘Model’(in tool.Model:Clone()) and ‘Head’(in modelInWorkspace.Head) with the exact names of your model and part in your tool. Remember, Mouse Button1Down only fires when pressed on Workspace and GUI buttons so it may not work as accurately in the 3D world. Going AFK for 15 hours, good luck!

seems like we live in the same timezone (lol) anyways, i already tried modifying again (btw keep note localplayer is only for local scripts) but its the same problem as before but this time the tool is cloned and placed into the character? or smth but the object isnt there, something is wrong again :((( (i already tried putting model in the tool, it was the same result but the object was visible, what do i do/???

 local TweenService = game:GetService("TweenService")
 local RunService = game:GetService("RunService")
local character = script.Parent.Parent
 local tool = script.Parent
local model = game:GetService("ReplicatedStorage").Model
local modelInWorkspace = model:Clone()


local function onMouseMove(mouse)
if character then
print(plr)
    if character:FindFirstChild("Head") then
        modelInWorkspace.Parent = workspace 
 modelInWorkspace:SetPrimaryPartCFrame(CFrame.new(plr.Head.Position + Vector3.new(0,1,0)))
        
        RunService.Heartbeat:Connect(function()
            --set the model's CFrame to the player's head CFrame if it exists or keep the model at its initial CFrame
            modelInWorkspace.PrimaryPart.CFrame = character.Head.CFrame
        end)
        mouse.Button1Down:Connect(function()
            local cf = CFrame.lookAt(modelInWorkspace.PrimaryPart.Position, mouse.Hit.p)
            local tween = TweenService:Create(modelInWorkspace.PrimaryPart, TweenInfo.new(1), {CFrame = cf})
            tween:Play()
        end)
    end
end
end

 tool.Equipped:Connect(onMouseMove)

Let’s walk through your code.

You’ve defined modelInWorkspace outside any function or event. It’s better to clone the model inside the Equipped event right after checking for the Head.

Moving the model’s PrimaryPart to the head position can be done right inside the Heartbeat connection. I noticed you used plr.Head in your SetPrimaryPartCFrame function but haven’t defined plr.

To fix these, we modify the code like:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local tool = script.Parent -- replace with path to your tool

local function onMouseMove(mouse)
    local playerCharacter = mouse.UserInputService.Codename

    if playerCharacter == nil then
        return
    end

    if playerCharacter.Head ~= nil then
        local modelInWorkspace = game:GetService("ReplicatedStorage").Model:Clone()
        modelInWorkspace.Parent = workspace -- set parent to workspace
        modelInWorkspace.PrimaryPart = modelInWorkspace.Head -- set primary part to Head

        local HeartbeatConnection
        HeartbeatConnection = RunService.Heartbeat:Connect(function()
            --set the model's CFrame to the player's head CFrame if it exists or keep the model at its initial CFrame
            modelInWorkspace.PrimaryPart.CFrame = playerCharacter.Head.CFrame
        end)
        mouse.Button1Down:Connect(function()
            local cf = CFrame.lookAt(modelInWorkspace.PrimaryPart.Position, mouse.Hit.p)
            local tween = TweenService:Create(modelInWorkspace.PrimaryPart, TweenInfo.new(1), {CFrame = cf})
            tween:Play()
        end)
        tool.Unequipped:Connect(function()
            HeartbeatConnection:Disconnect()  --disconnect from the Heartbeat event
            modelInWorkspace:Destroy() --cleanup the model when the tool is unequipped
        end)
    end
end

tool.Equipped:Connect(onMouseMove)

This code fetches the player’s character from the UserInputService.Codename of the passed mouse argument. But!! Creating a model everytime and updating every frame can quickly become inefficient and might lag on low-end devices. I would recommend you to setup your model once and modify parts instead.