View Model Sequences

So the problem i’ve been having with is playing the same animation in the reload function. When I reload it does the reload_start, then insert multiple times, and then reload_end. When the insert sequence plays for the second time, it literally does nothing. Is there a way to fix this, and if so how?


if CLIENT then
	SWEP.Author = "Red-XIII";
	SWEP.Contact = "Red-XIII@outlook.com";
	SWEP.Purpose = "";
	SWEP.Instructions = "";
	SWEP.Category = "Other";
	
	SWEP.BobScale = 2;
	SWEP.SwayScale = 2;
	
	SWEP.BounceWeaponIcon = true;
	
	SWEP.DrawWeaponInfoBox = true;
	SWEP.DrawAmmo = true;
	SWEP.DrawCrosshair = true;
	SWEP.AccurateCrosshair = false;
	
	SWEP.SpeechBubbleLid = surface.GetTextureID("gui/speech_lid");
	SWEP.WepSelectIcon = surface.GetTextureID("weapons/swep");
	
	SWEP.RenderGroup = RENDERGROUP_BOTH;
	
	SWEP.CSMuzzleFlashes = false;
	SWEP.CSMuzzleX = true;
end

if SERVER then
	SWEP.DisableDuplicator = false;

	SWEP.AutoSwitchFrom = true;
	SWEP.AutoSwitchTo = true;
	
	SWEP.Weight = 5;
end

SWEP.Spawnable = true;
SWEP.AdminOnly = false;
SWEP.PrintName = "Advanced SWEP";
SWEP.m_WeaponDeploySpeed = 1;

SWEP.ViewModel = Model("models/weapons/v_bo2r_870mcs.mdl");
SWEP.WorldModel = Model("models/weapons/w_bo2_870mcs.mdl");
SWEP.ViewModelFlip = false;
SWEP.ViewModelFlip1 = false;
SWEP.ViewModelFlip2 = false;
SWEP.ViewModelFOV = 60;
SWEP.UseHands = false;
SWEP.AutomaticFrameAdvance = true

SWEP.Slot = 0;
SWEP.SlotPos = 10;
SWEP.HoldType = "shotgun";

SWEP.Primary.Ammo = "SMG1";
SWEP.Primary.ClipSize = 10;
SWEP.Primary.DefaultClip = 10;
SWEP.Primary.Automatic = false;
SWEP.Primary.Reloading = false;

SWEP.Secondary.Ammo = nil;
SWEP.Secondary.ClipSize = 0;
SWEP.Secondary.DefaultClip = 0;
SWEP.Secondary.Automatic = false;

function SWEP:Initialize()
	if CLIENT then
		print("Advanced SWEP Base Initialized")
	end
	
	self:SetHoldType(self.HoldType);
end

function SWEP:Think()
	self:NextThink(CurTime());
	return true;
end

function SWEP:PrimaryAttack()
	local vm = self.Owner:GetViewModel();
	
	local id, dur = vm:LookupSequence("shoot");

	self:SetNextPrimaryFire(CurTime() + dur);

	vm:SendViewModelMatchingSequence(id);
	vm:SetPlaybackRate(1);
	vm:SetCycle(0);
	
	self.Owner:SetAnimation(PLAYER_ATTACK1);
end

function SWEP:Reload()
	if self.Primary.Reloading then
		return;
	end
	
	self.Primary.Reloading = true;
	
	local vm = self.Owner:GetViewModel();

	local id_0, dur_0 = vm:LookupSequence("reload_start");
	local id_1, dur_1 = vm:LookupSequence("insert");
	local id_2, dur_2 = vm:LookupSequence("reload_end");
	local id_3, dur_3 = vm:LookupSequence("idle");

	--self:SetNextPrimaryFire(CurTime() + dur_0 + (dur_1 * 7) + dur_2);

	vm:ResetSequenceInfo();
	vm:SendViewModelMatchingSequence(id_0);
	vm:SetPlaybackRate(1);
	vm:SetCycle(0);
	vm:SetAnimation(PLAYER_RELOAD);
	
	timer.Create("Reload_0", dur_0, 1, function ()
		vm:ResetSequenceInfo();
		vm:SendViewModelMatchingSequence(id_1);
		vm:SetPlaybackRate(1);
		vm:SetCycle(0);
	
		timer.Create("Reload_1", dur_1, self.Primary.ClipSize - 2, function ()
			vm:ResetSequenceInfo();
			vm:SendViewModelMatchingSequence(id_1);
			vm:SetPlaybackRate(1);
			vm:SetCycle(0);
		end);
	end);
	
	timer.Create("Reload_2", dur_0 + (dur_1 * self.Primary.ClipSize), 1, function ()
		vm:ResetSequenceInfo();
		vm:SendViewModelMatchingSequence(id_2);
		vm:SetPlaybackRate(1);
		vm:SetCycle(0);
		vm:SetAnimation(PLAYER_RELOAD);
	end)
	
	self.Primary.Reloading = false;
end

send idle, then insert in either the same frame or the next. i forget which.

Can you elaborate more please?

Play some other animation before playing the same animation again, like the idle animation.

You might also try resetting the animation frame ( SetCycle ) on the view model, or try this:

Looking through my old code, I just do the idle animation thing.

Thanks man, i’ll try these out.

Unfortunately those didn’t work for some reason. I used ent:SendViewModelMatchingSequence(id), and it was able to play the same animation more than once, but it’s touchy. It wont finish the animation sometimes.


local id, dur = vm:LookupSequence("idle");
vm:ResetSequenceInfo();
vm:ResetSequence(id);
vm:SetPlaybackRate(1);
vm:SetCycle(0);
		
vm:ResetSequenceInfo();
vm:ResetSequence(self.Shotgun.InsertAnim.ID);
vm:SetPlaybackRate(1);
vm:SetCycle(0);

Then you must wait a frame before doing a new animation.

Will try.

Nope that didn’t work. I don’t use timers anymore, but I now use my own timed/framed task system.


--AddTimedTask(identifier, delay, repeats, func)
--AddFramedTask(identifier, frame, repeats, func)
function SWEP:Reload()
	if (self.Reloading) then
		return;
	end
	
	if (self:Clip1() == self.Primary.ClipSize || self.Owner:GetAmmoCount(self.Primary.Ammo) <= 0) then
		return;
	end
	
	self.Reloading = true;
	
	PrintTable(self:GetSequenceList());
	
	local vm = self.Owner:GetViewModel();
	
	if (self.ReloadType == RT_SHOTGUN) then
		vm:SetCycle(0);
		vm:ResetSequenceInfo();
		vm:ResetSequence(2);
		
		self:AddTimedTask("Reload_Start", vm:SequenceDuration(2), 1, function ()
			vm:SetCycle(0);
			vm:ResetSequenceInfo();
			vm:ResetSequence(3);
			
			self:AddTimedTask("Reload_End", vm:SequenceDuration(3) * (self.Primary.ClipSize - 1), 1, function ()
				vm:SetCycle(0);
				vm:ResetSequenceInfo();
				vm:ResetSequence(4);
				
				self.Reloading = false;
			end)
		
			self:AddTimedTask("Reload_Insert", vm:SequenceDuration(3), self.Primary.ClipSize - 2, function ()
				vm:SetCycle(0);
				vm:ResetSequenceInfo();
				vm:ResetSequence(0);
				
				self:AddFramedTask("Reload_Idle", 1, 1, function ()
					vm:SetCycle(0);
					vm:ResetSequenceInfo();
					vm:ResetSequence(3);
				end)
			end);
		end);
	end
end

[editline]10th July 2016[/editline]

I guess it works well at 3 frames. Still doesn’t work the way I want it to though.

To actually get the animations working properly, you must create your own client side view model.


SWEP.C_ViewModel = nil;

if (CLIENT) then
	function SWEP:PreDrawViewModel()
		render.SetBlend(0);
	end
	
	function SWEP:PostDrawViewModel(vm, wp, ply)
		render.SetBlend(1);
		
		if (self.C_VM_Draw) then
			self.C_ViewModel:SetAngles(vm:GetAngles());
			self.C_ViewModel:SetPos(vm:GetPos());
			
			self.C_ViewModel:FrameAdvance(RealFrameTime());
			self.C_ViewModel:SetupBones()
			self.C_ViewModel:DrawModel();
		end
	end
end

function SWEP:Initialize()
	if (CLIENT) then
		self.C_ViewModel = ClientsideModel(self.ViewModel, RENDERGROUP_BOTH)
		--self.C_ViewModel:SetNoDraw(true)
		self.C_ViewModel:SetupBones()
	end
end

function SWEP:PrimaryAttack()
	local si = self:LookupSequence("shoot");

	if (CLIENT) then
		self.C_ViewModel:ResetSequence(si);
		self.C_ViewModel:SetPlaybackRate(1);
		self.C_ViewModel:SetCycle(0);
	end
end