求助:使用Tween移动Part后,其位置无法通过脚本或工具修改
解决Roblox Tween结束后Part无法修改位置的问题
我尝试用Tween平滑移动Part,脚本会创建Part并在1秒内移到目标位置,但移动完成后,不管是用移动工具还是脚本都没法修改这个Part的位置。
原问题脚本
local tweenService = game:GetService("TweenService") local runService = game:GetService("RunService") local player = game.Players.LocalPlayer local RunServiceEvent = nil local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut) function SpawnPart() local part = Instance.new("Part") part.Anchored = true part.Parent = game.Workspace.Clutter.Coins local startPos = Vector3.new(0, 2, 0) part.Position = startPos local TargetPosition = Vector3.new(5, 2, 0) local Tween = tweenService:Create(part, tweenInfo, {Position = TargetPosition}) Tween:Play() local StartTime = tick() RunServiceEvent = runService.RenderStepped:Connect(function() local Time = (tick() - StartTime) / tweenInfo.Time if part == nil then return end if Time > 1 then part.Position = TargetPosition return end end) task.spawn(function() Tween.Completed:Wait() task.wait() RunServiceEvent = nil end) end player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui"):WaitForChild("TextButton").Activated:Connect(SpawnPart)
问题原因
- RenderStepped连接未正确断开:代码仅将
RunServiceEvent设为nil,未调用Disconnect()方法,导致回调函数持续每帧执行。 - 强制锁死位置:当
Time > 1时,回调函数会不断把Part位置重置为目标位置,任何手动修改都会被立刻覆盖。 - 冗余逻辑:TweenService本身会自动完成位置过渡,不需要额外通过RenderStepped监听并设置位置。
修复方案
方案一:移除冗余的RenderStepped监听(推荐)
直接让TweenService独立完成移动逻辑,代码更简洁:
local tweenService = game:GetService("TweenService") local player = game.Players.LocalPlayer local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut) function SpawnPart() local part = Instance.new("Part") part.Anchored = true part.Parent = game.Workspace.Clutter.Coins local startPos = Vector3.new(0, 2, 0) part.Position = startPos local TargetPosition = Vector3.new(5, 2, 0) local Tween = tweenService:Create(part, tweenInfo, {Position = TargetPosition}) Tween:Play() -- 如需在Tween完成后执行其他逻辑,保留此任务即可 task.spawn(function() Tween.Completed:Wait() -- 这里添加Tween完成后的自定义逻辑 end) end player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui"):WaitForChild("TextButton").Activated:Connect(SpawnPart)
方案二:保留RenderStepped但正确断开连接
如果确实需要保留RenderStepped做额外帧同步逻辑,必须在合适时机断开连接:
local tweenService = game:GetService("TweenService") local runService = game:GetService("RunService") local player = game.Players.LocalPlayer local RunServiceEvent = nil local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut) function SpawnPart() local part = Instance.new("Part") part.Anchored = true part.Parent = game.Workspace.Clutter.Coins local startPos = Vector3.new(0, 2, 0) part.Position = startPos local TargetPosition = Vector3.new(5, 2, 0) local Tween = tweenService:Create(part, tweenInfo, {Position = TargetPosition}) Tween:Play() local StartTime = tick() RunServiceEvent = runService.RenderStepped:Connect(function() local Time = (tick() - StartTime) / tweenInfo.Time if not part then RunServiceEvent:Disconnect() return end if Time > 1 then RunServiceEvent:Disconnect() return end end) task.spawn(function() Tween.Completed:Wait() if RunServiceEvent then RunServiceEvent:Disconnect() RunServiceEvent = nil end end) end player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui"):WaitForChild("TextButton").Activated:Connect(SpawnPart)
内容的提问来源于stack exchange,提问作者Lukas Raby
相关产品推荐
相关产品推荐

