a UT1 code question about player physics

  • 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.

Dryn

New Member
Feb 20, 2003
128
0
0
Visit site
Its all but broken in everything pre-ut2k3; its there, sort of, but always crashed and never worked right. (you can't easily do AVP style movement even in the new engine)
 

Dryn

New Member
Feb 20, 2003
128
0
0
Visit site
Oh, and when a TRUE coder tells you that something 'ain't going to happen, or at least not without great difficulty, you don't turn around and tell them that its simple... Thats on par with telling the mechanic that 'its just telling the engine to work, how hard can it be?' when you have a wrecked car sitting in pieces on the floor...

Still though, Its all but impossible for anything less than the 2k3 level engine. The code is broken, and it doesn't handle edges worth a damn; even if you manage to stick to a surface, the relative locations are all screwed up, and If I remember right the visuals associated with the player are not rotated to match this new orientation. Suffice to say, that coder or not, making anything other than perhaps a wall run (which would be best done elsewhere anyways) would be a massive coding endevour with a very limited chance of success.
 

Shambler[sixpack]

New Member
May 3, 2001
564
0
0
Ireland
Visit site
Ok, it's been a long long time since I touched this code so I just made it a little neater and tested it still worked...

I gave similar code out here ages ago and the only change here is that I ripped the viewrotation code out of UT2k3's PlayerSpidering :) (can be disabled with bDisableViewFixing)
It works but has a lot of bugs, I really just did it to see if it could be done and left it there.. If you use it in something please give me a little credit ;) (also, this was done in Unreal1 so it should work fine in UT but I have no idea about online)

Code:
class StickyPlayer extends INFIL_MalePlayer; // Or a subclass or tournament player whatever, this was Unreal1

var vector LastHN, ViewX, ViewY, ViewZ;
var bool bDisableViewFixing;

state WallWalk
{
	function EndState()
	{
		WalkBob = vect(0,0,0);
		bIsCrouching = false;
	}

	function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
	{
		local vector OldAccel;

		OldAccel = Acceleration;
		Acceleration = NewAccel;
		bIsTurning = (Abs(DeltaRot.Yaw/DeltaTime) > 5000);

		if ((DodgeMove == DODGE_Active) && (Physics == PHYS_Falling))
			DodgeDir = DODGE_Active;     
		else if ((DodgeMove != DODGE_None) && (DodgeMove < DODGE_Active))
			Dodge(DodgeMove);

		if (bPressedJump)
			DoJump();

		if ((Physics == PHYS_Walking) && (GetAnimGroup(AnimSequence) != 'Dodge'))
		{
			if (!bIsCrouching)
			{
				if (bDuck != 0)
				{
					bIsCrouching = true;
					PlayDuck();
				}
			}
			else if (bDuck == 0)
			{
				OldAccel = vect(0,0,0);
				bIsCrouching = false;
			}

			if (!bIsCrouching)
			{
				if ((!bAnimTransition || (AnimFrame > 0)) && (GetAnimGroup(AnimSequence) != 'Landing'))
				{
					if (Acceleration != vect(0,0,0))
					{
						if ((GetAnimGroup(AnimSequence) == 'Waiting')
						|| (GetAnimGroup(AnimSequence) == 'Gesture')
						|| (GetAnimGroup(AnimSequence) == 'TakeHit'))
						{
							bAnimTransition = true;
							TweenToRunning(0.1);
						}
					}
					else if ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y < 1000)
					&& (GetAnimGroup(AnimSequence) != 'Gesture')) 
					{
						if (GetAnimGroup(AnimSequence) == 'Waiting')
						{
							if (bIsTurning && (AnimFrame >= 0)) 
							{
								bAnimTransition = true;
								PlayTurning();
							}
						}
						else if (!bIsTurning) 
						{
							bAnimTransition = true;
							TweenToWaiting(0.2);
						}
					}
				}
			}
			else
			{
				if ((OldAccel == vect(0,0,0)) && (Acceleration != vect(0,0,0)))
					PlayCrawling();
				else if (!bIsTurning && (Acceleration == vect(0,0,0)) && (AnimFrame > 0.1))
					PlayDuck();
			}
		}

		MoveSmooth(NewAccel*DeltaTime);
	}

	singular function ZoneChange(ZoneInfo NewZone)
	{
		Super.ZoneChange(NewZone);
		
		if (NewZone.bWaterZone)
		{
			setPhysics(PHYS_Swimming);
			GotoState('PlayerSwimming');
		}
	}

	event PlayerTick(float DeltaTime)
	{
		if (bUpdatePosition)
			ClientUpdatePosition();

		PlayerMove(DeltaTime);
	}

	// Called every PlayerTick()
	function PlayerMove(float DeltaTime)
	{
		local vector HitLoc, HitNor, EndLoc, ForwardAccel, NewAccel, X, Y, Z;
		local rotator R, OldRotation;
		local actor HitActor;
		
		// local vector X,Y,Z, NewAccel;
		local EDodgeDir OldDodge;
		local eDodgeDir DodgeMove;

		// local rotator OldRotation;
		local float Speed2D, xx;
		local bool     bSaveJump;
		local name AnimGroupName;

		GetAxes(ViewRotation,X,Y,Z);
		aForward *= 0.08;
		aStrafe *= 0.08;
		aLookup *= 0.24;
		aTurn *= 0.24;

		if (ViewRotation.Pitch > 16384 && ViewRotation.Pitch < 49152)
			aTurn=-aTurn;

		R = ViewRotation;
		R.Pitch -= 16384.0;
		EndLoc = Location + (Vector(R) * 250.0);
		HitActor = Trace(HitLoc, HitNor, EndLoc, Location, False);

		if (HitNor != vect(0,0,0))
			LastHN=HitNor;
		
		if (DodgeDir == DODGE_Active)
			DodgeMove = DODGE_Active;
		else
			DodgeMove = DODGE_None;

		if (DodgeClickTime > 0.0)
		{
			if (DodgeDir < DODGE_Active)
			{
				OldDodge = DodgeDir;
				DodgeDir = DODGE_None;

				if (bEdgeForward && bWasForward)
					DodgeDir = DODGE_Forward;

				if (bEdgeBack && bWasBack)
					DodgeDir = DODGE_Back;

				if (bEdgeLeft && bWasLeft)
					DodgeDir = DODGE_Left;

				if (bEdgeRight && bWasRight)
					DodgeDir = DODGE_Right;

				if (DodgeDir == DODGE_None)
					DodgeDir = OldDodge;

				else if (DodgeDir != OldDodge)
					DodgeClickTimer = DodgeClickTime + 0.5 * DeltaTime;
				else 
					DodgeMove = DodgeDir;
			}
               
			if (DodgeDir == DODGE_Done)
			{
				DodgeClickTimer -= DeltaTime;

				if (DodgeClickTimer < -0.35) 
				{
					DodgeDir = DODGE_None;
					DodgeClickTimer = DodgeClickTime;
				}
			}
			else if ((DodgeDir != DODGE_None) && (DodgeDir != DODGE_Active))
			{
				DodgeClickTimer -= DeltaTime;
             
				if (DodgeClickTimer < 0)
				{
					DodgeDir = DODGE_None;
					DodgeClickTimer = DodgeClickTime;
                         
				}
			}
		}

		AnimGroupName = GetAnimGroup(AnimSequence);
      
		if ((Physics == PHYS_Walking) && (AnimGroupName != 'Dodge'))
		{
			//if walking, look up/down stairs - unless player is rotating view
			if (!bKeyboardLook && (bLook == 0))
			{
				if (bLookUpStairs)
					ViewRotation.Pitch = FindStairRotation(deltaTime);
				else if (bCenterView)
				{
					ViewRotation.Pitch = ViewRotation.Pitch & 65535;

					if (ViewRotation.Pitch > 32768)
						ViewRotation.Pitch -= 65536;

					ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime));

					if (Abs(ViewRotation.Pitch) < 1000)
						ViewRotation.Pitch = 0;     
				}
			}
		}

		if (Role < ROLE_Authority) // then save this move and replicate it
			ReplicateMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation);
		else
			ProcessMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation);

		bPressedJump = bSaveJump;
		
		if (HitActor.IsA('LevelInfo') || HitActor.IsA('Mover'))
		{
			if (Physics != PHYS_None) 
				SetPhysics(PHYS_None);

			if (HitActor.IsA('Mover'))
				SetBase(HitActor);

			NewAccel = HitNor * -950.0;
			ForwardAccel = (aForward * X + aStrafe * Y);
			NewAccel+=ForwardAccel;

			if (aForward != 0 || aStrafe != 0)
			{
				if (aForward > 0)
					PlayWalking();
				else
					PlayWalking();
			}
			else
			{
				PlayWaiting();
			}
			SetRotation(rotator(HitNor));
		}

		OldRotation=Rotation;
		UpdateRotation(DeltaTime,1);

		if (Role < ROLE_Authority) // then save this move and replicate it
			ReplicateMove(DeltaTime,NewAccel,DodgeDir,OldRotation-Rotation);
		else if (Physics == PHYS_None) // ***
			ProcessMove(DeltaTime,NewAccel,DodgeDir,OldRotation-Rotation);
	}

	function UpdateRotation(float DeltaTime,float maxPitch)
	{
		local vector MyFloor, OldX;

		if (!bDisableViewFixing)
			MyFloor = LastHN;

		if (bDisableViewFixing)
			MyFloor = vect(0,0,1);

		if (ViewX == vect(0,0,0) && ViewY == vect(0,0,0) && ViewZ == vect(0,0,0))
			GetAxes(ViewRotation, ViewX, ViewY, ViewZ);

		// UT2k3 stuff
		if ((aTurn != 0.0) || (aLookUp != 0.0))
		{
			// adjust Yaw based on aTurn
			if (aTurn != 0.0)
				ViewX = Normal(ViewX + 2.0 * ViewY * Sin(0.0005*DeltaTime*aTurn));

			// adjust Pitch based on aLookUp
			if (aLookUp != 0.0)
			{
				OldX = ViewX;
				ViewX = Normal(ViewX + 2.0 * ViewZ * Sin(0.0005*DeltaTime*aLookUp));
				ViewZ = Normal(ViewX Cross ViewY);

				// bound max pitch
				if ((ViewZ Dot MyFloor) < 0.707 && !bDisableViewFixing)
				{
					OldX = Normal(OldX - MyFloor * (MyFloor Dot OldX));
					if ( (ViewX Dot MyFloor) > 0.0)
						ViewX = Normal(OldX + MyFloor);
					else
						ViewX = Normal(OldX - MyFloor);

					ViewZ = Normal(ViewX Cross ViewY);
				}
			}

			// calculate new Y axis
			ViewY = Normal(MyFloor Cross ViewX);
		}

		ViewRotation =  OrthoRotation(ViewX,ViewY,ViewZ);
		SetRotation(ViewRotation);

		ViewShake(deltaTime);
		ViewFlash(deltaTime);
	}

	function BeginState()
	{
		if (Physics != PHYS_Falling) 
			SetPhysics(PHYS_None);
		
		WalkBob = vect(0,0,0);
		DodgeDir = DODGE_None;
		bIsCrouching = false;
		bIsTurning = false;
		bPressedJump = false;

		if ( !IsAnimating() )
			PlayWaiting();
	}
	
	function AnimEnd()
	{
		local name MyAnimGroup;

		bAnimTransition = false;

		if (Physics == PHYS_Walking)
		{
			if (bIsCrouching)
			{
				if (!bIsTurning && ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000))
					PlayDuck();
				else
					PlayCrawling();
			}
			else
			{
				MyAnimGroup = GetAnimGroup(AnimSequence);

				if ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000)
				{
					if (MyAnimGroup == 'Waiting')
						PlayWaiting();
					else
					{
						bAnimTransition = true;
						TweenToWaiting(0.2);
					}
				}
				else if (bIsWalking)
				{
					if ((MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing')
					|| (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit'))
					{
						TweenToWalking(0.1);
						bAnimTransition = true;
					}
					else
						PlayWalking();
				}
				else
				{
					if ((MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing')
					|| (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit'))
					{
						bAnimTransition = true;
						TweenToRunning(0.1);
					}
					else
						PlayRunning();
				}
			}
		}
		else
			PlayInAir();
	}

	function Landed(vector HitNormal)
	{
		Global.Landed(HitNormal);

		if (DodgeDir == DODGE_Active)
		{
			DodgeDir = DODGE_Done;
			DodgeClickTimer = 0.0;
			Velocity *= 0.1;
		}
		else
			DodgeDir = DODGE_None;
	}

	function Dodge(eDodgeDir DodgeMove)
	{
		local vector X,Y,Z;

		if (bIsCrouching || (Physics != PHYS_Walking))
			return;

		GetAxes(Rotation,X,Y,Z);

		if (DodgeMove == DODGE_Forward)
			Velocity = 1.5*GroundSpeed*X + (Velocity Dot Y)*Y;
		else if (DodgeMove == DODGE_Back)
			Velocity = -1.5*GroundSpeed*X + (Velocity Dot Y)*Y; 
		else if (DodgeMove == DODGE_Left)
			Velocity = 1.5*GroundSpeed*Y + (Velocity Dot X)*X; 
		else if (DodgeMove == DODGE_Right)
			Velocity = -1.5*GroundSpeed*Y + (Velocity Dot X)*X; 

		Velocity.Z = 160;

		if (Role == ROLE_Authority)
			PlaySound(JumpSound, SLOT_Talk, 1.0, true, 800, 1.0 );

		PlayDodge(DodgeMove);
		DodgeDir = DODGE_Active;
	}

	exec function FeignDeath()
	{
		if (Physics == PHYS_Walking)
		{
			ServerFeignDeath();
			Acceleration = vect(0,0,0);
			GotoState('FeigningDeath');
		}
	}
     
	//Player Jumped
	function DoJump(optional float F)
	{
		GotoState('PlayerWalking');
	}
}


exec function GoWallWalk()
{
	GotoState('WallWalk');
	ClientMessage("In State WallWalk!");
}

defaultproperties
{
	bDisableViewFixing=False
}

The UT2k3 viewfixing stuff locks the viewrotation a lot but that's just because I haven't taken the time modify the code properly to suit it.. The reason it happens is becuase the polygon your attached to is relative to your viewrotation, this wasn't a problem before since I didn't have any code to update the view but it's a problem now since it's constantly updated... If you want to try fix/change it go ahead :)
 
Last edited by a moderator: