1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. 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.

UE2 - UT2kX Dynamically moving weapon in FirstPerson

Discussion in 'Programming' started by forrestmark9, Mar 25, 2014.

  1. forrestmark9

    forrestmark9 New Member

    Joined:
    Aug 6, 2009
    Messages:
    56
    Likes Received:
    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: Mar 25, 2014
  2. meowcat

    meowcat take a chance

    Joined:
    Jun 7, 2001
    Messages:
    803
    Likes Received:
    3
    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.
     
  3. forrestmark9

    forrestmark9 New Member

    Joined:
    Aug 6, 2009
    Messages:
    56
    Likes Received:
    0
    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: Mar 26, 2014
  4. meowcat

    meowcat take a chance

    Joined:
    Jun 7, 2001
    Messages:
    803
    Likes Received:
    3
    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: Mar 26, 2014
  5. forrestmark9

    forrestmark9 New Member

    Joined:
    Aug 6, 2009
    Messages:
    56
    Likes Received:
    0
    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: Mar 28, 2014
  6. forrestmark9

    forrestmark9 New Member

    Joined:
    Aug 6, 2009
    Messages:
    56
    Likes Received:
    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;
     

Share This Page