This is my basic Viewmodel Controller which handles positioning and animations of viewmodels. The game is a single player first person melee combo game for reference.
local ViewmodelController = {}
ViewmodelController.__index = ViewmodelController
-- Services
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Folders
local Viewmodels = ReplicatedStorage:WaitForChild("Viewmodels")
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
-- Viewmodels
local DoomFistViewmodel = Viewmodels:WaitForChild("DoomFist")
-- RemoteEvents
local PlayAnimation = RemoteEvents:WaitForChild("PlayAnimation")
-- Tables
local ViewmodelTable = {
["DoomFist"] = DoomFistViewmodel,
}
-- Variables
local Camera = game.Workspace.Camera
-- Methods
function ViewmodelController.new(Player_: Player, ViewmodelName: string)
local ViewmodelClone = ViewmodelTable[ViewmodelName]:Clone()
local self = {
Bound = false,
Player = Player_,
AnimationTracks = {},
SwayCF = CFrame.new(),
CurrentViewmodel = ViewmodelClone,
}
ViewmodelController[Player_] = self
return setmetatable(self, ViewmodelController)
end
-- Animation Methods
function ViewmodelController:ManipulateAnimation(Name: string, Request: string, TimePosition: number, Speed: number, Weight: number)
if Name == nil or Request == nil or self.CurrentViewmodel == nil then return end
if self.AnimationTracks[Name] == nil then warn("Animation Doesnt Exist") return end
local AnimationTrack: AnimationTrack = self.CurrentViewmodel.Humanoid.Animator:LoadAnimation(self.CurrentViewmodel.Animations[Name])
if Speed ~= nil then
AnimationTrack:AdjustSpeed(Speed)
end
if Weight ~= nil then
AnimationTrack:AdjustWeight(Weight)
end
if TimePosition ~= nil then
AnimationTrack.TimePosition = TimePosition
end
if Request == "Play" then
AnimationTrack:Play()
elseif Request == "Stop" then
AnimationTrack:Stop()
else
return -- This could be a request called "neither" or some other gibberish meant to just adjust the properties of the animation track
end
end
-- Camera Alignment Methods
function ViewmodelController:RenderStepped()
if self.CurrentViewmodel == nil then return end
self.CurrentViewmodel.Parent = Camera
self.CurrentViewmodel:SetPrimaryPartCFrame(Camera.CFrame)
local MouseDelta = UserInputService:GetMouseDelta()/50
local SwayX = math.clamp(MouseDelta.X, -0.6, 2)
local SwayY = math.clamp(MouseDelta.Y, 0.6, 2)
self.SwayCF = self.SwayCF:Lerp(CFrame.new(SwayX, SwayY, 0), 0.1)
self.CurrentViewmodel.Parent = Camera
self.CurrentViewmodel:SetPrimaryPartCFrame(Camera.CFrame * self.SwayCF)
end
function ViewmodelController:Initiate()
self.CurrentViewmodel["RightArm"].Color = self.Player.Character["Right Arm"].Color
self.CurrentViewmodel["LeftArm"].Color = self.Player.Character["Left Arm"].Color
if self.Bound == false then
self.Bound = true
RunService:BindToRenderStep("ViewmodelAlignment", Enum.RenderPriority.Camera.Value + 1, function()
self:RenderStepped()
end)
end
self.Player.Character.Humanoid.Died:Connect(function()
self.CurrentViewmodel:Destroy()
self.CurrentViewmodel = nil
self.AnimationTracks = {}
self.Player.CharacterAdded:Connect(function()
self:Initiate()
end)
end)
PlayAnimation.OnClientEvent:Connect(function(...)
self:ManipulateAnimation(...)
end)
for _, Animation in self.CurrentViewmodel.Animations:GetChildren() do
print("Animation.Name")
self.AnimationTracks[Animation.Name] = self.CurrentViewmodel.Humanoid.Animator:LoadAnimation(Animation)
end
end
return ViewmodelController
The line:
local AnimationTrack: AnimationTrack = self.CurrentViewmodel.Humanoid.Animator:LoadAnimation(self.CurrentViewmodel.Animations[Name])
Gets the animation track to play while this line:
local AnimationTrack: AnimationTrack = self.AnimationTracks[Name]
Plays the animation but it doesnt appear.
Animations play by reloading the animations:
But when I dont re-preload the animation, output prints play (signifiying the animation is playing) but I cant see it.
EDIT: The video I posted should work now