UE2 - UT2kX Dynamically moving weapon in FirstPerson

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

forrestmark9

New Member
Aug 6, 2009
56
0
0
I need help with making a Dynamically moving weapon, like when the player moves the weapon moves in the opposite direction, or to get more descriptive if the player moves forward smoothly move the weapon back, if he moves left then smoothly move the weapon to right, or or if he looks to the right then twist the weapon to the right. Much like how Bulletstorm does with it's weapons.

So far all I know is I'd need to do alot of complicated math involving where the player is moving then using SetLocation and SetRotation

I'd most likely have to do something like

Code:
OverlaysVector.X = Location.X + Min(-VSize(Instigator.Velocity)/(-VSize(Instigator.Velocity)/2), -20);
SetLocation(OverlaysVector);
 
Last edited by a moderator:

meowcat

take a chance
Jun 7, 2001
803
3
18
The UT3 source code has some good examples as far as the smooth rotation of the weapon is concerned. By exchanging the signs you can have the weapon's rotation either lag or lead the player's view rotation.
 

forrestmark9

New Member
Aug 6, 2009
56
0
0
The UT3 source code has some good examples as far as the smooth rotation of the weapon is concerned. By exchanging the signs you can have the weapon's rotation either lag or lead the player's view rotation.

I found the function in UT3 and attempted a conversion and here is what I got.

Ignore the extra code that's for my FP hands stuff in UE2. Somethings I removed such as anything that had : in it as I do not know what it does in UE3.

Code:
simulated function int LagRot(int NewValue, int LastValue, float MaxDiff, int Index)
{
	local int RotDiff;
	local float LeadMag, DeltaTime;

	if ( NewValue ClockWiseFrom LastValue )
	{
		if ( LastValue > NewValue )
		{
			LastValue -= 65536;
		}
	}
	else
	{
		if ( NewValue > LastValue )
		{
			NewValue -= 65536;
		}
	}

	DeltaTime = Level.TimeSeconds - LastRotUpdate;
	RotDiff = NewValue - LastValue;
	if ( (RotDiff == 0) || (OldRotDiff[Index] == 0) )
	{
		if(ShouldLagRot())
			LeadMag = OldLeadMag[Index]; //: 0.0;
		if ( (RotDiff == 0) && (OldRotDiff[Index] == 0) )
		{
			OldMaxDiff[Index] = 0;
		}
	}
	else if ( (RotDiff > 0) == (OldRotDiff[Index] > 0) )
	{
		if (ShouldLagRot())
		{
			MaxDiff = FMin(1, Abs(RotDiff)/(12000*DeltaTime)) * MaxDiff;
			if ( OldMaxDiff[Index] != 0 )
				MaxDiff = FMax(OldMaxDiff[Index], MaxDiff);

			OldMaxDiff[Index] = MaxDiff;
			if( (NewValue > LastValue) )
				LeadMag = -1 * MaxDiff;
		}
		else
		{
			LeadMag = 0;
		}
		if ( DeltaTime < 1/RotChgSpeed )
		{
			LeadMag = (1.0 - RotChgSpeed*DeltaTime)*OldLeadMag[Index] + RotChgSpeed*DeltaTime*LeadMag;
		}
		else
		{
			LeadMag = 0;
		}
	}
	else
	{
		LeadMag = 0;
		OldMaxDiff[Index] = 0;
		if ( DeltaTime < 1/ReturnChgSpeed )
		{
			LeadMag = (1 - ReturnChgSpeed*DeltaTime)*OldLeadMag[Index] + ReturnChgSpeed*DeltaTime*LeadMag;
		}
	}
	OldLeadMag[Index] = LeadMag;
	OldRotDiff[Index] = RotDiff;

	return NewValue + LeadMag;
}

simulated function bool ShouldLagRot()
{
	return default.RotationLag;
}

simulated event RenderOverlays( Canvas Canvas )
{
	local int m;

	if (Instigator == None)
		return;

	if ( Instigator.Controller != None )
		Hand = Instigator.Controller.Handedness;

	if ((Hand < -1.0) || (Hand > 1.0))
		return;

	// draw muzzleflashes/smoke for all fire modes so idle state won't
	// cause emitters to just disappear
	for (m = 0; m < NUM_FIRE_MODES; m++)
	{
		if (FireMode[m] != None)
		{
			FireMode[m].DrawMuzzleFlash(Canvas);
		}
	}

	SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) );
	SetPosition(Instigator);

	PreDrawFPWeapon();	// Laurent -- Hook to override things before render (like rotation if using a staticmesh)

	bDrawingFirstPerson = true;
	Canvas.DrawActor(self, false, false, DisplayFOV);
	Canvas.DrawActor(FPHands, false, false, DisplayFOV);
	if( AttachmentComponent != none ){ Canvas.DrawActor(AttachmentComponent, false, false, DisplayFOV); }
	bDrawingFirstPerson = false;
}

simulated event SetPosition(Pawn Holder)
{
	local rotator NewRotation, FinalRotation;

	if ( !Holder.IsFirstPerson() )
		return;

	if(Holder.Controller != None)
		NewRotation = Holder.GetViewRotation(); //: Holder.Controller.Rotation;

	// Add some rotation leading
	if (Holder.Controller != None)
	{
		FinalRotation.Yaw = LagRot(NewRotation.Yaw & 65535, LastRotation.Yaw & 65535, MaxYawLag, 0);
		FinalRotation.Pitch = LagRot(NewRotation.Pitch & 65535, LastRotation.Pitch & 65535, MaxPitchLag, 1);
	}
	else
	{
		FinalRotation = NewRotation;
	}
	LastRotUpdate = Level.TimeSeconds;
	LastRotation = NewRotation;

	SetRotation(FinalRotation);
}

This works but now I need to find out how to make it return to the default rotation this code just changes the rotation and leaves it there until you look elsewhere
 
Last edited by a moderator:

meowcat

take a chance
Jun 7, 2001
803
3
18
I used the UT3 code as a base to have my weapons "lead" into the turn and then smoothly return to the default player's rotation if not rotating (which sounds kind of like what you want to do). See my modified version of the function below, specifically the section where the "if ( (RotDiff == 0) || (OldRotDiff[Index] == 0) )..." statement is:
Code:
simulated function int LeadRot(int NewValue, int LastValue, float MaxDiff, int Index){
	local int RotDiff;
	local float LeadMag, DeltaTime;

    // MPEthe next two statements basically make sure that the rotation difference can be
    // calculated in a way that makes sense (absolute difference AND direction as indicated by the sign (+ or -)
	if(NewValue ClockwiseFrom LastValue ){
		if ( LastValue > NewValue )  LastValue -= 65536;
	}
	else{
		if ( NewValue > LastValue )  NewValue -= 65536;
	}

	DeltaTime = Level.timeseconds - LastRotUpdate;
	RotDiff = NewValue - LastValue;
	// MPE now, if we are not turning, go ahead and return to 0 leading
	if ( (RotDiff == 0) || (OldRotDiff[Index] == 0) ){
		//LeadMag = OldLeadMag[Index];// = ShouldLagRot() ? OldLeadMag[Index] : 0.0;
		//if(ShouldLagRot()) LeadMag = OldLeadMag[Index];
		if(ShouldLagRot()){
		   LeadMag = 0;
    		OldMaxDiff[Index] = 0;
    		if ( DeltaTime < 1/ReturnChgSpeed ){
    			LeadMag = (1 - ReturnChgSpeed*DeltaTime)*OldLeadMag[Index] + ReturnChgSpeed*DeltaTime*LeadMag;
    		}
        }
		else LeadMag = 0.0;
        if ( (RotDiff == 0) && (OldRotDiff[Index] == 0) ){
			OldMaxDiff[Index] = 0;
		}
	}
	else if ( (RotDiff > 0) == (OldRotDiff[Index] > 0) ){
		if (ShouldLagRot()){
			MaxDiff = FMin(1, Abs(RotDiff)/(12000*DeltaTime)) * MaxDiff;
			if ( OldMaxDiff[Index] != 0 )
				MaxDiff = FMax(OldMaxDiff[Index], MaxDiff);

			OldMaxDiff[Index] = MaxDiff;
			//LeadMag = (NewValue > LastValue) ? -1* MaxDiff : MaxDiff;
			if(NewValue > LastValue) LeadMag = MaxDiff;
			else LeadMag = -1*MaxDiff;   // MPE only difference when turning to lead (-1*) instead of lag
		}
		else LeadMag = 0;
		if ( DeltaTime < 1/RotChgSpeed ){
			LeadMag = (1.0 - RotChgSpeed*DeltaTime)*OldLeadMag[Index] + RotChgSpeed*DeltaTime*LeadMag;
		}
		else LeadMag = 0;
	}else{
		LeadMag = 0;
		OldMaxDiff[Index] = 0;
		if ( DeltaTime < 1/ReturnChgSpeed ){
			LeadMag = (1 - ReturnChgSpeed*DeltaTime)*OldLeadMag[Index] + ReturnChgSpeed*DeltaTime*LeadMag;
		}
	}
	OldLeadMag[Index] = LeadMag;
	OldRotDiff[Index] = RotDiff;

	return NewValue + LeadMag;
}
 
Last edited:

forrestmark9

New Member
Aug 6, 2009
56
0
0
I used the UT3 code as a base to have my weapons "lead" into the turn and then smoothly return to the default player's rotation if not rotating (which sounds kind of like what you want to do). See my modified version of the function below, specifically the section where the "if ( (RotDiff == 0) || (OldRotDiff[Index] == 0) )..." statement is:

Oh awesome, that code works pretty well, now I just need to find out how to do the same with the location when moving forward, sideways, and backwards. If I'm correct it would be done somewhat the same way as LagRot but with a Vector instead of a Rotator

All I know is I'd need to do this with the Location function
Code:
simulated event SetLocationLag(Pawn Holder)
{
	local vector NewLocation, FinalLocation;

	if ( !Holder.IsFirstPerson() )
		return;

	if(Holder.Controller != None)
		NewLocation = Instigator.Location + Instigator.CalcDrawOffset(self); //: Holder.Controller.Rotation;

	// Add some rotation leading
	if (Holder.Controller != None)
	{
		FinalLocation.X = LagLoc(NewLocation.X, LastLocation.X, MaxXLag, 0);
		FinalLocation.Y = LagLoc(NewLocation.Y, LastLocation.Y, MaxYLag, 1);
	}
	else
	{
		FinalLocation = NewLocation;
	}
	LastLocUpdate = Level.TimeSeconds;
	LastLocation = NewLocation;

	SetLocation(FinalLocation);
}
 
Last edited by a moderator:

forrestmark9

New Member
Aug 6, 2009
56
0
0
I found these while looking through the source of Bulletstorm sadly I do not know how they are used as LagRot and SetPosition are native functions

Code:
var private bool bShouldLagPos;
var private bool bShouldLagRot;
var private bool bShouldLagPosViaAnim;
var private bool bShouldLagRotViaAnim;
var private float MaxPitchLag;
var private float MaxYawLag;
var private float PitchLagScale;
var private float YawLagScale;
var private float LagRate;
var private float LastRotUpdate[3];
var private Rotator LastRotation;
var private float LagDiff[2];
var private float PrevCalcRot[2];
var private transient Vector LagRelLocation;
var private transient Vector LagVelocity;
var private float LagAimScale;
var private float LagAimBlendTime;
var private transient float LagAim;
var private float LagVelocityGoingUpBlendTime;
var private float LagVelocityGoingDownBlendTime;
var private float LagRelLocationBlendTime;
var private float MaxLagRelLocation;
var private float LagVelocityScale;
var private float LagScaleMoveForStrafeMovement;
var private float LagScaleRotForStrafeMovement;
var private float LagScaleMoveForFwdBwdMovement;
var private float LagScaleRotForFwdBwdMovement;
var private Rotator DefaultOriginRotation;
var private transient Rotator BaseOriginRotation;
var private Vector ActualViewOffset;
var private Rotator ActualViewRotOffset;
var private Rotator RotationFromAnim;
var private transient Vector2D LagRotationOffset;
var private Vector2D LagRotationOffsetScale;