I'm a doctor, not a mechanic

Legacy:Mod Ideas/LocalGravity

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

Moved from my Personal Projects page

Local Gravity[edit]

The Idea[edit]

The Idea is to allow mappers greater control of the gravity in the map, allowing people to walk on walls, around a planet, or in general whatever can make a level more fun.

The Progress[edit]

My progress thus far has been with editing the PlayerSpidering state of the Playercontroller, and here is most of my code thus far.

//=============================================================================
 
// GravPlayer.uc
 
//=============================================================================
 
class GravPlayer extends xPlayer;
 
var float MaxAcceleration, AccelerationDampening;
 
function Possess(Pawn aPawn)
 
{
 
	Super.Possess(aPawn);
 
	GoToState('PlayerSpidering');
 
}
 
state PlayerSpidering
 
{
 
function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
 
{
 
	local vector OldAccel;
 
	OldAccel = Pawn.Acceleration;
 
	if ( Pawn.Acceleration != NewAccel )
 
		Pawn.Acceleration = NewAccel;
 
	if ( bPressedJump )
 
		DoJump(bUpdating);
 
}
 
//Should put in the Pawn if possible, to eaise bot Implementation.
 
function bool DoJump( bool bUpdating )
 
{
  if ( !Pawn.bIsCrouched && !Pawn.bWantsToCrouch && Pawn.Physics == PHYS_Spider )
  {
    if ( Pawn.Role == ROLE_Authority )
    {
      if ( (Level.Game != None) && (Level.Game.GameDifficulty > 2) )
        MakeNoise(0.1 * Level.Game.GameDifficulty);
      if ( Pawn.bCountJumps && (Pawn.Inventory != None) )
        Pawn.Inventory.OwnerEvent('Jumped');
    }
    if ( Pawn.Physics == PHYS_Spider )
      Pawn.Velocity += Pawn.JumpZ * Pawn.Floor;
     if ( (Pawn.Base != None) && !Pawn.Base.bWorldGeometry )
      Pawn.Velocity.Z += Pawn.Base.Velocity.Z;
 
	   Pawn.PhysicsVolume.Gravity = vect(0,0,0);
    Pawn.SetPhysics(PHYS_Falling);
        return true;
  }
    return false;
 
}
 
function UpdateRotation(float DeltaTime, float maxPitch)
 
{
  local rotator ViewRotation;
  local vector MyFloor, CrossDir, FwdDir, OldFwdDir, OldX, RealFloor, PawnX, PawnZ;
 
  if ( bInterpolating || Pawn.bInterpolating )
  {
      ViewShake(deltaTime);
      return;
  }
 
  TurnTarget = None;
  bRotateToDesired = false;
  bSetTurnRot = false;
 
  if ( (Pawn.Base == None) || (Pawn.Floor == vect(0,0,0)) )
  {
    if(OldFloor == vect(0,0,0))
    OldFloor = vect(0,0,1);
    MyFloor = OldFloor;
  }
  else
      MyFloor = Pawn.Floor;
 
  if ( MyFloor != OldFloor )
  {
      // smoothly change floor
      RealFloor = MyFloor;
      MyFloor = Normal(6*DeltaTime * MyFloor + (1 - 6*DeltaTime) * OldFloor);
      if ( (RealFloor Dot MyFloor) > 0.999 )
          MyFloor = RealFloor;
      else
      {
      // translate view direction
        CrossDir = Normal(RealFloor Cross OldFloor);
        FwdDir = CrossDir Cross MyFloor;
        OldFwdDir = CrossDir Cross OldFloor;
        ViewX = MyFloor * (OldFloor Dot ViewX)
              + CrossDir * (CrossDir Dot ViewX)
              + FwdDir * (OldFwdDir Dot ViewX);
        ViewX = Normal(ViewX);
 
        ViewZ = MyFloor * (OldFloor Dot ViewZ)
              + CrossDir * (CrossDir Dot ViewZ)
              + FwdDir * (OldFwdDir Dot ViewZ);
        ViewZ = Normal(ViewZ);
        OldFloor = MyFloor;
        ViewY = Normal(MyFloor Cross ViewX);
      }
  }
 
  //Moved here because it is already calculated here
  //Pawn.FaceRotation(OrthoRotation(ViewX,ViewY,ViewZ), deltaTime );
 
  if ( (aTurn != 0) || (aLookUp != 0) )
  {
    // adjust Yaw based on aTurn
    if ( aTurn != 0 )
        ViewX = Normal(ViewX +  ViewY * Sin(0.0031*DeltaTime*aTurn));
 
    // adjust Pitch based on aLookUp
    if ( aLookUp != 0 )
    {
        OldX = ViewX;
        ViewX = Normal(ViewX +  ViewZ * Sin(0.0031*DeltaTime*aLookUp));
        ViewZ = Normal(ViewX Cross ViewY);
 
        //bound max pitch
        //Redo this now
        /*if ( (ViewZ Dot MyFloor) < 0.1   )
        {
            OldX = Normal(OldX - MyFloor * (MyFloor Dot OldX));
            if ( (ViewX Dot MyFloor) > 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);
  PawnX = Normal(ViewY Cross MyFloor);
  PawnZ = Normal(PawnX Cross ViewY);
  Pawn.FaceRotation(OrthoRotation(PawnX,ViewY,PawnZ), deltaTime );
  //Pawn.FaceRotation(ViewRotation, deltaTime );
 
}
 
function PlayerTick(float DeltaTime)
 
{
 
	local Vector HitLocation, HitNormal, X, Y, Z;
 
	local Actor HitActor;
 
	Super.PlayerTick(DeltaTime);
 
	GetAxes(Pawn.Rotation, X, Y, Z);
 
	if(Pawn.Physics == PHYS_Falling)
 
	{
 
	  if(VSize(Pawn.Acceleration) > MaxAcceleration)
 
	   Pawn.Acceleration = Normal(Pawn.Acceleration) * MaxAcceleration;
 
	  else
 
	   Pawn.Acceleration *= AccelerationDampening;
 
	  Pawn.Acceleration += Z * Pawn.PhysicsVolume.default.Gravity.Z;
 
	  Pawn.Velocity += Pawn.Acceleration*DeltaTime;
 
	  //Pawn.Acceleration = vect(0,0,0);
 
	  //Change 70 to something less, static.
      HitActor = Trace(HitLocation, HitNormal, Pawn.Location+Normal(Pawn.Velocity)*100, Pawn.Location);
      if(HitActor != None && HitActor.bWorldGeometry)
      {
        Log("Here2");
        Pawn.SetPhysics(PHYS_Spider);
        Pawn.SetBase(HitActor , HitNormal);
      }
 
	}
 
}
 
}
 
defaultproperties
 
{
  AccelerationDampening=0.1
  MaxAcceleration=200
  PawnClass=class'LocalGravity.GravPawn'
 
}

ProcessMove is overridden to use a DoJump in this class, will probally get rid of this when I move that code back to the Pawn.

UpdateRotation is mostly the same as in PlayerController.uc, except for a bit of math, that being in the middle of the function, no real way I could reuse it without copying it.

Now, what I would like some suggestions on, are in my PlayerTick. the Trace that I am doing has a static number in there, I kinda need a better way, this will make you stick to soon when falling straight down, or not at all when falling too diagonal.

Ohh yes, and we want to be able to get it into our map. So, an Actor!

//=============================================================================
 
// LocalGravActor.uc
 
//=============================================================================
 
class LocalGravActor extends Actor
  placeable;
 
var() Class<PlayerController> PCClass< SEMI >
 
var() string PlayerClassName;
 
function PreBeginPlay()
 
{
  Level.Game.PlayerControllerClass = PCClass< SEMI >
  Level.Game.DefaultPlayerClassName = PlayerClassName;
 
}
 
defaultproperties
 
{
  PCClass=class'LocalGravity.GravPlayer'
  PlayerClassName="LocalGravity.GravPawn"
  bHidden=true
 
}

To Do[edit]

The most pressing matters are finding a better way to see if we should be on something then

      HitActor = Trace(HitLocation, HitNormal, Pawn.Location+Normal(Pawn.Velocity)*100, Pawn.Location);
      if(HitActor != None && HitActor.bWorldGeometry)

Then fix thirdperson camera, allow more flexibality when creating the level, and giving bots the same flexibility

Comments[edit]

Glacian: I am working on a similar mod, maybe we could combine forces....muwahaha! I fixed the bounded view angle problem by substituting in quaternion rotation, and I've coded up some modified gravity, doublejumping, and dodging code to work at any angle. I stuck only on the problem of getting the physics to allow the pawn to walk on the wall, and phys_spidering has some behaviors I don't like. If you (or anyone else) are interested, my email is focusgir (at) yahoo (dot) com.