Setting a viewmodel's position upon the player holding down sprint, and preventing them from firing while doing so


function SWEP:GetViewModelPosition( pos, ang )

	if ( !self.IronSightsPos ) then return pos end
	if ( !self.IronSightsAng ) then return ang end
	
	local GetIron = self:GetNWBool( "IronSights" .. self:EntIndex() )
	
	if ( GetIron != self.LastIron ) then
	
		self.LastIron = GetIron
		self.IronTime = CurTime()
		
		if ( GetIron ) then 
			self.SwayScale 	= 0.3
			self.BobScale 	= 0.1
		else 
			self.SwayScale 	= 1.0
			self.BobScale 	= 1.0
		end
	
	end
	
	local IronTime = self.IronTime or 0

	if ( !GetIron and IronTime < CurTime() - self.IronSightsTime ) then 
		return pos, ang 
	end
	
	local Mul = 1.0
	
	if ( IronTime > CurTime() - self.IronSightsTime ) then
	
		Mul = math.Clamp( (CurTime() - IronTime) / self.IronSightsTime, 0, 1 )
		
		if ( !GetIron ) then Mul = 1 - Mul end
	
	end

	local Offset = self.IronSightsPos
	
	if ( self.IronSightsAng ) then
	
		ang = ang * 1
		ang:RotateAroundAxis( ang:Right(), 		self.IronSightsAng.x * Mul )
		ang:RotateAroundAxis( ang:Up(), 		self.IronSightsAng.y * Mul )
		ang:RotateAroundAxis( ang:Forward(), 	self.IronSightsAng.z * Mul )
	
	
	end
	
	local Right 	= ang:Right()
	local Up 		= ang:Up()
	local Forward 	= ang:Forward()
	
	

	pos = pos + Offset.x * Right * Mul
	pos = pos + Offset.y * Forward * Mul
	pos = pos + Offset.z * Up * Mul

	return pos, ang

end


How would I modify this to make the viewmodel be held downwards during sprinting?(Note: I want this to be a transition, not an instant-teleport to the viewmodel pos when they’re sprinting)Also, how would I prevent the player from firing while sprinting?

[editline]9th May 2015[/editline]

You could also just do it the way they’re doing it right now in the function you currently have.

Example? Sorry, but adding on to my current code is probably going to be hard enough(Getting it to work with returns is hard iirc)…

Well I would first advise you set up a unified sprint state first. That way you don’t always have to check using ply:KeyDown().

Something maybe under Think



local ply = self:GetOwner()
if ply:KeyDown(IN_SPEED) and (ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK) or ply:KeyDown(IN_LEFT) or ply:KeyDown(IN_RIGHT)) then
    self:SetNWBool("Sprinting", true)
else
    self:SetNWBool("Sprinting", false)
end


Then you can check if the player is running on both server and client with
self:GetNWBool(“Sprinting”, false)

To make it easier on yourself when typing things, you can write yourself a function that’s easier to type than “self:GetNWBool(“Sprinting”, false)”



function SWEP:SprintState()
    return self:GetNWBool("Sprinting", false)
end


then you would use something like



if self:SprintState() then
    --sprint position stuff
end


As for an example of math.Approach, perhaps it would be better to stick to your current code’s method.



	local Mul = 1.0
	
	if ( IronTime > CurTime() - self.IronSightsTime ) then
	
		Mul = math.Clamp( (CurTime() - IronTime) / self.IronSightsTime, 0, 1 )
		
		if ( !GetIron ) then Mul = 1 - Mul end
	
	end

	local Offset = self.IronSightsPos
	
	if ( self.IronSightsAng ) then
	
		ang = ang * 1
		ang:RotateAroundAxis( ang:Right(), 		self.IronSightsAng.x * Mul )
		ang:RotateAroundAxis( ang:Up(), 		self.IronSightsAng.y * Mul )
		ang:RotateAroundAxis( ang:Forward(), 	self.IronSightsAng.z * Mul )
	
	
	end


is basically how they’re doing it right now so you should probably use a ratio like they are to keep consistency.
I think this is garry’s code, right?

In order for the sprint position to work I need to return pos and ang. However I also need to use math.Approach to get that to work. What I mean by it’s hard to get that in with returns is that returning is supposedly the last thing you want to do in a function. Formatting it so it doesn’t create errors when returning can be a pain, so that’s why I needed help both finding a way to use math.Approach and how to add the sprint code to my current code.

I think I should clarify a bit more.

Mul represents a ratio between 0 and 100%, where 1 is 100 percent.



Mul = math.Clamp( (CurTime() - IronTime) / self.IronSightsTime, 0, 1 )


Basically, what’s going on here is that the current time elapsed since the player sighted their gun (CurTime() - IronTime) is being divided by the amount of time the coder wants for the viewmodel to be completely sighted in (self.IronsightsTime).
This becomes the value of Mul. We use math.Clamp on it so that it can neither be less than 0 or more than 1, as that would make the gun fly off screen.
so, let’s assume that the transition is now about 70% complete, and the gun model has traveled 70% of the distance and angle it needs to go to.

Mul at this point in time is 0.7, and so each component of the angle change is multiplied by this to give 70% of that angle change. this angle change is then applied using RotateAroundAxis, and is repeated for each component.



	local Right 	= ang:Right()
	local Up 		= ang:Up()
	local Forward 	= ang:Forward()
	
	

	pos = pos + Offset.x * Right * Mul
	pos = pos + Offset.y * Forward * Mul
	pos = pos + Offset.z * Up * Mul


now, we need to do the position. We use ang:Right()/Up()/Forward() to get vectors representing the direction of travel.
then we modify pos by adding the final position (Offset.x/y/z) times the directional vector(Right/Forward/Up) times the ratio (Mul).

then we return both values (in order)



return pos, ang


Then the gamemode processes the new position and angle you gave it and applies it to the viewmodel.

AKA I just need help merging these code snippets together with my current code

If you still want to use math.Approach, you can do that too.

(Untested)



local x,y,z = pos.x, pos.y, pos.z

x = math.Approach( x, targetX, FrameTime() * speed )
y = math.Approach( y, targetY, FrameTime() * speed )
z = math.Approach( Z, targetZ, FrameTime() * speed )

pos = pos + Vector( x, y, z )

return pos, ang


where targetX/Y/Z is your sprint position component and speed is the amount of distance it should cover in one second.

[editline]9th May 2015[/editline]

I would like to help you merge the snippets but you still lack some basic infrastructure (specifically, your sprint target vector/angle, and a constant representing the transition speed)

Would their be a better way using my code’s method for ironsights? This is confusing, but getting this right helps polish up my SWEP base I’m working on.

[editline]9th May 2015[/editline]

Add me on Steam, we can talk about this more in-depth. Name: Von Kaiser(AKA A Fighter Pilot)