Smooth vault system for game?

I’m trying to make a dead by daylight-like vault and I’ve gotten a system but its not as smooth as i’d hoped it would be.

I want to warn you guys that this IS JUST A PROTOTYPE, meaning its not going to look good, I’m just trying to get the feel down right now.

My problem it doesnt smoothly transition between tweens and there is kind of a snap.

How could I fix/improve it??

mainly focus on the PlayVault() part

local VaultManager = {}
VaultManager.__index = VaultManager

local SyncTween = require(game.ReplicatedStorage:WaitForChild("Modules"):WaitForChild("SyncTween"))

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

local animations = require(script.Animations)
local localManagement = require(game.ServerStorage:WaitForChild("Optimization"):WaitForChild("LocalManagement"))
local characterManager = require(game.ServerStorage:WaitForChild("CharacterManager"))

local lockInfo = TweenInfo.new(0.3, Enum.EasingStyle.Linear)
local OppositeLockInfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine)

function VaultManager.ConfigurePrompt(prompt)
	local vaultConfig = {}

	vaultConfig.prompt = prompt
	vaultConfig.vaultObject = prompt.Parent.Parent
	vaultConfig.playerActivated = nil
	vaultConfig.animations = {}
	vaultConfig.animations.playerLeft = animations.playerLeft

	setmetatable(vaultConfig, VaultManager)

	return vaultConfig
end


local function MoveDirectionToPart(hum, part)

	local pos = hum.MoveDirection
	local partPos = part.CFrame.LookVector
	local Looking = pos:Dot(partPos)
	return Looking
end

local function TweenInOrder(parts, tweenInfos, goals, updates)
	for i, part in parts do
		local tween = SyncTween.new(part, tweenInfos[i], goals[i], updates[i])
		tween:Play()
		tween.Completed:Wait()
	end
end

function VaultManager:PlayVault(side)

	local plr = self.playerActivated
	local char = plr.Character or plr.CharacterAdded:Wait()
	local plrHumRoot = char:WaitForChild("HumanoidRootPart")
	local hum = char:WaitForChild("Humanoid")
	local plrAnimator = hum:WaitForChild("Animator")

	local PosMiddle = self.vaultObject.VaultPos
	local PosLeft = self.vaultObject.LeftStartPos
	local PosRight = self.vaultObject.RightStartPos
	local vaultBarrier = self.vaultObject.Barrier

	local playerAnimation = self.animations.playerLeft
	local playerSide
	local middleCFrame
	local oppositePlayerSide

	plrHumRoot.Anchored = true


	if side == "Left" then
		playerSide = PosLeft
		oppositePlayerSide = PosRight


		local leftRotation = PosLeft.CFrame - PosLeft.Position
		middleCFrame = CFrame.new(PosMiddle.Position) * leftRotation
	else
		playerSide = PosRight
		oppositePlayerSide = PosLeft


		local rightRotation = PosRight.CFrame - PosRight.Position
		middleCFrame = CFrame.new(PosMiddle.Position) * rightRotation
	end


	local TweenGoals = {
		{CFrame = playerSide.CFrame},
		{CFrame = middleCFrame},
		{CFrame = oppositePlayerSide.CFrame:ToWorldSpace(CFrame.Angles(0,math.rad(180),0))}
	}


	if hum:GetAttribute("Sprint") == true then	

		local TweenInfos = {
			lockInfo,
			TweenInfo.new(0.3, Enum.EasingStyle.Linear),
			TweenInfo.new(0.4, Enum.EasingStyle.Linear)
		}

		characterManager:SetPlayerTurn(plr, false)
		localManagement:SetModelCollision(plr, self.vaultObject, false)
		localManagement:PlayAnimation(plr, playerAnimation.AnimationId, plrAnimator, nil, 1)
		TweenInOrder({plrHumRoot, plrHumRoot, plrHumRoot}, TweenInfos, TweenGoals, {false, false, true})
	else

		local TweenInfos = {
			lockInfo,
			TweenInfo.new(0.7, Enum.EasingStyle.Linear),
			TweenInfo.new(0.7, Enum.EasingStyle.Linear)
		}

		characterManager:SetPlayerTurn(plr, false)
		localManagement:SetModelCollision(plr, self.vaultObject, false)
		localManagement:PlayAnimation(plr, playerAnimation.AnimationId, plrAnimator, nil, 0.4)
		TweenInOrder({plrHumRoot, plrHumRoot, plrHumRoot}, TweenInfos, TweenGoals, {false, false, true})
	end

	task.wait(0.1)

	plrHumRoot.Anchored = false
	characterManager:SetPlayerTurn(plr, true)
	localManagement:SetModelCollision(plr, self.vaultObject, true)

	self.prompt.Enabled = true

end

return VaultManager

make the animation faster so the player doesn’t feel like they stop their momentum

4 Likes

I’m talking about specifically the “climax” of the vault, like when the player hits the is basically right over the object there vaulting, idk if you can tell but theres like a split second where the tweens just stop.

idk.

What I’m trying to say is the tweens don’t look like one constant motion, you can see a delay between each animation and where the next one begins - if you get what im saying.

I dont think this would really matter like at all, the player wont see it nor will they care much at all imo. Best thing to do is have it move faster.

1 Like

Unfamiliar with SyncTween, why are there two animations to begin with? Id look at that first.

But, to minimize this gap, id assume that SyncTween.new() is synchronous and probably pretty process intensive. Id premake all of the tweens and store them, that way you can play them back to back quicker under the TweenInOrder function.

Does this make sense?

1 Like

you can check out syncTween here but its basically just a module that runs tweens on the client (which makes it 10 times smoother) and updates it on the server afterwards.

But about the two animations thingy, not proud to say this but I reused a script for a similar system I was making, thats probably the leftover of it😬

I would condense to 1 animation, thats the technically correct answer. Pretty unconventional to animate one motion with two animations.

1 Like

sorry to make you clarify but what do you mean by 2 animations?

Added an animation, still think the vault it to choppy, I want everything to be seamless and what I have right now is far from it.

I can throw in my 2 pennies by showing you my setup! Here’s my dynamic vault system:

I originally used tweens, but at some point I decided to re-write it with custom cframe animation logic as my game has many moving parts, and I wanted to avoid the issue of players trying to vault onto moving objects and they start floating as the thing they’re climbing has moved away. This logic will work for you regardless of whether your level design is completely anchored or not :grinning_face_with_smiling_eyes:

The way it works boils down to creating ‘vault animation data’ when the vault action begins, and lerping the character’s pivot CFrame to the current target within the animation every render frame.

This ‘animation data’ is just a table of CFrame values regarding the points at which the player character should be during the vault:

  • vault start point (before the obstacle, feet on the floor)
  • vault mid point (at the peak, surmounting the obstacle)
  • vault end point (overcome and vaulted over to the other side)

I store constants for the target timings of each vault animation type. (I also store the ‘easing’ type, so I can tweak the exact pattern of movement to give it a certain feeling)

At the start of vault, I create my animation sequence data. Don’t worry about the messy CFrame stuff, that’s just me pre-determining the start, mid and end points of the animation relative to the basepart the player is surmounting.

Dynamically creating the vault CFrame keyframes

Now the actual animation part. This is just constantly lerping the character towards the current animation target CFrame, which itself is gotten by lerping between the current keyframe and the next keyframe.

Vault animation frame logic code example


Then, I convert the global CFrames to CFrames that are relative to the basepart I’m trying to vault. This is so I can set my character CFrame relative to the basepart, so when it moves I move along with it.

Forgive me if none of this made sense, I’m exhausted at the time of this post but I wanted to at least reply with something that may be useful :slight_smile:


SUMMARY:

  1. Dynamically create a table of ‘keyframes’ which denote the CFrame of the player character at the start, middle and end of vault animation.
  2. Every frame during the animation, lerp the character towards the next keyframe bit-by-bit.

This should feel smoother, is more organic, and allows for vaulting moving objects.

10 Likes

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