Announcement

Collapse
No announcement yet.

Looking for a video tutorial on vehicles

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Hi guys, I need some help with an airplane.

    It is based on ONSPlaneCraft:

    My Current Def. Properties (related to movement/flying) are:

     
    Spoiler


    My problems are:
    The plane flies very unrealistically.
    I need to move the mouse many times like crazy in order to bank the airplane.
    I need to bank almost 90 degrees to get a chance to steer.
    The steering is very slow....

    If anyone has made an unrealistically flying airplane, please share your experience. Thx!
    Last edited by Deggenyr; 09-23-2019, 11:00 AM.

    Comment


      Hey Deggenyr. Karma physics Planes are kind of tough. AirPower used the fake planecode/projectiles as I recall (similar to the SpaceFighters) to get their flying working, which is nice, but didn't use karma physics. I tried getting a couple of modified planes working, but most maps weren't large enough to use them, and I lost interest in working on them

      Here is some code I was using to try and implement both flying, and taxi-ing on the run way. I converted the C++ plane flying code into UnrealScript so that I could change the behavior (see the various checks for bOnGround). I print the plane's forward speed on the screen and use the chargebar to indicate thrust as a percentage of MaxThrust. The plane must reach 2000 uus forward speed (what the MinAirSpeed and kMaxSpeed variables are set to) before you can pull back on the mouse to get the plane off the ground. Because of the relative slow speed, I should probably adjust the drag factors a bit and lift calculations since I lose lift pretty fast when I bank this vehicle to turn it. I did get the mouse to bank it a lot faster though....
      Code:
      class TDJetTest extends ONSBomber;
      
      /*
        So, what I've done here is to try and create a more forgiving (e.g. poorly
        implemented and unrealistic, but hopefully fun) model for flight that restricts
        the player from turning too sharply based on their forward velocity.  They can
        then turn as much as I allow without really having to worry about losing lift, BUT
        if they hit a wall they will explode, and they can't do any cool aerobatic tricks
        like stalling & pitching over, or the "fighter jet wheelie"
      
        What I want:
        -Strafe:
            >on the ground turns the Jet, or rather applies a force at the front wheel
             in the lateral direction
            >in the air applies slight banking turn with roughly constant "tightness" that eases in-out
        -Rotation Pitch:
            >on the ground only affect camera... transitions into controlling nose pitch
             after take off
            >in the air control the nose pitch
        -Rotation Yaw:
            >on the ground only affect camera... transitions into controlling nose pitch
             after take off
            >in the air control the roll angle
      
      The "lift" feature seems problematic.... or at least harder to understand/troubleshoot
      so instead lets screw with the KActorGravScale variable so that we change it from 2.0
      while on the ground to 0.0 while flying at some full speed...
      
      */
      
      var     vector  UCForce, UCTorque;
      var     float TDBCurrentThrust;
      var()   InterpCurve   LiftSpeedGravCurve; // Input is forward speed as % of max, output is Kgravity scale
      
      
      var byte TestByteA, TestByteB;
      
      var float MinAirSpeed, MaxAirSpeed;
      var float MaxBrakeDampening;
      var float SavePitchTorque;
      var float SaveBankTorque;
      
      var string SdebugRotDelta, SdebugThrottleStr, SdebugKafStr, SdebugTorqueStr;
      
      
      // Calculate forces for thrust/turning etc. and apply them.
      simulated event UpdateVehicle(float DeltaTime){
          local vector Up, Force, Torque, DirX, DirY, DirZ, Forward, Right, Lift, Thrust,
                       Drag, RelativeWindVelocity, LateralVelocity, NormalizedVelocity,
                       CurPitchTorque, PitchDampening, CurBankTorque, BankDampening,
                       BrakingForce, TaxiTorque;
          local float AngleOfAttack, RelativeWindFactor, NewGravScale, Speed,
                      PitchTorqueScale, BankTorqueScale, TaxiTorqueScale;
          local int i, ViewOffsetPitch, ViewOffsetYaw;
          local rotator ViewOffset;
          local bool bOnGround;
          //local KRigidBodyState rbState;
          local KarmaParams KP;
      
          // Dont go adding forces if vehicle is asleep.
          if( !KIsAwake() )
              return;
      
          //KGetRigidBodyState(rbState); // danger, this function loads and overwrites
          KP = KarmaParams(KParams);
          if(KP == none)
              return;
          //TestByteA++;
          // Calc up (z), right(y) and forward (x) vectors
          GetAxes(Rotation, DirX, DirY, DirZ);
      
          // 'World plane' forward & right vectors ie. no z component.
          Forward = DirX;
          Forward.Z = 0.0f;
          Forward=Normal(Forward);
      
          Right = DirY;
          Right.Z = 0.0f;
          Right=Normal(Right);
      
          Up=vect(0,0,1);
      
          // Get body angular velocity (JTODO: Add AngularVelocity to Actor!)
      
      //////////////////////////////////////////////////////////////////////////////////////////////
      
          if (Controller!=none){
              // FIXME? below, test if the native code may have already wiped this out by resetting to zero
              ViewOffsetPitch = Controller.Rotation.Pitch & 65535;
              ViewOffsetYaw = Controller.Rotation.Yaw & 65535;
              SdebugThrottleStr = "ControllerRotation: Pitch"@Controller.Rotation.Pitch@", Yaw: "@Controller.Rotation.Yaw;
      
              if (ViewOffsetPitch > 32768)
                  ViewOffsetPitch -= 65535;
      
              if (ViewOffsetYaw > 32768)
                  ViewOffsetYaw -= 65535;
      
              // Reset Controller Rotation
              Controller.SetRotation(Rot(0,0,0)); // <-FIXME? the native code may have already wiped this out
      
              //bOnGround = true;
              for(i=0; i<KP.Repulsors.Length; i++){
                  if( KP.Repulsors[i] != None && KP.Repulsors[i].bRepulsorInContact )
                      bOnGround = true;
              }
      
              // THRUST //
              //TestByteB++;
              if (OutputThrust > 0)
              //SdebugThrottleStr = "Throttle: "@Throttle@", OutputThrust: "@OutputThrust@", PlaneState->ServerThrust:"@PlaneState.ServerThrust;
                  TDBCurrentThrust = FMin(TDBCurrentThrust + (ThrustAcceleration * DeltaTime), MaxThrust);
              else if (OutputThrust < 0) // only decrease thrust if we are actively trying to slow it down
                  TDBCurrentThrust = FMax(TDBCurrentThrust - (ThrustAcceleration * DeltaTime), 0.0);
              //else
              //    TDBCurrentThrust = FMax(TDBCurrentThrust - (ThrustAcceleration * DeltaTime), 0.0);
      
              Thrust = TDBCurrentThrust * DirX;
      
              // RELATIVE WIND //
              LateralVelocity = (Velocity dot DirY) * DirY;
              RelativeWindVelocity = -(Velocity - LateralVelocity); // Remove the Y component of the velocity and take the inverse
              RelativeWindFactor = AirFactor * VSize(RelativeWindVelocity) * VSize(RelativeWindVelocity);
      
              // ANGLE OF ATTACK //
              AngleOfAttack = Acos(FClamp((DirX dot -RelativeWindVelocity) / VSize(RelativeWindVelocity), -1.0, 1.0));
              AngleOfAttack = (AngleOfAttack / 3.14159f) * 360.0f;
              if ((DirZ dot -RelativeWindVelocity) > 0)
                  AngleOfAttack *= -1;
      
              // LIFT //
              Lift = DirZ * InterpCurveEval(LiftCoefficientCurve, AngleOfAttack) * RelativeWindFactor; // <- this assumes a certain airspeed to overcome gravity
      
              // "fake lift", really just turning off gravity..
              Speed = Velocity dot DirX;
              NewGravScale = InterpCurveEval(LiftSpeedGravCurve, Speed/MinAirSpeed);
              SdebugThrottleStr = SdebugThrottleStr @ ", GRAVSCALE: "@NewGravScale;
             // KSetActorGravScale(NewGravScale); // <- this works OK, but not great, and seem to be
      
              // DRAG //
              NormalizedVelocity = Normal(Velocity);
              Drag = InterpCurveEval(DragCoefficientCurve, AngleOfAttack) * RelativeWindFactor * -NormalizedVelocity;
      
              // BRAKING when taxiing
              if(bOnGround && OutputRise < 0){
                  // add some sort of drag?
                  BrakingForce = MaxBrakeDampening * Forward * Speed;
              }
      
              // ADD FORCES AND APPLY
              Force = Thrust + Lift + Drag - LateralVelocity * 0.2 - BrakingForce;
      
      
              ////////////
              // TORQUE //
              ////////////
              ViewOffset.Pitch = ViewOffsetPitch;
              ViewOffset.Yaw = -ViewOffsetYaw;
              ViewOffset.Roll = 0;
      
      
              // Pitching Torque
              PitchTorqueScale = Abs(float(ViewOffset.Pitch) / 4096.0);
              if (ViewOffset.Pitch > 0){
                  CurPitchTorque = PitchTorque * FMin(VSize(RelativeWindVelocity)/ MinAirSpeed, 1.0) * PitchTorqueScale * DirY;// MinAirSpeed used to be 3000 in this line
                  SavePitchTorque = VSize(CurPitchTorque); // DEBUG
              }else{
                  CurPitchTorque = PitchTorque * FMin(VSize(RelativeWindVelocity)/ MinAirSpeed, 1.0) * PitchTorqueScale * -DirY;// MinAirSpeed used to be 3000 in this line
                  SavePitchTorque = -1*VSize(CurPitchTorque); // DEBUG
              }
              //// Pitch Dampening
              //PitchDampening = -CurPitchTorque * AngleOfAttack / 90.0;
      
              // Banking Torque
              BankTorqueScale = Abs(float(ViewOffset.Yaw) / 4096.0);
              if (ViewOffset.Yaw > 0){
                  CurBankTorque = BankTorque * FMin(VSize(RelativeWindVelocity) / MinAirSpeed, 1.0) * BankTorqueScale * DirX;// MinAirSpeed used to be 3000 in this line
                  SaveBankTorque = VSize(CurBankTorque); // DEBUG
              }else{
                  CurBankTorque = BankTorque * FMin(VSize(RelativeWindVelocity) / MinAirSpeed, 1.0) * BankTorqueScale * -DirX;// MinAirSpeed used to be 3000 in this line
                  SaveBankTorque = -1*VSize(CurBankTorque); // DEBUG
              }
              //// Bank Dampening
              //BankDampening = -CurBankTorque * AngleOfAttack / 90.0;
      
              //StrafeTorque = (200 * -OutputStrafe * OnGroundTorqueScale) * Up;
              if(bOnGround && OutputStrafe != 0){
                  //Speed = VSize(Velocity);
                  TaxiTorqueScale = 1;// InterpCurveEval(HoverForceCurve, Speed) / 700;
                  TaxiTorque = (200 * -OutputStrafe * TaxiTorqueScale) * vect(0,0,1);
              }
              SdebugTorqueStr="TORQUE: Pitch"@SavePitchTorque@", Roll: "@SaveBankTorque;
              Torque = CurPitchTorque + PitchDampening + CurBankTorque + BankDampening + TaxiTorque;
      
              // Apply force/torque to body.
              //debugf(TEXT("BankTorqueScale: %f   ViewOffset.Yaw: %f"), BankTorqueScale, ViewOffset.Yaw);
      
          }
          //KAddForces(Force, Torque); // this can't be called from UScript
          UCForce = Force;
          UCTorque = Torque;
      }
      
      
      simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos){
          Super.DisplayDebug(Canvas, YL, YPos);
          Canvas.SetDrawColor(255,0,0);
          Canvas.DrawText("TDBThrust = "@TDBCurrentThrust@", TestbyteA "@TestByteA @", TestbyteB "@ TestByteB);
          YPos += YL;
          Canvas.DrawText(SdebugThrottleStr);
          YPos += YL;
          Canvas.DrawText(SdebugTorqueStr);
          YPos += YL;
          //Canvas.DrawText(SdebugKafStr);
          //YPos += YL;
      }
      
      simulated function float ChargeBar()
      {
          return TDBCurrentThrust/MaxThrust;
      }
      
      simulated function KApplyForce(out vector Force, out vector Torque){
          //local float OnGroundTorqueScale, Speed;
          Super.KApplyForce(Force, Torque);
          Force = UCForce;
          Torque = UCTorque;
      
          // Try to add some turning force while on the ground, THIS WORKS PRETTY WELL!
          //Speed = VSize(Velocity);
          //OnGroundTorqueScale = InterpCurveEval(HoverForceCurve, Speed) / 700;
          //Torque += (200 * -OutputStrafe * OnGroundTorqueScale) * vect(0,0,1);
      
          // now zero them out so they don't persist to the next tick
          UCForce = vect(0,0,0);
          UCTorque = vect(0,0,0);
          //SdebugKafStr =" -- Kaf Force: "@Force@", Torque"@Torque;
      }
      
      // try to fix the first person view, to actually view in FP
      simulated function SpecialCalcFirstPersonView(PlayerController PC, out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
      {
         local vector CamLookAt;//, HitLocation, HitNormal;
         local float LerpAmount;
         local float CurTime;
      
         ViewActor = self;
      
         CurTime = Level.TimeSeconds;
         LerpAmount = 1.0 - ( CameraSwingRatio ** (CurTime - LastCamTime) );
         LastCamTime = CurTime;
            CamLookAt = Location;
            CameraRotation.Roll = Rotation.roll;
            CameraRotation.Yaw = LastCamRot.Yaw + GetRotDiff(Rotation.Yaw, LastCamRot.Yaw) * LerpAmount;
            CameraRotation.Pitch = Rotation.pitch;
      
          CameraLocation = CamLookAt + (FPCamPos >> Rotation);
         LastCamRot = CameraRotation;
      }
      
      
      simulated function DrawHUD(Canvas Canvas)
      {
          local float ScaleX, ScaleY;
          local float DirXSpeed;
      
          super.DrawHUD(Canvas);
          // Draw some bars near the center that represent the forces being applied for
          // pitch and roll, and forward speed
          if (IsLocallyControlled())
          {
              DirXSpeed = Velocity dot vector(Rotation);
              Canvas.Font = Canvas.MedFont;
              ScaleX = Canvas.clipX/1024;
              ScaleY = Canvas.clipY/768;
              Canvas.SetDrawColor (20, 255, 20 ,255);
              Canvas.DrawColor.A = 255;
              Canvas.Style = ERenderStyle.STY_Alpha;
              Canvas.DrawTextJustified("Fwd Speed:"@DirXSpeed, 1, Canvas.clipX/2, Canvas.clipY/2 , Canvas.ClipX/2 + ScaleX*150, Canvas.clipY/2 + ScaleY*15);
              // No Torque Bar code yet...
              //SavePitchTorque =;
              //SaveBankTorque =;
           }
      }
      
      
      defaultproperties
      {
          bShowChargingBar=true // for displaying the thrust!
      
          VehiclePositionString="in a TD Harrier Jet"
          VehicleNameString="TD Harrier Jet"
      
          Mesh=Mesh'Harrier_mesh_v4'
          RedSkin=material'MiG35Skin_shad'
          BlueSkin=material'MiG35Skin_shad'
          skins(1)=material'BHawkInteriorSkin'
          DriverWeapons(0)=(WeaponClass=class'JetMiG35_PilotGun',WeaponBone=tip_R);
      
          Health=2000
          HealthMax=2000
          CollisionHeight=+120.0
          CollisionRadius=380.0
      
          IdleSound=sound'ONSVehicleSounds-S.Flying.Flying02'
          MaxPitchSpeed=3200
          SoundVolume=255
      
          Begin Object Class=KarmaParamsRBFull Name=KParamsHarrier
              KInertiaTensor(0)=3.5
              KInertiaTensor(1)=0.0
              KInertiaTensor(2)=0.0
              KInertiaTensor(3)=10
              KInertiaTensor(4)=0.0
              KInertiaTensor(5)=13
              KCOMOffset=(X=0.65,Y=0.0,Z=0.0)
              KStartEnabled=True
              KFriction=0.6
              KLinearDamping=0.0
              KAngularDamping=1.5
              bKNonSphericalInertia=True
              bHighDetailOnly=False
              bClientOnly=False
              bKDoubleTickRate=True
              KActorGravScale=2.0
              KMaxSpeed=2000//2500.0//4000.0
              KImpactThreshold=300
              bDestroyOnWorldPenetrate=True
              bDoSafetime=True
              Name="KParamsHarrier"
          End Object
          KParams=KarmaParams'KParamsHarrier'
      
          DrawScale=1.0
      
          //VehicleMass=4
      
          //bDrawDriverInTP=False
          //bDrawMeshInFP=True
          //TPCamDistance=500
          //TPCamLookAt=(X=0.0,Y=0.0,Z=0)
          //TPCamWorldOffset=(X=0,Y=0,Z=200)
          FPCamPos=(X=260,Y=0.0,Z=60.0)
          //TPCamDistance=500
          //TPCamLookAt=(X=0.0,Y=0.0,Z=0)
          //TPCamWorldOffset=(X=0,Y=0,Z=200)
          DrivePos=(X=260.0,Y=0.0,Z=60.0)
          EntryPosition=(X=250.0,Y=0.0,Z=0.0)
          EntryRadius=100.0
      
          LiftSpeedGravCurve=(Points=((InVal=0.0,OutVal=2.0),(InVal=0.3,OutVal=1.3),(InVal=0.6,OutVal=0.8),(InVal=0.75,OutVal=0.5),(InVal=0.85,OutVal=0.2),(InVal=1.0,OutVal=0.0),(InVal=4.0,OutVal=0.0)))
          MinAirSpeed=2000//2500
          MaxAirSpeed=3500
          MaxBrakeDampening=0.25
      
          LiftCoefficientCurve=(Points=((InVal=-180,OutVal=0.0),(InVal=-10.0,OutVal=0.0),(InVal=0.0,OutVal=0.4),(InVal=6.0,OutVal=0.8),(InVal=10.0,OutVal=1.2),(InVal=12.0,OutVal=1.4),(InVal=20.0,OutVal=0.8),(InVal=60.0,OutVal=0.6),(InVal=90.0,OutVal=0.0),(InVal=180.0,OutVal=0.0)))
          DragCoefficientCurve=(Points=((InVal=-180,OutVal=0.0),(InVal=-90.0,OutVal=1.2),(InVal=-10.0,OutVal=0.1),(InVal=-5.0,OutVal=0.35),(InVal=0.0,OutVal=0.01),(InVal=5.0,OutVal=0.35),(InVal=10.0,OutVal=0.1),(InVal=15.0,OutVal=0.3),(InVal=60.0,OutVal=1.0),(InVal=90.0,OutVal=1.2),(InVal=180.0,OutVal=0.0)))
          AirFactor=0.00010//<- good for 2000uu airspeed, good for 4000uu airspeed-> 0.00005
      
          HoverForceCurve=(Points=((InVal=0,OutVal=500),(InVal=30,OutVal=700),(InVal=250,OutVal=0)))
          COMHeight=20.0
          MaxThrust=110.0
          PitchTorque=700.0
          BankTorque=700.0
          ThrustAcceleration=60.0
          bHoverOnGround=True
      
          //ImpactDamageThreshold=1000
          ImpactDamageMult=0.01
      
          MomentumMult=0.05
      
          HoverSoftness=0.05//0.9
          HoverPenScale=1.5
          HoverCheckDist=85
      
          ThrusterOffsets(0)=(X=176,Y=0,Z=10)
          ThrusterOffsets(1)=(X=-112,Y=180,Z=10)
          ThrusterOffsets(2)=(X=-112,Y=-180,Z=10)
          ThrusterOffsets(3)=(X=-176,Y=0,Z=10)
      
          ExitPositions(0)=(X=0,Y=500,Z=100)
          ExitPositions(1)=(X=0,Y=-500,Z=100)
          ExitPositions(2)=(X=350,Y=0,Z=100)
          ExitPositions(3)=(X=-350,Y=0,Z=100)
      
          //bZeroPCRotOnEntry=true
          bEjectDriver=true
          bEjectPassengersWhenFlipped=false
          bCanBeBaseForPawns=true
      }
      Last edited by meowcatbuf; 10-14-2019, 10:55 AM.

      Comment

      Working...
      X