How to rotate door on client?

At first i tried hinge constraints but controlling those wont work on the client without network ownership. I also tried tween but that doesnt give the effect of the door being attached to hinges and rotating on the hinges.
What can i do?

You can tween the orientation and position of the door at the same time. For example, if you’re tweening the door on its Y axis, the orientation goal would look something like this:

local goal = {Orientation = part.Orientation + Vector3.new(0,90,0)}

If it’s rotating on its Y axis, the position should change on its X and Z axes, using CFrame.XVector and CFrame.ZVector

1 Like

Since you’re rotating the doors on the client, I’m assuming you don’t care about replicating the state of the door (animation and/or whether the door is open or closed) on other clients? If that’s not the case, then you should seek an approach where the doors are instead opened/closed on the server.

There’s multiple ways you might set this up to work on the client:

  1. Create the doors on the client, ensuring network ownership. This approach would work best if you have multiple places where the same door asset is used. Using CollectionService and tags on a Part or other instance you can represent where each client will insert a local model of the door, which it can then open using HingeConstraints without the issue you mentioned.
  2. Use Tweens on a Weld that connects the door at the intended hinge pivot.
  3. Use CFrame interpolation or possibly even an ideal spring via TweenService:SmoothDamp
1 Like

I wrote this script

local part = workspace.Part
local function rotate(hinge:Vector2,rotation:number)
	local function rotatePositionAroundCircle(center:Vector2,position:Vector2,rotation:number)
		local line = position - center
		local radius = line.Magnitude
		local originalRotation = math.atan2(line.Y,line.X)
		local newRotation = originalRotation + math.rad(rotation)
		local sine = math.sin(newRotation)
		local cosine = math.cos(newRotation)
		return center + Vector2.new(cosine,sine) * radius
	end

	local tweenService = game.TweenService
	local ti = TweenInfo.new(1,Enum.EasingStyle.Linear)
	tweenService:Create(part,ti,{Orientation = part.Orientation - Vector3.new(0,rotation,0)}):Play()
	
	task.spawn(function()
		local time = ti.Time
		local total = 0
		local originalPosition = Vector2.new(part.Position.X,part.Position.Z)
		local goal = rotatePositionAroundCircle(hinge,originalPosition,rotation)
		repeat
			total += task.wait()
			local pos = rotatePositionAroundCircle(hinge,originalPosition,total/time * rotation)
			part.Position = Vector3.new(pos.X,part.Position.Y,pos.Y)
		until total >= time
		part.Position = Vector3.new(goal.X,part.Position.Y,goal.Y)
	end)
end
local part = workspace.Part
local halfX = part.Size.X / 2
local hinge = part.Position - part.CFrame.XVector * halfX

local rotation = 90
rotate(Vector2.new(hinge.X,hinge.Z),rotation)

Here’s the result:

1 Like