Smooth Character transitioning

I have a game where you can switch in between an drone and the player. Problem is when switching inbetween characters, there is a moment delay. Also, the viewmodel stops working after a bit. Heres a video:

Code:

Client:(gameCamera

local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local cameraclass = {}
cameraclass.__index = cameraclass

export type gameCamera = { camera: Camera, player: Player, cameraclass: initialize, viewport: Model, cameraclass:pause, cameraclass:resume }
function cameraclass.new(): gameCamera
	local self: gameCamera = setmetatable({}, cameraclass)
	local camera = Workspace.CurrentCamera
	local Player = Players.LocalPlayer
	self.camera = camera
	self.player = Player
	self.viewmodel = nil

	return self
end

function cameraclass:__tostring()
	return "player: " .. self.player.Name
end

function cameraclass:initialize()
	self.player.CameraMode = Enum.CameraMode.LockFirstPerson
	local character: Model = self.player.Character
	print(HttpService:JSONDecode(self))
	if not self.player.Character then
		self.player.CharacterAdded:Wait()
	end
	print("player: " .. self.player.Character.Name)
	self.player.Character.Archivable = true
	--local RunService = game:GetService("RunService")
	--local PhysicsService = game:GetService("PhysicsService")

	local Camera = workspace.CurrentCamera
	if Camera:FindFirstChild("ViewModel") then
		Camera.ViewModel:Destroy()
	end

	local Animator: Animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")

	local ViewModel = ReplicatedStorage.viewModel:Clone()
	local BodyColors = character:FindFirstChildOfClass("BodyColors"):Clone()
	BodyColors.Parent = ViewModel
	ViewModel.Parent = camera
	local ViewModelAnimator = ViewModel.Humanoid:WaitForChild("Animator")
	self.animationConnection = Animator.AnimationPlayed:Connect(function(AnimationTrack)
		local track = ViewModelAnimator:LoadAnimation(AnimationTrack.Animation)
		track.Priority = Enum.AnimationPriority.Action4
		track:Play()
	end)
	self.viewModelConnection = RunService.RenderStepped:Connect(function()
		ViewModel.PrimaryPart.CFrame = camera.CFrame
	end)

	self.viewmodel = ViewModel
end

function cameraclass:pause()
	self.viewModelConnection:Disconnect()
	self.animationConnection:Disconnect()
	camera:WaitForChild("viewModel"):Destroy()
end

function cameraclass:resume()
	self.player.CameraMode = Enum.CameraMode.LockFirstPerson
	local Camera = workspace.CurrentCamera
	task.wait(1)
	if Camera:FindFirstChild("ViewModel") then
		Camera.ViewModel:Destroy()
	end
	camera.CameraSubject = Workspace:WaitForChild(self.player.Name).Humanoid
	local PlayerGui:PlayerGui = self.player.PlayerGui
	local characterGui = PlayerGui.MainHud.playerGui
    local droneGui = PlayerGui.MainHud.droneGui
	for _, gui:ScreenGui in pairs(characterGui:GetChildren()) do
        if gui:IsA("ScreenGui") then
            gui.Enabled = true
        end
    end
    for _, gui:ScreenGui in pairs(droneGui:GetChildren()) do
        if gui:IsA("ScreenGui") then
            gui.Enabled = false
        end
    end
	local character: Model = Workspace:WaitForChild(self.player.Name)
	local Animator: Animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")
	local ViewModel = ReplicatedStorage:WaitForChild("viewModel"):Clone()
	local BodyColors = character:FindFirstChildOfClass("BodyColors"):Clone()
	BodyColors.Parent = ViewModel
	ViewModel.Parent = camera
	local ViewModelAnimator = ViewModel.Humanoid:WaitForChild("Animator")
	self.animationConnection = Animator.AnimationPlayed:Connect(function(AnimationTrack)
		local track = ViewModelAnimator:LoadAnimation(AnimationTrack.Animation)
		track.Priority = Enum.AnimationPriority.Action4
		track:Play()
	end)
	self.viewModelConnection = RunService.RenderStepped:Connect(function()
		ViewModel.PrimaryPart.CFrame = camera.CFrame
	end)
	self.viewmodel = ViewModel
end



return cameraclass

Client(droneCamera):

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local cameraclass = {}
cameraclass.__index = cameraclass

export type droneCamera = { camera: Camera, player: Player, droneModel: Model, dronelvl: number, cameraclass: initialize }

function cameraclass.new(): droneCamera
	local self: gameCamera = setmetatable({}, cameraclass)
	local camera = Workspace.CurrentCamera
	local Player = Players.LocalPlayer
	print(Player)
	if not Player.Character then
		Player.CharacterAdded:Wait()
	end
	self.camera = camera
	self.player = Player
	self.dronelvl = 1
	return self
end

function cameraclass:__tostring()
	return "player: " .. self.player.Name
end

function cameraclass:initialize()
	local drone = ReplicatedStorage.createDrone:InvokeServer(1)
	self.droneModel = drone
end

function cameraclass:resume()
    self.droneModel.PrimaryPart.Anchored = false
	print("resuming droneCamera")
	self.droneModel:PivotTo(self.droneModel.PrimaryPart.CFrame + Vector3.new(0, 2.5, 0))
	self.droneModel.Humanoid.HipHeight = 10
	local camera: Camera = self.camera
	local player = Players.LocalPlayer
	local PlayerGui: PlayerGui = player.PlayerGui
	player.CameraMode = Enum.CameraMode.Classic
	camera.CameraSubject = self.droneModel.Humanoid
	camera.CameraType = Enum.CameraType.Custom
	ReplicatedStorage.setDroneCharacter:FireServer(self.droneModel)
	local characterGui = PlayerGui.MainHud.playerGui
	local droneGui = PlayerGui.MainHud.droneGui
	for _, gui: ScreenGui in pairs(characterGui:GetChildren()) do
		if gui:IsA("ScreenGui") then
			gui.Enabled = false
		end
	end
	for _, gui: ScreenGui in pairs(droneGui:GetChildren()) do
		if gui:IsA("ScreenGui") then
			gui.Enabled = true
		end
	end
end

function cameraclass:pause()
	print("pausingCamera")
	self.droneModel.PrimaryPart.Anchored = true
end

return cameraclass

Server(Remote Events):

function createDrone(player, level)
	local drone = ReplicatedStorage:WaitForChild("Drones")["lvl".. tostring(level)]:Clone()
	drone.Name = "drone"
    drone:PivotTo(player.Character.PrimaryPart.CFrame + Vector3.new(0,75,0))
	drone.Parent = Workspace
	return drone
end

ReplicatedStorage.createDrone.OnServerInvoke = createDrone




ReplicatedStorage.createItems.OnServerEvent:Connect(function(player, item)
	local itemManager = require(ServerStorage:WaitForChild("ItemManager"))
	local itemObject: itemManager.itemClass = itemManager.create(item, player)
	local itemTable = equipedItems[player.Name]
	itemTable[item] = itemObject
end)

ReplicatedStorage.equipItem.OnServerEvent:Connect(function(player, item)
	local itemTable = equipedItems[player.Name]
	local itemObject = itemTable[item]
	if itemObject then
		itemObject:equip()
	end
end)


ReplicatedStorage.setDroneCharacter.OnServerEvent:Connect(function(player, drone)
	drone.PrimaryPart.Anchored = false
	for _, v:BasePart in pairs(drone:GetChildren()) do
		if v:IsA("BasePart") then
			v:SetNetworkOwner(player)
		end
	end
	local oldCharacter = player.Character
	player.Character = drone
	oldCharacter.Parent = Workspace
end)

ReplicatedStorage.exitDrone.OnServerEvent:Connect(function(player)
	local drone = player.Character
	drone.PrimaryPart.Anchored = true
	player.Character = Workspace:WaitForChild(player.Name)
	drone.Parent = Workspace
end)

Edit:

any help? help pls this is annoying

can any one help with this issue?

can any one help here?

748 characters

Update: The Viewmodel Glitch does not happen anymore, there was an loading problem with the viewmodel, now the script automatically checks if the viewmodel Loaded properly

The delay inbetween the switch from drone to character is still there though

Any help? this is bothering me

When you anchor a part, the network ownership goes to the server so when you’re calling the exitDrone event that might be what’s causing the delay. Not sure why you’re changing the whole character too, you could just set the cameras subject to the drone and then back to the humanoid on the client

the drone can move around, and the player controls the drone

1 Like

ah ok, in that case iirc when you do that character swap trick, the camera gets destroyed and remade so that might be what’s causing your issue. Try maybe first tweening the camera and once it reaches the destination you can then switch the character?

1 Like

yes, but wouldn’t the character switch delay still be their?

Okay, it works, but I do not gain control of the character until a few seconds

Yes it would still be there, but you can hide it to an acceptable level. In the video below, I am doing the same trick at the end of the wolf transformation where I change the players character from a human to a wolf and once the new wolf model is set, I tween the camera and it’s smooth enough. If you tween halfway how you’re doing it, there’s going to be a jump.

You can notice a jump on my method too right at the beginning of the tween when the wolf loses it’s glow effect but it’s not as pronounced. My code’s also pretty much identical to yours so won’t be much of a difference

um, i kind of need an really fast paced transition. is their any way to like, transition the character without delay?

Do you mean the tween is too slow? Do you still want it to tween or just to set the camera position instantly?

i am going to try to set the camera position instantly, il be right back

1 Like

i just set the camera position instantly, and the controls still dont come back before an delay. What i mean is that the camera works, but the controls dont

1 Like

Ok so two options you can do. Option one (harder) is to not change the character because there’s always going to be a delay and instead just write a small quick custom movement system for the drone and toggle between drone movement and player controls on the client. Will be instant and smooth

option 2 is to just hide the character swap latency with an animation or something. This is probably a lot easier to do imo. I put a video below as a concept animation for when you equip the drone from call of duty. So you would basically run this animation, then swap the character on the server to the drone, and once the animation is complete, the player would of seen a smooth animation transition because you’re basically “hiding” the character swap lag

1 Like

I use the “hide stuff loading with a cute animation” method a lot in my games and it works pretty well lol

1 Like

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