Announcement

Collapse
No announcement yet.

Looking for a video tutorial on vehicles

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

    Thank you Mad Maxx, those are perfect! And thank you for including the picture of the other vehicle around it for scale too. Golly that is a big vehicle!

    Comment


      Hi Maxx,
      Yeah, should be ready to link the animations now.

      In this case I think there is some pretty simple code that might work. The 'pawn' class (which is the parent class of vehicles) has a couple of variables that can be used to store the animation names. The 'MovementAnims' array holds 4 names for the animations that the pawns should play when moving forward, back, left and right. There is also the 'TurnLeftAnim', 'TurnRightAnim' and 'IdleRestAnim'. These can be filled in down in your default properties like this, with the animation name from the BF2142 mech skeletal animation set that would look best:
      Code:
          // change the RunF/RunB/RunL/RunR/TurnR/TurnL/Idle_Rest to the names of the BF2142 mech animation would look best
          MovementAnims(0)=RunF
          MovementAnims(1)=RunB
          MovementAnims(2)=RunL
          MovementAnims(3)=RunR
          TurnRightAnim=TurnR
          TurnLeftAnim=TurnL
          IdleRestAnim=Idle_Rest
      Now the xPawn class (the pawn class of your player that actually runs around in game) has some native (C++) code that actually play the appropriate animations based on the pawn's Physics state (walking, falling, flying, swimming etc.), ground speed, and whether the player is pressing crouch or walk. I converted that native code (which was included in the UT2004 source code for reference) into UScript code about 10 years ago (unfortunately UnrealWiki is down right now but I'll kink it later), so all we have to do is use portions of that in this case.

      I think for starters all you'll really need to do is have the Mech play the an idle/still animation when not moving (or falling), a turning animation when turning in place, or a moving animation. So here is a sample function that might work (this is very simplified, and could be made "nicer" with added code, but should get you started...), note that this is completely untested:

      Code:
      /* simply add this function call to your 'Tick' function right after CheckJumpDuck(); by adding this line
      
      UpdateMechAnim(DeltaTime);
      
      */
      // Then paste this function code block in your code after the 'KApplyForce' 
      // function code block and before the 'StaticPrecache' function code block 
      // (you can actually paste the new function after any of the function code
      // blocks as long as it is after all of the class variables have been declared
      // at the top, and before you begin listing the default properties.
      
      simulated function UpdateMechAnim(float DeltaTime)
      {
          local int NewAnimDirection;
          local KRigidBodyState BodyState;
          local float  TurnZAmount;
      
           // if we are on a server, don't bother playing the animations....  though you might want to for collision purposes even if they don't  completely sync up on the clients and server...
          if ( Level.NetMode == NM_DedicatedServer )
              return;
          // Don't bother running the animations if this particular mech has not been rendered for over a second on this computer
          if (Level.TimeSeconds - LastRenderTime > 1.0){
              return;
          }
          // Now start checking for whether the player is moving, standing still, or turning.
          //  The check for 80 may sound like a lot, but for a vehicle, 80 UU/seconds is not very fast at all
          // so we are basically standing still, or only moving very very slowly, so don't animate the legs 
          // as walking
          
          if(VSize(Velocity) < 80)
          {
                KGetRigidBodyState(BodyState);
                 TurnZAmount = BodyState.AngVel.Z; // how much we are turning around the  Z-Axis, I do not know what unit this is in: radians-per-second,  degrees-per-second, rotations-per-second, URots-per-second it could eb  any of these.
                if(Abs(TurnZAmount) > 40) // NOTE!!!!: you  will probably have to change the '40' to some other value since I don't  know what the typical magnitude of the AngularVelocity (AngVel) would  be expected to see...
                {
                    if(TurnZAmount  > 0) LoopAnim(TurnRightAnim, 1.0, 0.1f, 0); // you might need to swap  the '>' operator for '<' if the animations are turning the wrong  direction.
                    else LoopAnim(TurnLeftAnim, 1.0, 0.1f, 0);
                }
                else // we're not turning, so we must just be standing in place...
                    LoopAnim(IdleRestAnim, 1.0, 0.1f, 0);
          }
          // we must be moving then, so first lets check to see if we are falling
          // and if we are not falling then, we're probably running around
          else
          {
               VDirectionNormal = Normal(Velocity); // turn the velocity vector into a  'Unit Vector' (length == 1.0) and see if it mostly points down
              if(VDirectionNormal.Z < -0.8) // we are mostly falling!
              {
                    LoopAnim(IdleRestAnim, 1.0, 0.1f, 0); // go ahead and play the IdleRestAnim while falling
              } 
              else
              {
                     NewAnimDirection = Get4WayDirection(); // this native C++ function returns 0,1,2,  or 3 based on which direction the pawn is moving compared to their  facing direction
                    LoopAnim(MovementAnims[NewAnimDirection], 1.0, 0.1f, 0);
              }
          }
      }
      Now, if the animations don't include "strafing" left and right animations, then you will end up having to also change the direction of the mesh just like the UT pawns do when the player is turning while standing still (watch your player in third person, you twist your pawn's body to the left and right about 45 degrees before they will start turning too). I have converted code for this too if its needed, but it get a bit more complex.
      Last edited by meowcatbuf; 03-26-2017, 08:35 PM.

      Comment


        Whoops! If you look at my code, 'VDirectionNormal' is a vector variable (the function 'Normal(vector MyVector)' returns a normalized vector), but I failed to declare it in the beginning of the function or above in the class variables. I've edited the code you posted with 'VDirectionNormal' declared as a local variable, and also made a few other corrections, see highlights in blue.

        and yes wordwrap should never be used if you writing your code in Notepad. I use the Unreal Development Environment (UDE), which was a version of WotGreal licensed by Epic for UT2k4, to do all my code editing since it has syntax highlighting.

        Code:
        //-----------------------------------------------------------
        //
        //-----------------------------------------------------------
        class BF2142_Chassis extends ONSHoverCraft;
        
        #exec OBJ LOAD FILE=..\Animations\MegaForce_A.ukx
        #exec OBJ LOAD FILE=..\textures\MegaForceTX.utx
        
        var()   float   MaxPitchSpeed;
        
        var()   float   JumpDuration;
        var()    float    JumpForceMag;
        var     float   JumpCountdown;
        var     float    JumpDelay, LastJumpTime;
        
        var()   float   DuckDuration;
        var()   float   DuckForceMag;
        var     float   DuckCountdown;
        
        var()    array<vector>                    BikeDustOffset;
        var()    float                            BikeDustTraceDistance;
        
        var()   sound                           JumpSound;
        var()   sound                           DuckSound;
        
        // Force Feedback
        var()    string                            JumpForce;
        
        var        array<ONSHoverBikeHoverDust>    BikeDust;
        var        array<vector>                    BikeDustLastNormal;
        
        var        bool                            DoBikeJump;
        var        bool                            OldDoBikeJump;
        
        var        bool                            DoBikeDuck;
        var        bool                            OldDoBikeDuck;
        var     bool                            bHoldingDuck;
        
        replication
        {
            reliable if (bNetDirty && Role == ROLE_Authority)
                DoBikeJump;
        }
        
        function Pawn CheckForHeadShot(Vector loc, Vector ray, float AdditionalScale)
        {
            local vector X, Y, Z, newray;
        
            GetAxes(Rotation,X,Y,Z);
        
            if (Driver != None)
            {
                // Remove the Z component of the ray
                newray = ray;
                newray.Z = 0;
                if (abs(newray dot X) < 0.7 && Driver.IsHeadShot(loc, ray, AdditionalScale))
                    return Driver;
            }
        
            return None;
        }
        
        simulated function Destroyed()
        {
            local int i;
        
            if (Level.NetMode != NM_DedicatedServer)
            {
                for (i = 0; i < BikeDust.Length; i++)
                    BikeDust[i].Destroy();
        
                BikeDust.Length = 0;
            }
        
            Super.Destroyed();
        }
        
        simulated function DestroyAppearance()
        {
            local int i;
        
            if (Level.NetMode != NM_DedicatedServer)
            {
                for (i = 0; i < BikeDust.Length; i++)
                    BikeDust[i].Destroy();
        
                BikeDust.Length = 0;
            }
        
            Super.DestroyAppearance();
        }
        
        function bool Dodge(eDoubleClickDir DoubleClickMove)
        {
            Rise = 1;
            return true;
        }
        
        function ChooseFireAt(Actor A)
        {
            if (Pawn(A) != None && Vehicle(A) == None && VSize(A.Location - Location) < 1500 && Controller.LineOfSightTo(A))
            {
                if (!bWeaponIsAltFiring)
                    AltFire(0);
            }
            else if (bWeaponIsAltFiring)
                VehicleCeaseFire(true);
        
            Fire(0);
        }
        
        simulated event DrivingStatusChanged()
        {
            local int i;
        
            Super.DrivingStatusChanged();
        
            if (bDriving && Level.NetMode != NM_DedicatedServer && BikeDust.Length == 0 && !bDropDetail)
            {
                BikeDust.Length = BikeDustOffset.Length;
                BikeDustLastNormal.Length = BikeDustOffset.Length;
        
                for(i=0; i<BikeDustOffset.Length; i++)
                    if (BikeDust[i] == None)
                    {
                        BikeDust[i] = spawn( class'ONSHoverBikeHoverDust', self,, Location + (BikeDustOffset[i] >> Rotation) );
                        BikeDust[i].SetDustColor( Level.DustColor );
                        BikeDustLastNormal[i] = vect(0,0,1);
                    }
            }
            else
            {
                if (Level.NetMode != NM_DedicatedServer)
                {
                    for(i=0; i<BikeDust.Length; i++)
                        BikeDust[i].Destroy();
        
                    BikeDust.Length = 0;
                }
                JumpCountDown = 0.0;
            }
        }
        
        simulated function Tick(float DeltaTime)
        {
            local float EnginePitch, HitDist;
            local int i;
            local vector TraceStart, TraceEnd, HitLocation, HitNormal;
            local actor HitActor;
            local Emitter JumpEffect;
        
            Super.Tick(DeltaTime);
        
            EnginePitch = 64.0 + VSize(Velocity)/MaxPitchSpeed * 64.0;
            SoundPitch = FClamp(EnginePitch, 64, 128);
        
            JumpCountdown -= DeltaTime;
        
            CheckJumpDuck();
        
            UpdateMechAnim(DeltaTime);
        
            if(DoBikeJump != OldDoBikeJump)
            {
                JumpCountdown = JumpDuration;
                OldDoBikeJump = DoBikeJump;
                if (Controller != Level.GetLocalPlayerController())
                {
                    JumpEffect = Spawn(class'ONSHoverBikeJumpEffect');
                    JumpEffect.SetBase(Self);
                    ClientPlayForceFeedback(JumpForce);
                }
            }
        
            if(Level.NetMode != NM_DedicatedServer && !bDropDetail)
            {
                for(i=0; i<BikeDust.Length; i++)
                {
                    BikeDust[i].bDustActive = false;
        
                    TraceStart = Location + (BikeDustOffset[i] >> Rotation);
                    TraceEnd = TraceStart - ( BikeDustTraceDistance * vect(0,0,1) );
        
                    HitActor = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, True);
        
                    if(HitActor == None)
                    {
                        BikeDust[i].UpdateHoverDust(false, 0);
                    }
                    else
                    {
                        HitDist = VSize(HitLocation - TraceStart);
        
                        BikeDust[i].SetLocation( HitLocation + 10*HitNormal);
        
                        BikeDustLastNormal[i] = Normal( 3*BikeDustLastNormal[i] + HitNormal );
                        BikeDust[i].SetRotation( Rotator(BikeDustLastNormal[i]) );
        
                        BikeDust[i].UpdateHoverDust(true, HitDist/BikeDustTraceDistance);
        
                        // If dust is just turning on, set OldLocation to current Location to avoid spawn interpolation.
                        if(!BikeDust[i].bDustActive)
                            BikeDust[i].OldLocation = BikeDust[i].Location;
        
                        BikeDust[i].bDustActive = true;
                    }
                }
            }
        }
        
        ////Anim test part 2 // this call to the function is not inside the 'Tick' function code block, 
        // see edit above ;-) ^^^
        /* simply add this function call to your 'Tick' function right after CheckJumpDuck(); by adding this line
        
        UpdateMechAnim(DeltaTime); // this is actually inside a comment block because of the / and * and then * and / closing the comment block
        
        */
        ////
        
        function VehicleCeaseFire(bool bWasAltFire)
        {
            Super.VehicleCeaseFire(bWasAltFire);
        
            if (bWasAltFire)
                bHoldingDuck = False;
        }
        
        simulated function float ChargeBar()
        {
            // Clamp to 0.999 so charge bar doesn't blink when maxed
            if (Level.TimeSeconds - JumpDelay < LastJumpTime)
                return (FMin((Level.TimeSeconds - LastJumpTime) / JumpDelay, 0.999));
            else
                return 0.999;
        }
        
        simulated function CheckJumpDuck()
        {
            local KarmaParams KP;
            local Emitter JumpEffect, DuckEffect;
            local bool bOnGround;
            local int i;
        
            KP = KarmaParams(KParams);
        
            // Can only start a jump when in contact with the ground.
            bOnGround = false;
            for(i=0; i<KP.Repulsors.Length; i++)
            {
                if( KP.Repulsors[i] != None && KP.Repulsors[i].bRepulsorInContact )
                    bOnGround = true;
            }
        
            // If we are on the ground, and press Rise, and we not currently in the middle of a jump, start a new one.
            if (JumpCountdown <= 0.0 && Rise > 0 && bOnGround && !bHoldingDuck && Level.TimeSeconds - JumpDelay >= LastJumpTime)
            {
                PlaySound(JumpSound,,1.0);
        
                if (Role == ROLE_Authority)
                   DoBikeJump = !DoBikeJump;
        
                if(Level.NetMode != NM_DedicatedServer)
                {
                    JumpEffect = Spawn(class'ONSHoverBikeJumpEffect');
                    JumpEffect.SetBase(Self);
                    ClientPlayForceFeedback(JumpForce);
                }
        
                if ( AIController(Controller) != None )
                    Rise = 0;
        
                LastJumpTime = Level.TimeSeconds;
            }
            else if (DuckCountdown <= 0.0 && (Rise < 0 || bWeaponIsAltFiring))
            {
                if (!bHoldingDuck)
                {
                    bHoldingDuck = True;
        
                    PlaySound(DuckSound,,1.0);
        
                    DuckEffect = Spawn(class'ONSHoverBikeDuckEffect');
                    DuckEffect.SetBase(Self);
        
                    if ( AIController(Controller) != None )
                        Rise = 0;
        
                    JumpCountdown = 0.0; // Stops any jumping that was going on.
                }
            }
            else
               bHoldingDuck = False;
        }
        
        simulated function KApplyForce(out vector Force, out vector Torque)
        {
            Super.KApplyForce(Force, Torque);
        
            if (bDriving && JumpCountdown > 0.0)
            {
                Force += vect(0,0,1) * JumpForceMag;
            }
        
            if (bDriving && bHoldingDuck)
            {
                Force += vect(0,0,-1) * DuckForceMag;
            }
        }
        
        ////Anim test part 3
        // Then paste this function code block in your code after the 'KApplyForce' 
        // function code block and before the 'StaticPrecache' function code block 
        // (you can actually paste the new function after any of the function code
        // blocks as long as it is after all of the class variables have been declared
        // at the top, and before you begin listing the default properties.
        
        simulated function UpdateMechAnim(float DeltaTime)
        {
            local int NewAnimDirection;
            local KRigidBodyState BodyState;
            local float  TurnZAmount;
            local vector VDirectionNormal;
        
             // if we are on a server, don't bother playing the animations....
             // though you might want to for collision purposes even if they don't completely sync up on the clients and server...
            if ( Level.NetMode == NM_DedicatedServer )
                return;
            // Don't bother running the animations if this particular mech has 
            // not been rendered for over a second on this computer
            if (Level.TimeSeconds - LastRenderTime > 1.0){
                return;
            }
            // Now start checking for whether the player is moving, standing still, or turning.
            //  The check for 80 may sound like a lot, but for a vehicle, 80 UU/seconds is not very fast at all
            // so we are basically standing still, or only moving very very slowly, so don't animate the legs 
            // as walking
            
            if(VSize(Velocity) < 80)
            {
                  KGetRigidBodyState(BodyState);
                   TurnZAmount = BodyState.AngVel.Z; // how much we are turning around the  Z-Axis, 
             // I do not know what unit this is in: radians-per-second,  degrees-per-second, rotations-per-second, 
             // URots-per-second it could eb  any of these.
                  if(Abs(TurnZAmount) > 40) // NOTE!!!!: you  will probably have to change the '40' to some other value 
             // since I don't  know what the typical magnitude of the AngularVelocity (AngVel) would  be expected to see...
                  {
                      if(TurnZAmount  > 0) LoopAnim(TurnRightAnim, 1.0, 0.1f, 0); // you might need to swap  the '>' operator for '<' if the animations are turning the wrong  direction.
                      else LoopAnim(TurnLeftAnim, 1.0, 0.1f, 0);
                  }
                  else // we're not turning, so we must just be standing in place...
                      LoopAnim(IdleRestAnim, 1.0, 0.1f, 0);
            }
            // we must be moving then, so first lets check to see if we are falling
            // and if we are not falling then, we're probably running around
            else
            {
                 VDirectionNormal = Normal(Velocity); // turn the velocity vector into a   'Unit Vector' (length == 1.0) 
             // and see if it mostly points down
                if(VDirectionNormal.Z < -0.8) // we are mostly falling!
                {
                      LoopAnim(IdleRestAnim, 1.0, 0.1f, 0); // go ahead and play the IdleRestAnim while falling
                } 
                else
                {
                       NewAnimDirection = Get4WayDirection(); // this native C++ function returns 0,1,2,  
             // or 3 based on which direction the pawn is moving compared to their  facing direction
                      LoopAnim(MovementAnims[NewAnimDirection], 1.0, 0.1f, 0);
                }
            }
        }
        ////
        
        static function StaticPrecache(LevelInfo L)
        {
            Super.StaticPrecache(L);
        
            L.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverWing');
            L.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverChair');
            L.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris2');
            L.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris1');
            L.AddPrecacheStaticMesh(StaticMesh'ONSWeapons-SM.PC_MantaJumpBlast');
        
            L.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp2_frames');
            L.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp1_frames');
            L.AddPrecacheMaterial(Material'ExplosionTex.Framed.we1_frames');
            L.AddPrecacheMaterial(Material'AW-2004Particles.Fire.MuchSmoke1');
            L.AddPrecacheMaterial(Material'AW-2004Particles.Fire.NapalmSpot');
            L.AddPrecacheMaterial(Material'EpicParticles.Fire.SprayFire1');
            L.AddPrecacheMaterial(Material'WeaponSkins.Skins.RocketTex0');
            L.AddPrecacheMaterial(Material'AW-2004Particles.Energy.JumpDuck');
            L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hovercraftFANSblurTEX');
            L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftRED');
            L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftBLUE');
            L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.NewHoverCraftNOcolor');
            L.AddPrecacheMaterial(Material'AW-2004Particles.Energy.AirBlast');
            L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
            L.AddPrecacheMaterial(Material'Engine.GRADIENT_Fade');
        
        }
        
        simulated function UpdatePrecacheStaticMeshes()
        {
            Level.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverWing');
            Level.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverChair');
            Level.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris2');
            Level.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris1');
            Level.AddPrecacheStaticMesh(StaticMesh'ONSWeapons-SM.PC_MantaJumpBlast');
            Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hovercraftFANSblurTEX');
        
            Super.UpdatePrecacheStaticMeshes();
        }
        
        simulated function UpdatePrecacheMaterials()
        {
            Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp2_frames');
            Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp1_frames');
            Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.we1_frames');
            Level.AddPrecacheMaterial(Material'AW-2004Particles.Fire.MuchSmoke1');
            Level.AddPrecacheMaterial(Material'AW-2004Particles.Fire.NapalmSpot');
            Level.AddPrecacheMaterial(Material'EpicParticles.Fire.SprayFire1');
            Level.AddPrecacheMaterial(Material'WeaponSkins.Skins.RocketTex0');
            Level.AddPrecacheMaterial(Material'AW-2004Particles.Energy.JumpDuck');
            Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftRED');
            Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftBLUE');
            Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.NewHoverCraftNOcolor');
            Level.AddPrecacheMaterial(Material'AW-2004Particles.Energy.AirBlast');
            Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
            Level.AddPrecacheMaterial(Material'Engine.GRADIENT_Fade');
        
            Super.UpdatePrecacheMaterials();
        }
        
        defaultproperties
        { // the new default properties need to be enclosed inside the opening brace, {, to actually be part of the default properties
        ////Anim test part 1
            // change the RunF/RunB/RunL/RunR/TurnR/TurnL/Idle_Rest to the names of the BF2142 mech animation would look best
            MovementAnims(0)=Walk
            MovementAnims(1)=WalkBack
            MovementAnims(2)=StepLeft
            MovementAnims(3)=StepRight
            TurnRightAnim=Turn
            TurnLeftAnim=Turn
            IdleRestAnim=Idle
        ////
        //{
             MaxPitchSpeed=1000.000000
             JumpDuration=0.220000
             JumpForceMag=100.000000
             JumpDelay=3.000000
             DuckForceMag=150.000000
             JumpSound=ONSVehicleSounds-S.HoverBike.HoverBikeJump05
             DuckSound=ONSVehicleSounds-S.HoverBike.HoverBikeTurbo01
             JumpForce="HoverBikeJump"
             ThrusterOffsets(0)=(X=95.000000,Z=200.000000)
             HoverSoftness=0.220000
             HoverPenScale=1.000000
             HoverCheckDist=600.000000
             UprightStiffness=500.000000
             UprightDamping=500.000000
             MaxThrustForce=2.000000
             LongDamping=0.020000
             MaxStrafeForce=1.000000
             LatDamping=0.100000
             TurnTorqueFactor=1000.000000
             TurnTorqueMax=125.000000
             TurnDamping=40.000000
             MaxYawRate=1.500000
             PitchTorqueFactor=200.000000
             PitchTorqueMax=9.000000
             PitchDamping=20.000000
             RollTorqueTurnFactor=450.000000
             RollTorqueStrafeFactor=200.000000
             RollTorqueMax=1.500000
             RollDamping=3.000000
             StopThreshold=50.000000
        
             DriverWeapons(0)=(None)
             PassengerWeapons(0)=(None)
        
             bHasAltFire=False
             IdleSound=ONSVehicleSounds-S.HoverBike.HoverBikeEng02
             StartUpSound=ONSVehicleSounds-S.HoverBike.HoverBikeStart01
             ShutDownSound=ONSVehicleSounds-S.HoverBike.HoverBikeStop01
             StartUpForce="HoverBikeStartUp"
             ShutDownForce="HoverBikeShutDown""
             DestroyedVehicleMesh=ONSDeadVehicles-SM.HoverBikeDead
             DestructionEffectClass=Onslaught.ONSSmallVehicleExplosionEffect
             DisintegrationEffectClass=Onslaught.ONSVehDeathHoverBike
             DestructionLinearMomentum=(Min=62000.000000,Max=100000.000000)
             DestructionAngularMomentum=(Min=25.000000,Max=75.000000)
             DamagedEffectScale=0.600000
             DamagedEffectOffset=(X=50.000000,Y=-25.000000,Z=10.000000)
             ImpactDamageMult=0.000100
             HeadlightCoronaOffset(0)=(X=73.000000,Y=10.000000,Z=14.000000)
             HeadlightCoronaOffset(1)=(X=73.000000,Y=-10.000000,Z=14.000000)
             HeadlightCoronaMaterial=Texture'EpicParticles.Flares.FlashFlare1'
             HeadlightCoronaMaxSize=60.000000
             bDrawDriverInTP=False
             bTurnInPlace=True
             bShowDamageOverlay=True
             bScriptedRise=True
             bShowChargingBar=True
             bDriverHoldsFlag=True
             bCanCarryFlag=True
             DrivePos=(X=-50.000000,Z=75.000000)
             ExitPositions(0)=(Y=300.000000,Z=100.000000)
             ExitPositions(1)=(Y=-300.000000,Z=100.000000)
             ExitPositions(2)=(X=350.000000,Z=100.000000)
             ExitPositions(3)=(X=-350.000000,Z=100.000000)
             ExitPositions(4)=(X=-350.000000,Z=-100.000000)
             ExitPositions(5)=(X=350.000000,Z=-100.000000)
             ExitPositions(6)=(Y=300.000000,Z=-100.000000)
             ExitPositions(7)=(Y=-300.000000,Z=-100.000000)
             EntryRadius=350.000000
             FPCamPos=(X=100.000000,Z=500.000000)
             TPCamDistance=500.000000
             TPCamLookat=(X=100.000000,Z=50.000000)
             TPCamWorldOffset=(Z=100.000000)
             VehiclePositionString="in an BF2142 Mech"
             VehicleNameString="BF2142 Mech"
             RanOverDamageType=Onslaught.DamTypeHoverBikeHeadshot
             CrushedDamageType=Onslaught.DamTypeHoverBikePancake
             ObjectiveGetOutDist=750.000000
             FlagBone="HoverCraft"
             FlagOffset=(Z=45.000000)
             FlagRotation=(Yaw=32768)
             HornSounds(0)=ONSVehicleSounds-S.Horns.Horn02
             HornSounds(1)=ONSVehicleSounds-S.Horns.La_Cucharacha_Horn
             bCanStrafe=True
             MeleeRange=-100.000000
             GroundSpeed=700.000000
             HealthMax=400.000000
             Health=400
             Mesh=SkeletalMesh'MegaForce_A.BF2142_Mech'
             SoundRadius=900.000000
             Begin Object Class=KarmaParamsRBFull Name=KParams0
                 KInertiaTensor(0)=1.300000
                 KLinearDamping=0.150000
                 KAngularDamping=200.000000
                 KStartEnabled=True
                 bHighDetailOnly=False
                 bClientOnly=False
                 bKDoubleTickRate=True
                 bKStayUpright=True
                 bKAllowRotate=True
                 bDestroyOnWorldPenetrate=True
                 bDoSafetime=True
                 KFriction=0.500000
                 KImpactThreshold=700.000000
             End Object
             KParams=KarmaParamsRBFull'MegaForce.BF2142_Chassis.KParams0'
        
        }
        Last edited by meowcatbuf; 03-27-2017, 09:16 PM.

        Comment


          Hi Maxx,
          For the animation speed you have two options (pr possibly a combination of the two):
          1. Change each animation sequence's play speed (rate) in the UnrealEd via the rate property (the tabs in the animation browser allow you to click on each animation sequence on the left hand window, and then edit the rate property AND things like translation and rotation). If the speed is 2x too fast, just divide the play rate by 2. Make sure to save the file once you are done modifying it.

          2. Change the play rate in the 'LoopAnim' function calls in the code. Per the 'LoopAnim' function call explanation, the play rate is the second parameter in the function. So in the code I posted above just change the "1.0" that I listed in the four different calls to LoopAnim, to 0.5 instead.

          I'm not entirely sure why the animations would not kick in immediately... hmmm. Is it only the first three seconds of the very first time that you begin driving the mech, or is it every time you change movement directions?

          As for fixing the animation sequences: When ever I re-import a .psa file, I always choose to overwrite the animation sequences (I think I use the "File->Animation Append" option from the menu and then click the 'Overwrite Existing Sequences' radio button in addition to the 'Merge Sequences into Existing' radio button). Whenever you have two animation sequences (or really two of ANYTHING) in the same package (.ukx, .usx, .utx etc.) with exactly the same name, the engine gets "confused", and you can actually break an entire file. If you do want to import the .psa file again, but not overwrite the other sequences, you can import it again but change its name when you import it so that it becomes a separate animation set (however, you then have to link it to the mesh in code if you want to use sequences from both .psa animation sets since you can only have 1 default animation set).
          Last edited by meowcatbuf; 03-28-2017, 08:37 PM.

          Comment


            Maxx,
            Here is an updated version of the Mech code, my changes highlighted in blue. This should be a bit more responsive. Also, I recommend you update the collision boxes on the mech main turret model (or chassis), so that it will collide with stuff.

            Code:
            //-----------------------------------------------------------
            //
            //-----------------------------------------------------------
            class BF2142_Chassis extends ONSHoverCraft;
            
            #exec OBJ LOAD FILE=MegaForce_A.ukx
            #exec OBJ LOAD FILE=MegaForceTX.utx
            
            var()   float   MaxPitchSpeed;
            
            var()   float   JumpDuration;
            var()    float    JumpForceMag;
            var     float   JumpCountdown;
            var     float    JumpDelay, LastJumpTime;
            
            var()   float   DuckDuration;
            var()   float   DuckForceMag;
            var     float   DuckCountdown;
            
            var()    array<vector>                    BikeDustOffset;
            var()    float                            BikeDustTraceDistance;
            
            var()   sound                           JumpSound;
            var()   sound                           DuckSound;
            
            // Force Feedback
            var()    string                            JumpForce;
            
            var        array<ONSHoverBikeHoverDust>    BikeDust;
            var        array<vector>                    BikeDustLastNormal;
            
            var        bool                            DoBikeJump;
            var        bool                            OldDoBikeJump;
            
            var        bool                            DoBikeDuck;
            var        bool                            OldDoBikeDuck;
            var     bool                            bHoldingDuck;
            
            //edited meowcat - vars below used to limit how much the mech is jerked around when taking damage
            var() config float MomentumDamageThreshold; // if damage is less than this, multiply momentum by the scaler
            var() config float MomentumScaler;
            
            replication
            {
                reliable if (bNetDirty && Role == ROLE_Authority)
                    DoBikeJump;
            }
            
            function Pawn CheckForHeadShot(Vector loc, Vector ray, float AdditionalScale)
            {
                local vector X, Y, Z, newray;
            
                GetAxes(Rotation,X,Y,Z);
            
                if (Driver != None)
                {
                    // Remove the Z component of the ray
                    newray = ray;
                    newray.Z = 0;
                    if (abs(newray dot X) < 0.7 && Driver.IsHeadShot(loc, ray, AdditionalScale))
                        return Driver;
                }
            
                return None;
            }
            
            simulated function Destroyed()
            {
                local int i;
            
                if (Level.NetMode != NM_DedicatedServer)
                {
                    for (i = 0; i < BikeDust.Length; i++)
                        BikeDust[i].Destroy();
            
                    BikeDust.Length = 0;
                }
            
                Super.Destroyed();
            }
            
            simulated function DestroyAppearance()
            {
                local int i;
            
                if (Level.NetMode != NM_DedicatedServer)
                {
                    for (i = 0; i < BikeDust.Length; i++)
                        BikeDust[i].Destroy();
            
                    BikeDust.Length = 0;
                }
            
                Super.DestroyAppearance();
            }
            
            // edited Meowcat - added this function extension to turn off water collision so that the mech can walk into, rather than on, water
            simulated function PostNetBeginPlay()
            {
                local KarmaParams kp;
                local int i;
            
                Super.PostNetBeginPlay();
                // Turn off water repulsion
                kp = KarmaParams(KParams);
            
                for(i=0;i<kp.Repulsors.Length;i++){
                    kp.Repulsors[i].bRepulseWater = false;
                }
            }
            
            function bool Dodge(eDoubleClickDir DoubleClickMove)
            {
                Rise = 1;
                return true;
            }
            
            function ChooseFireAt(Actor A)
            {
                if (Pawn(A) != None && Vehicle(A) == None && VSize(A.Location - Location) < 1500 && Controller.LineOfSightTo(A))
                {
                    if (!bWeaponIsAltFiring)
                        AltFire(0);
                }
                else if (bWeaponIsAltFiring)
                    VehicleCeaseFire(true);
            
                Fire(0);
            }
            
            simulated event DrivingStatusChanged()
            {
                local int i;
            
                Super.DrivingStatusChanged();
            
                if (bDriving && Level.NetMode != NM_DedicatedServer && BikeDust.Length == 0 && !bDropDetail)
                {
                    BikeDust.Length = BikeDustOffset.Length;
                    BikeDustLastNormal.Length = BikeDustOffset.Length;
            
                    for(i=0; i<BikeDustOffset.Length; i++)
                        if (BikeDust[i] == None)
                        {
                            BikeDust[i] = spawn( class'ONSHoverBikeHoverDust', self,, Location + (BikeDustOffset[i] >> Rotation) );
                            BikeDust[i].SetDustColor( Level.DustColor );
                            BikeDustLastNormal[i] = vect(0,0,1);
                        }
                }
                else
                {
                    if (Level.NetMode != NM_DedicatedServer)
                    {
                        for(i=0; i<BikeDust.Length; i++)
                            BikeDust[i].Destroy();
            
                        BikeDust.Length = 0;
                    }
                    JumpCountDown = 0.0;
                   
                }
                if(!bDriving) LoopAnim(IdleRestAnim, 1.0, 0.1f, 0);
            }
            
            simulated function Tick(float DeltaTime)
            {
                local float EnginePitch, HitDist;
                local int i;
                local vector TraceStart, TraceEnd, HitLocation, HitNormal;
                local actor HitActor;
                local Emitter JumpEffect;
            
                Super.Tick(DeltaTime);
            
                EnginePitch = 64.0 + VSize(Velocity)/MaxPitchSpeed * 64.0;
                SoundPitch = FClamp(EnginePitch, 64, 128);
            
                JumpCountdown -= DeltaTime;
            
                CheckJumpDuck();
            
                UpdateMechAnim(DeltaTime);
            
                if(DoBikeJump != OldDoBikeJump)
                {
                    JumpCountdown = JumpDuration;
                    OldDoBikeJump = DoBikeJump;
                    if (Controller != Level.GetLocalPlayerController())
                    {
                        JumpEffect = Spawn(class'ONSHoverBikeJumpEffect');
                        JumpEffect.SetBase(Self);
                        ClientPlayForceFeedback(JumpForce);
                    }
                }
            
                if(Level.NetMode != NM_DedicatedServer && !bDropDetail)
                {
                    for(i=0; i<BikeDust.Length; i++)
                    {
                        BikeDust[i].bDustActive = false;
            
                        TraceStart = Location + (BikeDustOffset[i] >> Rotation);
                        TraceEnd = TraceStart - ( BikeDustTraceDistance * vect(0,0,1) );
            
                        HitActor = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, True);
            
                        if(HitActor == None)
                        {
                            BikeDust[i].UpdateHoverDust(false, 0);
                        }
                        else
                        {
                            HitDist = VSize(HitLocation - TraceStart);
            
                            BikeDust[i].SetLocation( HitLocation + 10*HitNormal);
            
                            BikeDustLastNormal[i] = Normal( 3*BikeDustLastNormal[i] + HitNormal );
                            BikeDust[i].SetRotation( Rotator(BikeDustLastNormal[i]) );
            
                            BikeDust[i].UpdateHoverDust(true, HitDist/BikeDustTraceDistance);
            
                            // If dust is just turning on, set OldLocation to current Location to avoid spawn interpolation.
                            if(!BikeDust[i].bDustActive)
                                BikeDust[i].OldLocation = BikeDust[i].Location;
            
                            BikeDust[i].bDustActive = true;
                        }
                    }
                }
            }
            
            ////Anim test part 2 // this call to the function is not inside the 'Tick' function code block,
            // see edit above ;-) ^^^
            /* simply add this function call to your 'Tick' function right after CheckJumpDuck(); by adding this line
            
            UpdateMechAnim(DeltaTime); // this is actually inside a comment block because of the / and * and then * and / closing the comment block
            
            */
            ////
            
            function VehicleCeaseFire(bool bWasAltFire)
            {
                Super.VehicleCeaseFire(bWasAltFire);
            
                if (bWasAltFire)
                    bHoldingDuck = False;
            }
            
            simulated function float ChargeBar()
            {
                // Clamp to 0.999 so charge bar doesn't blink when maxed
                if (Level.TimeSeconds - JumpDelay < LastJumpTime)
                    return (FMin((Level.TimeSeconds - LastJumpTime) / JumpDelay, 0.999));
                else
                    return 0.999;
            }
            
            simulated function CheckJumpDuck()
            {
                local KarmaParams KP;
                local Emitter JumpEffect, DuckEffect;
                local bool bOnGround;
                local int i;
            
                KP = KarmaParams(KParams);
            
                // Can only start a jump when in contact with the ground.
                bOnGround = false;
                for(i=0; i<KP.Repulsors.Length; i++)
                {
                    if( KP.Repulsors[i] != None && KP.Repulsors[i].bRepulsorInContact )
                        bOnGround = true;
                }
            
                // If we are on the ground, and press Rise, and we not currently in the middle of a jump, start a new one.
                if (JumpCountdown <= 0.0 && Rise > 0 && bOnGround && !bHoldingDuck && Level.TimeSeconds - JumpDelay >= LastJumpTime)
                {
                    PlaySound(JumpSound,,1.0);
            
                    if (Role == ROLE_Authority)
                       DoBikeJump = !DoBikeJump;
            
                    if(Level.NetMode != NM_DedicatedServer)
                    {
                        JumpEffect = Spawn(class'ONSHoverBikeJumpEffect');
                        JumpEffect.SetBase(Self);
                        ClientPlayForceFeedback(JumpForce);
                    }
            
                    if ( AIController(Controller) != None )
                        Rise = 0;
            
                    LastJumpTime = Level.TimeSeconds;
                }
                else if (DuckCountdown <= 0.0 && (Rise < 0 || bWeaponIsAltFiring))
                {
                    if (!bHoldingDuck)
                    {
                        bHoldingDuck = True;
            
                        PlaySound(DuckSound,,1.0);
            
                        DuckEffect = Spawn(class'ONSHoverBikeDuckEffect');
                        DuckEffect.SetBase(Self);
            
                        if ( AIController(Controller) != None )
                            Rise = 0;
            
                        JumpCountdown = 0.0; // Stops any jumping that was going on.
                    }
                }
                else
                   bHoldingDuck = False;
            }
            
            simulated function KApplyForce(out vector Force, out vector Torque)
            {
                Super.KApplyForce(Force, Torque);
            
                if (bDriving && JumpCountdown > 0.0)
                {
                    Force += vect(0,0,1) * JumpForceMag;
                }
            
                if (bDriving && bHoldingDuck)
                {
                    Force += vect(0,0,-1) * DuckForceMag;
                }
            }
            
            ////Anim test part 3
            // Then paste this function code block in your code after the 'KApplyForce'
            // function code block and before the 'StaticPrecache' function code block
            // (you can actually paste the new function after any of the function code
            // blocks as long as it is after all of the class variables have been declared
            // at the top, and before you begin listing the default properties.
            
            simulated function UpdateMechAnim(float DeltaTime)
            {
                local int NewAnimDirection;
                local KRigidBodyState BodyState;
                local float  TurnZAmount, Speed2D;  //edited meowcat
                local vector VDirectionNormal;
            
                 // if we are on a server, don't bother playing the animations....
                 // though you might want to for collision purposes even if they don't completely sync up on the clients and server...
                if ( Level.NetMode == NM_DedicatedServer )
                    return;
                // Don't bother running the animations if this particular mech has
                // not been rendered for over a second on this computer
                if (Level.TimeSeconds - LastRenderTime > 1.0){
                    return;
                }
                // Now start checking for whether the player is moving, standing still, or turning.
                //  The check for 80 may sound like a lot, but for a vehicle, 80 UU/seconds is not very fast at all
                // so we are basically standing still, or only moving very very slowly, so don't animate the legs
                // as walking
            
                if(VSize(Velocity) < 80)
                {
                      KGetRigidBodyState(BodyState);
                       TurnZAmount = BodyState.AngVel.Z; // how much we are turning around the  Z-Axis,
                 // I do not know what unit this is in: radians-per-second,  degrees-per-second, rotations-per-second,
                 // URots-per-second it could eb  any of these.
                      if(Abs(TurnZAmount) > 0.5)
                 // since I don't  know what the typical magnitude of the AngularVelocity (AngVel) would  be expected to see...
                      {
                          if(TurnZAmount  > 0) LoopAnim(TurnRightAnim, 1.0, 0.1f, 0); // you might need to swap  the '>' operator for '<' if the animations are turning the wrong  direction.
                          else LoopAnim(TurnLeftAnim, 1.0, 0.1f, 0);
                      }
                      else // we're not turning, so we must just be standing in place...
                          LoopAnim(IdleRestAnim, 1.0, 0.1f, 0);
                }
                // we must be moving then, so first lets check to see if we are falling
                // and if we are not falling then, we're probably running around
                else
                {
                    VDirectionNormal = Normal(Velocity); // turn the velocity vector into a   'Unit Vector' (length == 1.0)
                                // and see if it mostly points down
            
                    if(VDirectionNormal.Z < -0.8) // we are mostly falling!
                    {
                          LoopAnim(IdleRestAnim, 1.0, 0.1f, 0); // go ahead and play the IdleRestAnim while falling
                    }
                    else
                    {
                           Speed2D = VSize(Velocity);
                           Speed2D /= 1000; // 1000 was about the velocity that the animation looked OK at
                           NewAnimDirection = Get4WayDirection(); // this native C++ function returns 0,1,2,
                 // or 3 based on which direction the pawn is moving compared to their  facing direction
                          LoopAnim(MovementAnims[NewAnimDirection], Speed2D , 0.1f, 0); //edited meowcat
                    }
                }
            }
            ////
            
            // make sure we don't screw up getting knocked around too badly!!
            function TakeDamage(int Damage, Pawn instigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> DamageType){
                if(damage < MomentumDamageThreshold && MomentumScaler !=1.0) Momentum *= MomentumScaler;// no momentum to spin the vehicle around
                Super.TakeDamage(Damage, instigatedBy, Hitlocation, Momentum, damageType);
            }
            
            static function StaticPrecache(LevelInfo L)
            {
                Super.StaticPrecache(L);
            
                L.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverWing');
                L.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverChair');
                L.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris2');
                L.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris1');
                L.AddPrecacheStaticMesh(StaticMesh'ONSWeapons-SM.PC_MantaJumpBlast');
            
                L.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp2_frames');
                L.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp1_frames');
                L.AddPrecacheMaterial(Material'ExplosionTex.Framed.we1_frames');
                L.AddPrecacheMaterial(Material'AW-2004Particles.Fire.MuchSmoke1');
                L.AddPrecacheMaterial(Material'AW-2004Particles.Fire.NapalmSpot');
                L.AddPrecacheMaterial(Material'EpicParticles.Fire.SprayFire1');
                L.AddPrecacheMaterial(Material'WeaponSkins.Skins.RocketTex0');
                L.AddPrecacheMaterial(Material'AW-2004Particles.Energy.JumpDuck');
                L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hovercraftFANSblurTEX');
                L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftRED');
                L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftBLUE');
                L.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.NewHoverCraftNOcolor');
                L.AddPrecacheMaterial(Material'AW-2004Particles.Energy.AirBlast');
                L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
                L.AddPrecacheMaterial(Material'Engine.GRADIENT_Fade');
            
            }
            
            simulated function UpdatePrecacheStaticMeshes()
            {
                Level.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverWing');
                Level.AddPrecacheStaticMesh(StaticMesh'ONSDeadVehicles-SM.HoverExploded.HoverChair');
                Level.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris2');
                Level.AddPrecacheStaticMesh(StaticMesh'AW-2004Particles.Debris.Veh_Debris1');
                Level.AddPrecacheStaticMesh(StaticMesh'ONSWeapons-SM.PC_MantaJumpBlast');
                Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hovercraftFANSblurTEX');
            
                Super.UpdatePrecacheStaticMeshes();
            }
            
            simulated function UpdatePrecacheMaterials()
            {
                Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp2_frames');
                Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.exp1_frames');
                Level.AddPrecacheMaterial(Material'ExplosionTex.Framed.we1_frames');
                Level.AddPrecacheMaterial(Material'AW-2004Particles.Fire.MuchSmoke1');
                Level.AddPrecacheMaterial(Material'AW-2004Particles.Fire.NapalmSpot');
                Level.AddPrecacheMaterial(Material'EpicParticles.Fire.SprayFire1');
                Level.AddPrecacheMaterial(Material'WeaponSkins.Skins.RocketTex0');
                Level.AddPrecacheMaterial(Material'AW-2004Particles.Energy.JumpDuck');
                Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftRED');
                Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.hoverCraftBLUE');
                Level.AddPrecacheMaterial(Material'VMVehicles-TX.HoverBikeGroup.NewHoverCraftNOcolor');
                Level.AddPrecacheMaterial(Material'AW-2004Particles.Energy.AirBlast');
                Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
                Level.AddPrecacheMaterial(Material'Engine.GRADIENT_Fade');
            
                Super.UpdatePrecacheMaterials();
            }
            
            defaultproperties
            { // the new default properties need to be enclosed inside the opening brace, {, to actually be part of the default properties
            ////Anim test part 1
                // change the RunF/RunB/RunL/RunR/TurnR/TurnL/Idle_Rest to the names of the BF2142 mech animation would look best
                MovementAnims(0)=WalkForward
                MovementAnims(1)=WalkBackward
                MovementAnims(2)=StepLeft
                MovementAnims(3)=StepRight
                TurnRightAnim=Turn
                TurnLeftAnim=Turn
                IdleRestAnim=Idle
            ////
            //{
                 MaxPitchSpeed=1000.000000
                 JumpDuration=0.220000
                 JumpForceMag=100.000000
                 JumpDelay=3.000000
                 DuckForceMag=150.000000
                 JumpSound=ONSVehicleSounds-S.HoverBike.HoverBikeJump05
                 DuckSound=ONSVehicleSounds-S.HoverBike.HoverBikeTurbo01
                 JumpForce="HoverBikeJump"
                 ThrusterOffsets(0)=(X=0.0,Z=200.0) //edited meowcat
                 HoverSoftness=0.220000
                 HoverPenScale=1.000000
                 HoverCheckDist=600.0
                 UprightStiffness=500.000000
                 UprightDamping=500.000000
                 MaxThrustForce=16.000000 //edited meowcat
                 LongDamping=0.020000
                 MaxStrafeForce=10.000000 //edited meowcat
                 LatDamping=0.100000
                 TurnTorqueFactor=1000.000000
                 TurnTorqueMax=125.000000
                 TurnDamping=40.000000
                 MaxYawRate=1.500000
                 PitchTorqueFactor=200.000000
                 PitchTorqueMax=9.000000
                 PitchDamping=20.000000
                 RollTorqueTurnFactor=450.000000
                 RollTorqueStrafeFactor=200.000000
                 RollTorqueMax=1.500000
                 RollDamping=3.000000
                 StopThreshold=50.000000
            
                 VehicleMass=1.1 // edited meowcat
                 bTraceWater=false // edited meowcat
                 MomentumDamageThreshold=200 // edited meowcat
                 MomentumScaler=0.05 // edited meowcat
                 CollisionRadius=+360.0 // edited meowcat
                 CollisionHeight=+400.0 // edited meowcat
            
                 DriverWeapons(0)=(WeaponClass=Class'MegaForce.BF2142_Main_Turret',WeaponBone="Main_Turret_Base")
                 PassengerWeapons(0)=(WeaponPawnClass=Class'MegaForce.BF2142_Gun_TurretPawn',WeaponBone="Gun_Turret_Base")
            
                 bHasAltFire=False
                 IdleSound=ONSVehicleSounds-S.HoverBike.HoverBikeEng02
                 StartUpSound=ONSVehicleSounds-S.HoverBike.HoverBikeStart01
                 ShutDownSound=ONSVehicleSounds-S.HoverBike.HoverBikeStop01
                 StartUpForce="HoverBikeStartUp"
                 ShutDownForce="HoverBikeShutDown""
                 DestroyedVehicleMesh=ONSDeadVehicles-SM.HoverBikeDead
                 DestructionEffectClass=Onslaught.ONSSmallVehicleExplosionEffect
                 DisintegrationEffectClass=Onslaught.ONSVehDeathHoverBike
                 DestructionLinearMomentum=(Min=62000.000000,Max=100000.000000)
                 DestructionAngularMomentum=(Min=25.000000,Max=75.000000)
                 DamagedEffectScale=0.600000
                 DamagedEffectOffset=(X=50.000000,Y=-25.000000,Z=10.000000)
                 ImpactDamageMult=0.000100
                 HeadlightCoronaOffset(0)=(X=73.000000,Y=10.000000,Z=14.000000)
                 HeadlightCoronaOffset(1)=(X=73.000000,Y=-10.000000,Z=14.000000)
                 HeadlightCoronaMaterial=Texture'EpicParticles.Flares.FlashFlare1'
                 HeadlightCoronaMaxSize=60.000000
                 bDrawDriverInTP=False
                 bTurnInPlace=True
                 bShowDamageOverlay=True
                 bScriptedRise=True
                 bShowChargingBar=True
                 bDriverHoldsFlag=True
                 bCanCarryFlag=True
                 DrivePos=(X=-50.000000,Z=75.000000)
                 ExitPositions(0)=(Y=300.000000,Z=100.000000)
                 ExitPositions(1)=(Y=-300.000000,Z=100.000000)
                 ExitPositions(2)=(X=350.000000,Z=100.000000)
                 ExitPositions(3)=(X=-350.000000,Z=100.000000)
                 ExitPositions(4)=(X=-350.000000,Z=-100.000000)
                 ExitPositions(5)=(X=350.000000,Z=-100.000000)
                 ExitPositions(6)=(Y=300.000000,Z=-100.000000)
                 ExitPositions(7)=(Y=-300.000000,Z=-100.000000)
                 EntryRadius=350.000000
                 FPCamPos=(X=100.000000,Z=500.000000)
                 TPCamDistance=500.000000
                 TPCamLookat=(X=100.000000,Z=50.000000)
                 TPCamWorldOffset=(Z=100.000000)
                 VehiclePositionString="in an BF2142 Mech"
                 VehicleNameString="BF2142 Mech"
                 RanOverDamageType=Onslaught.DamTypeHoverBikeHeadshot
                 CrushedDamageType=Onslaught.DamTypeHoverBikePancake
                 ObjectiveGetOutDist=750.000000
                 FlagBone="HoverCraft"
                 FlagOffset=(Z=45.00)
                 FlagRotation=(Yaw=32768)
                 HornSounds(0)=ONSVehicleSounds-S.Horns.Horn02
                 HornSounds(1)=ONSVehicleSounds-S.Horns.La_Cucharacha_Horn
                 bCanStrafe=True
                 MeleeRange=-100.00
                 GroundSpeed=700.00
                 HealthMax=400.000000
                 Health=400
                 Mesh=SkeletalMesh'MegaForce_A.BF2142_Mech'
                 SoundRadius=900.0
                 Begin Object Class=KarmaParamsRBFull Name=KParams0
                     KInertiaTensor(0)=1.300000
                     KLinearDamping=0.150000
                     KAngularDamping=200.000000
                     KStartEnabled=True
                     bHighDetailOnly=False
                     bClientOnly=False
                     bKDoubleTickRate=True
                     bKStayUpright=True
                     bKAllowRotate=True
                     bDestroyOnWorldPenetrate=True
                     bDoSafetime=True
                     KFriction=0.500000
                     KImpactThreshold=700.0
                     KMaxSpeed=800.0 // meowcat edited
                 End Object
                 KParams=KarmaParamsRBFull'MegaForce.BF2142_Chassis.KParams0'
            
            }
            And on a side note, here is the link to the default native pawn animation code converted to UScript (I did the conversion about 9'ish years ago to support adding some parkour/Splinter Cell style aniamtions and capabilities to the pawn code).
            Last edited by meowcatbuf; 04-01-2017, 05:55 PM.

            Comment


              Hey Mad Maxx, what you been up to lately?

              I've been able to drum up a little motivation to try and make my own "Mammoth" vehicle for UT2k4 from scratch (screenshot below). I've got the basic test vehicle in game now, its only weapon is the cannon from the Leviathan (with my own mesh). I've used about 20 skeletal collision boxes so far to allow players to wander around on and in the vehicle, but will probably be around 40'ish collision boxes when complete (not counting the collision boxes on the cannon). Obviously with a vehicle this large it is really, really finicky with level collision. The map that I'm testing it in is a VCTF version of ONS-Minus, but with all of the karma collision of the light poles turned off (much less to snag on).

              [EDIT] I did a bit more work on it today. I have most of the collision boxes in place (a couple more to go for the doors and safety railings)., they've taken quite a bit of tweaking in order to actually be able to drive around Torlan. I've also got the tires skinned, and have a test front windshield glass texture made.

              Click image for larger version  Name:	MammothTestMesh_shot.jpg Views:	1 Size:	213.9 KB ID:	395714 Click image for larger version

Name:	MammothTestMesh_CollisionShot.jpg
Views:	1
Size:	115.3 KB
ID:	395732Click image for larger version

Name:	MammothTestMesh_SkinProgressShot.jpg
Views:	1
Size:	127.3 KB
ID:	395733
              Last edited by meowcatbuf; 12-21-2017, 07:27 PM.

              Comment


                Got some more skin work done on the model. I've also tweaked the collision a little bit and the torque curves so it can get going pretty good on flat surfaces. I still need to add the ramps on the forward and aft ends, and then skin the interior and add decorations.
                [EDIT] got the forward and aft doors meshed and skinned, as well as the basic aft end geometry (now I just have to animate the doors). Still lots left to do.
                Click image for larger version  Name:	MammothTestMesh_SkinProgressShot02.jpg Views:	1 Size:	134.4 KB ID:	395756 Click image for larger version

Name:	MammothTestMesh_SkinProgressShot03.jpg
Views:	1
Size:	247.9 KB
ID:	395757
                Last edited by meowcatbuf; 12-23-2017, 03:54 AM.

                Comment


                  Hi Maxx, those look like they are coming along nicely! (warthogs always seem fun to drive, no matter which game they are in) Did you base the Elephant on a hover tank?

                  The four texture thing for the elephant and H3 tanks just means that you will need to create a few more "runtime" TexPanners for the tank treads (rather than just the 2 that the hover tank already spawns).

                  I've been working on some code to try and get the bots to move around on-top-of/inside the vehicle. While they can walk around (the collision boxes area all walkable etc.), the native (C++) navigation code does not really support "dynamic" navigation path building. I tried spawning and attaching a subclass of "Pickup" (since pickups can be added to the navigation network in real-time) but they do not connect to each other, and only the ones closest to the ground and in line-of-sight (LOS) to other map-placed navigation points actually connect to anything, the points on the upper decks typically don't connect to anything. I already have some basic navigation data-node-mesh data setup for the vehicle (just a basic array of vector points where the navigation nodes would be if it were a static map placed object), but you can't spawn and move NavigationPoints or ReachSpecs at runtime (I tried this a while back) so the bots can use them.

                  If I rewrote the Bot code I could probably add in a really "kludgy" navigation/path-finding system that parallels the native navigation and movement code (just got to implement the A* pathfinding algorithm in UScript... ugh), but then it could easily break compatibility with other mods so I'm, reluctant to spend a lot of time doing that.

                  I've got Weapon lockers on it at the moment along with four rotating barrel Halo-style cannons for passengers. Still a lot of work to do.

                  Comment


                    The Phantom looks like it should be build-able. I'd love to make a "UT-ish" version of the Scarab complete with legs, but the whole inverse-kinematic foot placement code is kind of daunting (just looking at the source script from the Black Strider vehicle is challenging though Matariel did a nice job documenting his stuff... wish he was still around to help out with that part). I may try it sometime, but it looks like it will take more time than I am interested in putting into it.

                    Thank you for posting that video, that was really good for actually seeing what the interior of the Mammoth looks like. My mammoth will not have anywhere near as much detail.

                    Comment



                      Sorry about the late reply, I've been really busy with work stuff and was finally able to get around to putting all of the files in UT2k4 to test code fixes.

                      Here is the fixed Halo 3 Scorpion Tank code for the treads. It looks like it was just the skin array indices that needed to be updated to match the skin index values on the skeletal model in the Animation Browser:
                      Code:
                      //=============================================================================
                      //
                      //=============================================================================
                      
                      class H3_Scorpion_Tank_Chassis extends ONSHoverTank;
                      
                      #exec OBJ LOAD FILE=..\Animations\H3_Vehicles_A.ukx
                      
                      var()    float            WheelSuspensionTravel;           //added for treadpod control
                      var()    float            WheelSuspensionOffset;           //added for treadpod control
                      var()    float            WheelSuspensionMaxRenderTravel;  //added for treadpod control
                      var()    float            WheelSoftness;                   //added for treadpod control
                      var()    float            WheelPenScale;                   //added for treadpod control
                      
                      
                      simulated event bool KUpdateState(out KRigidBodyState newState)
                      {
                          // This should never get called on the server - but just in case!
                          if(Role == ROLE_Authority || !bNewTreadState)
                              return false;
                      
                      
                          newState = ChassisState;
                          bNewTreadState = false;
                      
                      
                          return true;
                      }
                      
                      
                      //==================================================================
                      simulated event SVehicleUpdateParams()  //added for treadpod control
                      {
                              local KarmaParams kp; //======from ONSTreadCraft========
                          local int i;
                      
                      
                          Super.SVehicleUpdateParams();
                      
                          kp = KarmaParams(KParams);     //===========================
                      
                      
                          for(i=0;i<kp.Repulsors.Length;i++)
                          {
                                  kp.Repulsors[i].Softness = HoverSoftness;                //ONSTreadCraft stuff
                                  kp.Repulsors[i].PenScale = HoverPenScale;
                                  kp.Repulsors[i].CheckDist = HoverCheckDist;
                          }
                      
                      
                          KSetStayUprightParams( UprightStiffness, UprightDamping );   //==================
                      
                      
                          for(i=0; i<Wheels.Length; i++)                      //********ONSWheeledCraft******************
                          {
                              Wheels[i].Softness = WheelSoftness;
                              Wheels[i].PenScale = WheelPenScale;
                              //Wheels[i].PenOffset = WheelPenOffset;  //I only called what I needed here for the effect to work
                              //Wheels[i].LongSlip = WheelLongSlip;
                              //Wheels[i].LatSlipFunc = WheelLatSlipFunc;
                              //Wheels[i].Restitution = WheelRestitution;
                              //Wheels[i].Adhesion = WheelAdhesion;
                              //Wheels[i].WheelInertia = WheelInertia;
                              //Wheels[i].LongFrictionFunc = WheelLongFrictionFunc;
                              //Wheels[i].HandbrakeFrictionFactor = WheelHandbrakeFriction;
                              //Wheels[i].HandbrakeSlipFactor = WheelHandbrakeSlip;
                              Wheels[i].SuspensionTravel = WheelSuspensionTravel;
                              Wheels[i].SuspensionOffset = WheelSuspensionOffset;
                              Wheels[i].SuspensionMaxRenderTravel = WheelSuspensionMaxRenderTravel;
                          }                                                                   //******************************
                      }
                      
                      function AltFire(optional float F)
                      {
                          super(ONSVehicle).AltFire( F );
                      }
                      
                      function ClientVehicleCeaseFire(bool bWasAltFire)
                      {
                          super(ONSVehicle).ClientVehicleCeaseFire( bWasAltFire );
                      }
                      
                      simulated function SetupTreads()
                      {
                          LeftTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                          RightTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                      LeftTreadPanner.Material = Skins[4];
                           RightTreadPanner.Material = Skins[3];
                           LeftTreadPanner.PanRate = 0;
                           RightTreadPanner.PanRate = 0;
                           //LeftTreadPanner.PanDirection = rot(0, 16384, 0);
                           //RightTreadPanner.PanDirection = rot(0, 16384, 0);
                        Skins[4] = LeftTreadPanner;
                           Skins[3] = RightTreadPanner;
                      }
                      
                      defaultproperties
                      {
                      
                           WheelSuspensionTravel=90.000000
                           WheelSuspensionOffset=-10.000000
                           WheelSuspensionMaxRenderTravel=90.000000
                           WheelSoftness=0.110000
                           WheelPenScale=1.900000
                      
                           Begin Object Class=SVehicleWheel Name=LFWheel
                           BoneName="lfarm"
                           WheelRadius=40.000000
                           SupportBoneName="LFPivot"
                           End Object
                           Wheels(0)=SVehicleWheel'H3_Vehicles.H3_Scorpion_Tank_Chassis.LFWheel'
                      
                           Begin Object Class=SVehicleWheel Name=RFWheel
                           BoneName="rfarm"
                           WheelRadius=40.000000
                           SupportBoneName="RFPivot"
                           End Object
                           Wheels(1)=SVehicleWheel'H3_Vehicles.H3_Scorpion_Tank_Chassis.RFWheel'
                      
                           Begin Object Class=SVehicleWheel Name=LRWheel
                           BoneName="lrarm"
                           WheelRadius=40.000000
                           SupportBoneName="LRPivot"
                           End Object
                           Wheels(2)=SVehicleWheel'H3_Vehicles.H3_Scorpion_Tank_Chassis.LRWheel'
                      
                           Begin Object Class=SVehicleWheel Name=RRWheel
                           BoneName="rrarm"
                           WheelRadius=40.000000
                           SupportBoneName="RRPivot"
                           End Object
                           Wheels(3)=SVehicleWheel'H3_Vehicles.H3_Scorpion_Tank_Chassis.RRWheel'
                      
                           DriverWeapons(0)=(WeaponClass=Class'H3_Vehicles.H3_Scorpion_Tank_Cannon',WeaponBone="TankCannonWeapon")
                           PassengerWeapons(0)=(WeaponPawnClass=Class'H3_Vehicles.H3_Scorpion_Tank_MG_TurretPawn',WeaponBone="MachineGunTurret")
                           bHasAltFire=True
                           RedSkin=Texture'H3_VehiclesTX.SCORPION.scorpion_hull'
                           BlueSkin=Texture'H3_VehiclesTX.SCORPION.scorpion_hull'
                           DestroyedVehicleMesh=AS_Vehicles_SM.Vehicles.IonTankDestroyed
                           DestructionEffectClass=Onslaught.ONSVehicleIonExplosionEffect
                           DisintegrationEffectClass=Onslaught.ONSVehicleExplosionEffect
                           bShowChargingBar=True
                           FPCamPos=(X=-80.000000,Z=150.000000)
                           FPCamViewOffset=(X=25.000000)
                           VehiclePositionString="in an Halo 3 Scorpion Tank"
                           VehicleNameString="Halo 3 Scorpion Tank"
                           RanOverDamageType=OnslaughtFull.DamTypeIonTankRoadkill
                           CrushedDamageType=OnslaughtFull.DamTypeIonTankPancake
                           VehicleIcon=(Material=Texture'H3_VehiclesTX.SCORPION.scorpion_treads',bIsGreyScale=True)
                           Mesh=SkeletalMesh'H3_Vehicles_A.H3_Scorpion_Tank_Chassis'
                           //Skins(0)=Texture'H3_VehiclesTX.SCORPION.scorpion_treads'
                           //Skins(1)=Texture'H3_VehiclesTX.SCORPION.scorpion_treads'
                        Skins(3)=Texture'H3_VehiclesTX.Scorpion.scorpion_Treads'
                           Skins(4)=Texture'H3_VehiclesTX.Scorpion.scorpion_Treads'
                      }
                      The rest of the vehicle package looked pretty good too. I like the way this Scorpion's "tread blocks" move up and down over objects, I did not know that was possible to do by just inserting that wheel code above! Its very cool!

                      Also, I found a way to reduce the H3_VehiclesTx.utx file from the 200+ Mb down to about 25Mb. First you can compress all of the textures down to either dxt1 (if no transparency) or dxt5 (if there is some transparency) by right clicking the texture in the browser and select the compress option.

                      ... and then for the two repeating tiled floor textures, those can be edited to just one tile, and then use a texscaler to make them repeat the number of times you need them to (and then delete those "fat" 2048x2048 and 4096x4096 textures altogether). I exported them both and edited them in PaintShopPro to select one tile (one was 64x64 pixels, the other was 256x256 pixels). I then reimported them, created new TexScalers and adjusted the U and V scaling appropriately. For the 64x64 textures the scaling should be 1/64 (since the old texture tiled 64 times) which is 0.015625 for both U & V. For the 256x256 tile the scaling should be 1/8 (since the old texture tiled 8 times) which is 0.125 for both U & V.

                      I would post the tutorial links to using the TexScalers but it looks like Epic may have broken/eliminated those pages altogether (how lame!!) from the UDN2.
                      Last edited by meowcatbuf; 02-03-2018, 06:46 PM.

                      Comment


                        Wow, the tread works great. Thanks again meowcatbuf, I could not have done it with out your help.
                        I have racked my brain for months to figure it out, but to no avail.
                        I really admire you talent for coding, the best I can do is just to understand what code to copy where.
                        But you can create new code out of thin air, that is very cool.

                        The "Scorpion's tread blocks moving up and down over objects" code was created by exo7341.
                        I told him what I wanted the tank pods to do (it was very difficult to explain) and exo7341
                        created the code and tweaked it a bunch of times to make it perfect (he did some tricky stuff to make it work).

                        Thanks for the info on the dxt1 and dxt5 texture compression.
                        Funny thing, I was planning on asking you how its done as soon I fixed all vehicles.
                        Because if I change any textures, I think I would have to re-compress them all over again?

                        Ok, I took a look at the original code and compared it to the new code you made.
                        I changed the code on the HR tank Skins from 1 and 2 to 7 and 6 as you told me to do
                        with the corresponding animation texture list number order.

                        Everything worked in the right place but the tread is running backwards.
                        How do I reverse the direction of the tank treads texture movement?


                        Code:
                        //=============================================================================
                        //
                        //=============================================================================
                        
                        class HR_Scorpion_Tank_Chassis extends ONSHoverTank;
                        
                        #exec OBJ LOAD FILE=..\Animations\HR_Vehicles_A.ukx
                        
                        var() float WheelSuspensionTravel; //added for treadpod control
                        var() float WheelSuspensionOffset; //added for treadpod control
                        var() float WheelSuspensionMaxRenderTravel; //added for treadpod control
                        var() float WheelSoftness; //added for treadpod control
                        var() float WheelPenScale; //added for treadpod control
                        
                        
                        simulated event bool KUpdateState(out KRigidBodyState newState)
                        {
                        // This should never get called on the server - but just in case!
                        if(Role == ROLE_Authority || !bNewTreadState)
                        return false;
                        
                        
                        newState = ChassisState;
                        bNewTreadState = false;
                        
                        
                        return true;
                        }
                        
                        
                        //==================================================================
                        simulated event SVehicleUpdateParams() //added for treadpod control
                        {
                        local KarmaParams kp; //======from ONSTreadCraft========
                        local int i;
                        
                        
                        Super.SVehicleUpdateParams();
                        
                        kp = KarmaParams(KParams); //===========================
                        
                        
                        for(i=0;i<kp.Repulsors.Length;i++)
                        {
                        kp.Repulsors[i].Softness = HoverSoftness; //ONSTreadCraft stuff
                        kp.Repulsors[i].PenScale = HoverPenScale;
                        kp.Repulsors[i].CheckDist = HoverCheckDist;
                        }
                        
                        
                        KSetStayUprightParams( UprightStiffness, UprightDamping ); //==================
                        
                        
                        for(i=0; i<Wheels.Length; i++) //********ONSWheeledCraft******************
                        {
                        Wheels[i].Softness = WheelSoftness;
                        Wheels[i].PenScale = WheelPenScale;
                        //Wheels[i].PenOffset = WheelPenOffset; //I only called what I needed here for the effect to work
                        //Wheels[i].LongSlip = WheelLongSlip;
                        //Wheels[i].LatSlipFunc = WheelLatSlipFunc;
                        //Wheels[i].Restitution = WheelRestitution;
                        //Wheels[i].Adhesion = WheelAdhesion;
                        //Wheels[i].WheelInertia = WheelInertia;
                        //Wheels[i].LongFrictionFunc = WheelLongFrictionFunc;
                        //Wheels[i].HandbrakeFrictionFactor = WheelHandbrakeFriction;
                        //Wheels[i].HandbrakeSlipFactor = WheelHandbrakeSlip;
                        Wheels[i].SuspensionTravel = WheelSuspensionTravel;
                        Wheels[i].SuspensionOffset = WheelSuspensionOffset;
                        Wheels[i].SuspensionMaxRenderTravel = WheelSuspensionMaxRenderTravel;
                        } //******************************
                        }
                        
                        function AltFire(optional float F)
                        {
                        super(ONSVehicle).AltFire( F );
                        }
                        
                        function ClientVehicleCeaseFire(bool bWasAltFire)
                        {
                        super(ONSVehicle).ClientVehicleCeaseFire( bWasAltFire );
                        }
                        
                        simulated function SetupTreads()
                        {
                        LeftTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                        RightTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                        LeftTreadPanner.Material = Skins[6];
                        RightTreadPanner.Material = Skins[7];
                        LeftTreadPanner.PanRate = 0;
                        RightTreadPanner.PanRate = 0;
                        //LeftTreadPanner.PanDirection = rot(0, 16384, 0);
                        //RightTreadPanner.PanDirection = rot(0, 16384, 0);
                        Skins[6] = LeftTreadPanner;
                        Skins[7] = RightTreadPanner;
                        }
                        
                        defaultproperties
                        {
                        
                        WheelSuspensionTravel=90.000000
                        WheelSuspensionOffset=-10.000000
                        WheelSuspensionMaxRenderTravel=90.000000
                        WheelSoftness=0.110000
                        WheelPenScale=1.900000
                        
                        Begin Object Class=SVehicleWheel Name=LFWheel
                        BoneName="lfarm"
                        WheelRadius=40.000000
                        SupportBoneName="LFPivot"
                        End Object
                        Wheels(0)=SVehicleWheel'HR_Vehicles.HR_Scorpion_Tank_Chassis.LFWheel'
                        
                        Begin Object Class=SVehicleWheel Name=RFWheel
                        BoneName="rfarm"
                        WheelRadius=40.000000
                        SupportBoneName="RFPivot"
                        End Object
                        Wheels(1)=SVehicleWheel'HR_Vehicles.HR_Scorpion_Tank_Chassis.RFWheel'
                        
                        Begin Object Class=SVehicleWheel Name=LRWheel
                        BoneName="lrarm"
                        WheelRadius=40.000000
                        SupportBoneName="LRPivot"
                        End Object
                        Wheels(2)=SVehicleWheel'HR_Vehicles.HR_Scorpion_Tank_Chassis.LRWheel'
                        
                        Begin Object Class=SVehicleWheel Name=RRWheel
                        BoneName="rrarm"
                        WheelRadius=40.000000
                        SupportBoneName="RRPivot"
                        End Object
                        Wheels(3)=SVehicleWheel'HR_Vehicles.HR_Scorpion_Tank_Chassis.RRWheel'
                        
                        DriverWeapons(0)=(WeaponClass=Class'HR_Vehicles.HR_Scorpion_Tank_Cannon',WeaponBone="TankCannonWeapon")
                        PassengerWeapons(0)=
                        
                        (WeaponPawnClass=Class'HR_Vehicles.HR_Scorpion_Tank_MG_TurretPawn',WeaponBone="MachineGunTurret")
                        bHasAltFire=True
                        RedSkin=Texture'HR_Vehicles_TX.SCORPION.scorpion_turrets'
                        BlueSkin=Texture'HR_Vehicles_TX.SCORPION.scorpion_turrets'
                        DestroyedVehicleMesh=AS_Vehicles_SM.Vehicles.IonTankDestroyed
                        DestructionEffectClass=Onslaught.ONSVehicleIonExplosionEffect
                        DisintegrationEffectClass=Onslaught.ONSVehicleExplosionEffect
                        bShowChargingBar=True
                        FPCamPos=(X=-80.000000,Z=150.000000)
                        FPCamViewOffset=(X=25.000000)
                        VehiclePositionString="in an Scorpion Tank"
                        VehicleNameString="Scorpion Tank"
                        RanOverDamageType=OnslaughtFull.DamTypeIonTankRoadkill
                        CrushedDamageType=OnslaughtFull.DamTypeIonTankPancake
                        VehicleIcon=(Material=Texture'HR_Vehicles_TX.SCORPION.scorpion_treads',bIsGreyScale=True)
                        Mesh=SkeletalMesh'HR_Vehicles_A.HR_Scorpion_Tank_Chassis'
                        Skins(6)=Texture'HR_Vehicles_TX.SCORPION.scorpion_treads'
                        Skins(7)=Texture'HR_Vehicles_TX.SCORPION.scorpion_treads'
                        }
                        Last edited by Mega_Mad_Maxx; 02-08-2018, 05:51 PM. Reason: Edited cus I always make way to many mistakes :D

                        Comment


                          See where the two code lines reading:
                          //LeftTreadPanner.PanDirection = rot(0, 16384, 0);
                          //RightTreadPanner.PanDirection = rot(0, 16384, 0);

                          have been commented out in the 'SetUpTreads()' function? (commented out lines all begin with //)

                          Uncomment those lines and try setting the PanDirection to this instead:
                          LeftTreadPanner.PanDirection = rot(0, 32768, 0);
                          RightTreadPanner.PanDirection = rot(0, 32768, 0);

                          In unreal rotation units (URUs), 0-65535 is the same as 0-360 degrees, so 32768 (0.5 * 65535) = 180 degrees. Let me know if that does not work.

                          Comment


                            I uncommened the lines on the "PanDirection" and changed the number to 32768. Needless to say it now works perfect.
                            Thanks.

                            Well I got all the textures compressed to dx1 and dx5, some from 200mb down to 20mb.
                            I also textured the Behemoth and the tread seems to works fine.

                            I might have to split the tracks up to left tread and right tread (like with the tank), right now it all one texture.
                            I also have to add like 30 collision bones so bots can walk around on deck while its moving.
                            While I'm at it I think will make guns only used by passengers. After all I have to re-do it all over in 3dsmax anyway.

                            I have been putting it off for a while because its a lot of work to do, but it will be worth it in the end (much fun).

                            I wonder if it would be possible to make that crane move and pick things up? That will have to be for a later time.

                            One of the textures is incorrect in game but looks fine in the animation browser.
                            I think it may be a prob with skins[16] but I'm not sure.
                            Here is the code What do you think the texture problem is?

                            Code:
                            //=============================================================================
                            //
                            //=============================================================================
                            
                            class H3_Behemoth_Chassis extends ONSHoverTank;
                            
                            #exec OBJ LOAD FILE=..\textures\H3_VehiclesTX.utx
                            
                            var()    float            WheelSuspensionTravel;           //added for treadpod control
                            var()    float            WheelSuspensionOffset;           //added for treadpod control
                            var()    float            WheelSuspensionMaxRenderTravel;  //added for treadpod control
                            var()    float            WheelSoftness;                   //added for treadpod control
                            var()    float            WheelPenScale;                   //added for treadpod control
                            
                            
                            simulated event bool KUpdateState(out KRigidBodyState newState)
                            {
                                // This should never get called on the server - but just in case!
                                if(Role == ROLE_Authority || !bNewTreadState)
                                    return false;
                            
                            
                                newState = ChassisState;
                                bNewTreadState = false;
                            
                            
                                return true;
                            }
                            
                            
                            //==================================================================
                            simulated event SVehicleUpdateParams()  //added for treadpod control
                            {
                                    local KarmaParams kp; //======from ONSTreadCraft========
                                local int i;
                            
                            
                                Super.SVehicleUpdateParams();
                            
                                kp = KarmaParams(KParams);     //===========================
                            
                            
                                for(i=0;i<kp.Repulsors.Length;i++)
                                {
                                        kp.Repulsors[i].Softness = HoverSoftness;                //ONSTreadCraft stuff
                                        kp.Repulsors[i].PenScale = HoverPenScale;
                                        kp.Repulsors[i].CheckDist = HoverCheckDist;
                                }
                            
                            
                                KSetStayUprightParams( UprightStiffness, UprightDamping );   //==================
                            
                            
                                for(i=0; i<Wheels.Length; i++)                      //********ONSWheeledCraft******************
                                {
                                    Wheels[i].Softness = WheelSoftness;
                                    Wheels[i].PenScale = WheelPenScale;
                                    //Wheels[i].PenOffset = WheelPenOffset;  //I only called what I needed here for the effect to work
                                    //Wheels[i].LongSlip = WheelLongSlip;
                                    //Wheels[i].LatSlipFunc = WheelLatSlipFunc;
                                    //Wheels[i].Restitution = WheelRestitution;
                                    //Wheels[i].Adhesion = WheelAdhesion;
                                    //Wheels[i].WheelInertia = WheelInertia;
                                    //Wheels[i].LongFrictionFunc = WheelLongFrictionFunc;
                                    //Wheels[i].HandbrakeFrictionFactor = WheelHandbrakeFriction;
                                    //Wheels[i].HandbrakeSlipFactor = WheelHandbrakeSlip;
                                    Wheels[i].SuspensionTravel = WheelSuspensionTravel;
                                    Wheels[i].SuspensionOffset = WheelSuspensionOffset;
                                    Wheels[i].SuspensionMaxRenderTravel = WheelSuspensionMaxRenderTravel;
                                }                                                                   //******************************
                            }
                            
                            function AltFire(optional float F)
                            {
                                super(ONSVehicle).AltFire( F );
                            }
                            
                            function ClientVehicleCeaseFire(bool bWasAltFire)
                            {
                                super(ONSVehicle).ClientVehicleCeaseFire( bWasAltFire );
                            }
                            
                            simulated function SetupTreads()
                            {
                                LeftTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                                RightTreadPanner = VariableTexPanner(Level.ObjectPool.AllocateObject(class'VariableTexPanner'));
                                LeftTreadPanner.Material = Skins[23];
                                 RightTreadPanner.Material = Skins[16];
                                 LeftTreadPanner.PanRate = 0;
                                 RightTreadPanner.PanRate = 0;
                                 //LeftTreadPanner.PanDirection = rot(0, 16384, 0);
                                 //RightTreadPanner.PanDirection = rot(0, 16384, 0);
                                 Skins[23] = LeftTreadPanner;
                                 Skins[16] = RightTreadPanner;
                            }
                            
                            defaultproperties
                            {
                            
                                 WheelSuspensionTravel=90.000000
                                 WheelSuspensionOffset=-10.000000
                                 WheelSuspensionMaxRenderTravel=90.000000
                                 WheelSoftness=0.110000
                                 WheelPenScale=1.900000
                            
                            ////
                                 Begin Object Class=SVehicleWheel Name=LFWheel1
                                 BoneName="LFarm1"
                                 WheelRadius=25.000000
                                 SupportBoneName="LFPivot"
                                 End Object
                                 Wheels(0)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.LFWheel1'
                            
                                 Begin Object Class=SVehicleWheel Name=LFWheel2
                                 BoneName="LFarm2"
                                 WheelRadius=25.000000
                                 SupportBoneName="LFPivot"
                                 End Object
                                 Wheels(1)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.LFWheel2'
                            ////
                                 Begin Object Class=SVehicleWheel Name=RFWheel1
                                 BoneName="RFarm1"
                                 WheelRadius=25.000000
                                 SupportBoneName="RFPivot"
                                 End Object
                                 Wheels(2)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.RFWheel1'
                            
                                 Begin Object Class=SVehicleWheel Name=RFWheel2
                                 BoneName="RFarm2"
                                 WheelRadius=25.000000
                                 SupportBoneName="RFPivot"
                                 End Object
                                 Wheels(3)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.RFWheel2'
                            ////
                                 Begin Object Class=SVehicleWheel Name=LRWheel1
                                 BoneName="LRarm1"
                                 WheelRadius=25.000000
                                 SupportBoneName="LRPivot"
                                 End Object
                                 Wheels(4)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.LRWheel1'
                            
                                 Begin Object Class=SVehicleWheel Name=LRWheel2
                                 BoneName="LRarm2"
                                 WheelRadius=25.000000
                                 SupportBoneName="LRPivot"
                                 End Object
                                 Wheels(5)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.LRWheel2'
                            ////
                                 Begin Object Class=SVehicleWheel Name=RRWheel1
                                 BoneName="RRarm1"
                                 WheelRadius=25.000000
                                 SupportBoneName="RRPivot"
                                 End Object
                                 Wheels(6)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.RRWheel1'
                            
                                 Begin Object Class=SVehicleWheel Name=RRWheel2
                                 BoneName="RRarm2"
                                 WheelRadius=25.000000
                                 SupportBoneName="RRPivot"
                                 End Object
                                 Wheels(7)=SVehicleWheel'H3_Vehicles.H3_Behemoth_Chassis.RRWheel2'
                            ////
                                 DriverWeapons(0)=(WeaponClass=Class'H3_Vehicles.H3_Behemoth_RocketPods',WeaponBone="Rocket_Turret")
                                 PassengerWeapons(0)=(WeaponPawnClass=Class'H3_Vehicles.H3_Behemoth_SecondaryTurretPawn',WeaponBone="MG_Turret_1")
                                 PassengerWeapons(1)=(WeaponPawnClass=Class'H3_Vehicles.H3_Behemoth_SecondaryTurretPawn',WeaponBone="MG_Turret_2")
                                 bHasAltFire=True
                                 RedSkin=Texture'H3_VehiclesTX.bohemeth_parts'
                                 BlueSkin=Texture'H3_VehiclesTX.bohemeth_parts'
                                 DestroyedVehicleMesh=AS_Vehicles_SM.Vehicles.IonTankDestroyed
                                 DestructionEffectClass=Onslaught.ONSVehicleIonExplosionEffect
                                 DisintegrationEffectClass=Onslaught.ONSVehicleExplosionEffect
                                 bShowChargingBar=True
                                 FPCamPos=(X=-80.000000,Z=150.000000)
                                 FPCamViewOffset=(X=25.000000)
                                 VehiclePositionString="in an Behemoth"
                                 VehicleNameString="Behemoth"
                                 RanOverDamageType=OnslaughtFull.DamTypeIonTankRoadkill
                                 CrushedDamageType=OnslaughtFull.DamTypeIonTankPancake
                                 VehicleIcon=(Material=Texture'H3_VehiclesTX.Behemoth.beh_metal',bIsGreyScale=True)
                                 Mesh=SkeletalMesh'H3_Vehicles_A.H3_Behemoth_Chassis'
                                 Skins(16)=Texture'H3_VehiclesTX.Behemoth.bohemeth_treads'
                                 Skins(24)=Texture'H3_VehiclesTX.Behemoth.bohemeth_treads'
                            }
                            Last edited by Mega_Mad_Maxx; 02-13-2018, 03:30 AM.

                            Comment


                              In the SetupTreads() function you specify texture index 23 for one of them, but down in the default properties, you assign the tread texture to skin index 24, those should both match (either 23, or 24) whatever is correct when you check the model in the animation browser.

                              Comment


                                I need help with H2 Wraith hover tank.

                                Here is what I want to do, make the main cannon fire regular, but have the machine gun be on the Alt fire.

                                If i use this line of code by its self in the H2_Wraith_Chassis.uc (if you know what I mean) the cannon fire works fine.
                                Code:
                                     DriverWeapons(0)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Cannon',WeaponBone="Cannon")
                                If i use these lines of code by its self in the H2_Wraith_Chassis.uc (if you know what I mean) the gun fire works fine.
                                Code:
                                     DriverWeapons(0)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_R")
                                     DriverWeapons(1)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_L")
                                If i use all three lines of code in the H2_Wraith_Chassis.uc (if you know what I mean) only the cannon fire works.
                                Code:
                                     DriverWeapons(0)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Cannon',WeaponBone="Cannon")
                                     DriverWeapons(1)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_R")
                                     DriverWeapons(2)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_L")
                                How do I make them both work together with the machine gun/Gun_Fire on the Alt fire (if you know what I mean)?


                                Here is the code for H2_Wraith_Chassis.uc
                                Code:
                                //-----------------------------------------------------------
                                //
                                //-----------------------------------------------------------
                                class H2_Wraith_Chassis extends ONSHoverCraft;
                                
                                #exec OBJ LOAD FILE=..\Animations\H2_Vehicles_A.ukx
                                #exec OBJ LOAD FILE=..\textures\VehicleFX.utx
                                #exec OBJ LOAD FILE=..\textures\EpicParticles.utx
                                #exec OBJ LOAD FILE=..\textures\VMVehicles-TX.utx
                                #exec OBJ LOAD FILE=..\sounds\ONSVehicleSounds-S.uax
                                
                                
                                //// This code is for simultaneous right and left gun fire.
                                simulated function PostNetBeginPlay()
                                {
                                    Super.PostNetBeginPlay();
                                
                                    if (Role == ROLE_Authority)
                                    {
                                        if (WeaponPawns[0]!=None)
                                            WeaponPawns[0].Gun.SetOwner(self);
                                
                                        if (Weapons.Length == 2 && ONSLinkableWeapon(Weapons[0]) != None){
                                        ONSLinkableWeapon(Weapons[0]).ChildWeapon = Weapons[1];
                                        }
                                
                                    }
                                }
                                ////
                                
                                //// This code is for non stop fire problem fix.
                                function KDriverEnter(Pawn p)
                                {
                                    Super.KDriverEnter(p);
                                
                                
                                    Weapons[1].bActive = true;
                                }
                                
                                function VehicleCeaseFire(bool bWasAltFire)
                                {
                                    Super.VehicleCeaseFire(bWasAltFire);
                                
                                
                                    Weapons[1].CeaseFire(Controller);
                                    Weapons[1].WeaponCeaseFire(Controller,bWasAltFire);
                                }
                                ////
                                
                                
                                
                                defaultproperties
                                {
                                     MaxPitchSpeed=1000.000000
                                     JumpDuration=0.220000
                                     JumpForceMag=100.000000
                                     JumpDelay=3.000000
                                     DuckForceMag=150.000000
                                     JumpSound=ONSVehicleSounds-S.HoverBike.HoverBikeJump05
                                     DuckSound=ONSVehicleSounds-S.HoverBike.HoverBikeTurbo01
                                     JumpForce="HoverBikeJump"
                                     ThrusterOffsets(0)=(X=95.000000,Z=10.000000)
                                     ThrusterOffsets(1)=(X=-10.000000,Y=80.000000,Z=10.000000)
                                     ThrusterOffsets(2)=(X=-10.000000,Y=-80.000000,Z=10.000000)
                                     HoverSoftness=0.220000
                                     HoverPenScale=1.000000
                                     HoverCheckDist=150.000000
                                     UprightStiffness=500.000000
                                     UprightDamping=300.000000
                                     MaxThrustForce=27.000000
                                     LongDamping=0.020000
                                     MaxStrafeForce=15.000000
                                     LatDamping=0.100000
                                     TurnTorqueFactor=1000.000000
                                     TurnTorqueMax=125.000000
                                     TurnDamping=40.000000
                                     MaxYawRate=1.500000
                                     PitchTorqueFactor=200.000000
                                     PitchTorqueMax=9.000000
                                     PitchDamping=20.000000
                                     RollTorqueTurnFactor=450.000000
                                     RollTorqueStrafeFactor=200.000000
                                     RollTorqueMax=12.500000
                                     RollDamping=30.000000
                                     StopThreshold=50.000000
                                     DriverWeapons(0)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Cannon',WeaponBone="Cannon")
                                     DriverWeapons(1)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_R")
                                     DriverWeapons(2)=(WeaponClass=Class'H2_Vehicles.H2_Wraith_Gun_Fire',WeaponBone="Gun_Fire_L")
                                     bHasAltFire=False
                                     IdleSound=Sound'Ghost.Ghost.ghost_hover'
                                     StartUpSound=Sound'Ghost.Ghost.ghost_in'
                                     ShutDownSound=Sound'Ghost.Ghost.ghost_out'
                                     StartUpForce="HoverBikeStartUp"
                                     ShutDownForce="HoverBikeShutDown"
                                     DestroyedVehicleMesh=ONSDeadVehicles-SM.HoverBikeDead
                                     DestructionEffectClass=Onslaught.ONSSmallVehicleExplosionEffect
                                     DisintegrationEffectClass=Onslaught.ONSVehDeathHoverBike
                                     DestructionLinearMomentum=(Min=62000.000000,Max=100000.000000)
                                     DestructionAngularMomentum=(Min=25.000000,Max=75.000000)
                                     DamagedEffectScale=0.600000
                                     DamagedEffectOffset=(X=50.000000,Y=-25.000000,Z=10.000000)
                                     ImpactDamageMult=0.000100
                                     HeadlightCoronaOffset(0)=(X=73.000000,Y=10.000000,Z=14.000000)
                                     HeadlightCoronaOffset(1)=(X=73.000000,Y=-10.000000,Z=14.000000)
                                     HeadlightCoronaMaterial=Texture'EpicParticles.Flares.FlashFlare1'
                                     HeadlightCoronaMaxSize=60.000000
                                     bDrawDriverInTP=False
                                     bTurnInPlace=True
                                     bShowDamageOverlay=True
                                     bScriptedRise=True
                                     bShowChargingBar=True
                                     bDriverHoldsFlag=False
                                     bCanCarryFlag=False
                                     DrivePos=(Z=130.000000)
                                     ExitPositions(0)=(Y=-200.000000,Z=100.000000)
                                     ExitPositions(1)=(Y=200.000000,Z=100.000000)
                                     EntryRadius=375.000000
                                     FPCamPos=(X=-70.000000,Z=130.000000)
                                     FPCamViewOffset=(X=90.000000)
                                     TPCamLookat=(X=-50.000000,Z=0.000000)
                                     TPCamWorldOffset=(Z=250.000000)
                                     VehiclePositionString="in a H2 Wraith Tank"
                                     VehicleNameString="H2 Wraith Tank"
                                     RanOverDamageType=Onslaught.DamTypeHoverBikeHeadshot
                                     CrushedDamageType=Onslaught.DamTypeHoverBikePancake
                                     ObjectiveGetOutDist=750.000000
                                     FlagBone="HoverCraft"
                                     FlagOffset=(Z=45.000000)
                                     FlagRotation=(Yaw=32768)
                                     HornSounds(0)=ONSVehicleSounds-S.Horns.Horn02
                                     HornSounds(1)=ONSVehicleSounds-S.Horns.La_Cucharacha_Horn
                                     bCanStrafe=True
                                     MeleeRange=-100.000000
                                     GroundSpeed=520.000000
                                     HealthMax=900.000000
                                     Health=900
                                     Mesh=SkeletalMesh'H2_Vehicles_A.H2_Wraith_Chassis'
                                     SoundRadius=900.000000
                                     Begin Object Class=KarmaParamsRBFull Name=KParams0
                                         KInertiaTensor(0)=1.300000
                                         KInertiaTensor(3)=4.000000
                                         KInertiaTensor(5)=4.500000
                                         KLinearDamping=0.150000
                                         KAngularDamping=0.000000
                                         KStartEnabled=True
                                         bHighDetailOnly=False
                                         bClientOnly=False
                                         bKDoubleTickRate=True
                                         bKStayUpright=True
                                         bKAllowRotate=True
                                         bDestroyOnWorldPenetrate=True
                                         bDoSafetime=True
                                         KFriction=0.500000
                                         KImpactThreshold=700.000000
                                     End Object
                                     KParams=KarmaParamsRBFull'H2_Vehicles.H2_Wraith_Chassis.KParams0'
                                
                                }



                                Here is the code for H2_Wraith_Gun_Fire.uc
                                Code:
                                //-----------------------------------------------------------
                                //
                                //-----------------------------------------------------------
                                class H2_Wraith_Gun_Fire extends ONSLinkableWeapon;
                                
                                var class<Emitter>      mTracerClass;
                                var() editinline Emitter mTracer;
                                var() float                mTracerInterval;
                                var() float                mTracerPullback;
                                var() float                mTracerMinDistance;
                                var() float                mTracerSpeed;
                                var float                mLastTracerTime;
                                
                                static function StaticPrecache(LevelInfo L)
                                {
                                    L.AddPrecacheMaterial(Material'VMparticleTextures.TankFiringP.CloudParticleOrangeBMPtex');
                                    L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.TracerShot');
                                }
                                
                                simulated function UpdatePrecacheMaterials()
                                {
                                    Level.AddPrecacheMaterial(Material'VMparticleTextures.TankFiringP.CloudParticleOrangeBMPtex');
                                    Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.TracerShot');
                                
                                    Super.UpdatePrecacheMaterials();
                                }
                                
                                function byte BestMode()
                                {
                                    return 0;
                                }
                                
                                simulated function Destroyed()
                                {
                                    if (mTracer != None)
                                        mTracer.Destroy();
                                
                                    Super.Destroyed();
                                }
                                
                                simulated function UpdateTracer()
                                {
                                    local vector SpawnDir, SpawnVel;
                                    local float hitDist;
                                
                                    if (Level.NetMode == NM_DedicatedServer)
                                        return;
                                
                                    if (mTracer == None)
                                    {
                                        mTracer = Spawn(mTracerClass);
                                    }
                                
                                    if (Level.bDropDetail || Level.DetailMode == DM_Low)
                                        mTracerInterval = 2 * Default.mTracerInterval;
                                    else
                                        mTracerInterval = Default.mTracerInterval;
                                
                                    if (mTracer != None && Level.TimeSeconds > mLastTracerTime + mTracerInterval)
                                    {
                                            mTracer.SetLocation(WeaponFireLocation);
                                
                                        hitDist = VSize(LastHitLocation - WeaponFireLocation) - mTracerPullback;
                                
                                        if (Instigator != None && Instigator.IsLocallyControlled())
                                            SpawnDir = vector(WeaponFireRotation);
                                        else
                                            SpawnDir = Normal(LastHitLocation - WeaponFireLocation);
                                
                                        if(hitDist > mTracerMinDistance)
                                        {
                                            SpawnVel = SpawnDir * mTracerSpeed;
                                
                                            mTracer.Emitters[0].StartVelocityRange.X.Min = SpawnVel.X;
                                            mTracer.Emitters[0].StartVelocityRange.X.Max = SpawnVel.X;
                                            mTracer.Emitters[0].StartVelocityRange.Y.Min = SpawnVel.Y;
                                            mTracer.Emitters[0].StartVelocityRange.Y.Max = SpawnVel.Y;
                                            mTracer.Emitters[0].StartVelocityRange.Z.Min = SpawnVel.Z;
                                            mTracer.Emitters[0].StartVelocityRange.Z.Max = SpawnVel.Z;
                                
                                            mTracer.Emitters[0].LifetimeRange.Min = hitDist / mTracerSpeed;
                                            mTracer.Emitters[0].LifetimeRange.Max = mTracer.Emitters[0].LifetimeRange.Min;
                                
                                            mTracer.SpawnParticle(1);
                                        }
                                
                                        mLastTracerTime = Level.TimeSeconds;
                                    }
                                }
                                
                                simulated function FlashMuzzleFlash()
                                {
                                    Super.FlashMuzzleFlash();
                                
                                    if (Role < ROLE_Authority)
                                        DualFireOffset *= -1;
                                
                                    UpdateTracer();
                                }
                                
                                defaultproperties
                                {
                                     mTracerClass=Class'XEffects.NewTracer'
                                     mTracerInterval=0.060000
                                     mTracerPullback=150.000000
                                     mTracerSpeed=15000.000000
                                     YawBone="Dummy_Fire"
                                     PitchBone="Dummy_Fire"
                                     PitchUpLimit=12500
                                     PitchDownLimit=59500
                                     WeaponFireAttachmentBone="Dummy_Fire"
                                     WeaponFireOffset=0.000001
                                     DualFireOffset=5.000000
                                     RotationsPerSecond=2.000000
                                     bInstantRotation=True
                                     bInstantFire=True
                                     bDoOffsetTrace=True
                                     bAmbientFireSound=True
                                     bIsRepeatingFF=True
                                     Spread=0.010000
                                     RedSkin=Shader'VMVehicles-TX.HoverTankGroup.HoverTankChassisFinalRED'
                                     BlueSkin=Shader'VMVehicles-TX.HoverTankGroup.HoverTankChassisFinalBLUE'
                                     FireInterval=0.100000
                                     AmbientEffectEmitterClass=Class'Onslaught.ONSRVChainGunFireEffect'
                                     FireSoundClass=Sound'ONSVehicleSounds-S.Tank.TankMachineGun01'
                                     AmbientSoundScaling=1.300000
                                     FireForce="minifireb"
                                     DamageType=Class'Onslaught.DamTypeONSChainGun'
                                     DamageMin=17
                                     DamageMax=17
                                     TraceRange=15000.000000
                                     ShakeRotMag=(X=50.000000,Y=50.000000,Z=50.000000)
                                     ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
                                     ShakeRotTime=2.000000
                                     ShakeOffsetMag=(X=1.000000,Y=1.000000,Z=1.000000)
                                     ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
                                     ShakeOffsetTime=2.000000
                                     AIInfo(0)=(bInstantHit=True,aimerror=750.000000)
                                     CullDistance=8000.000000
                                     Mesh=SkeletalMesh'H2_Vehicles_A.Dummy_Fire'
                                }



                                Here is the code for H2_Wraith_Cannon.uc
                                Code:
                                //=============================================================================
                                //
                                //
                                //=============================================================================
                                
                                class H2_Wraith_Cannon extends ONSHoverTankCannon;
                                
                                var()    class<FX_Turret_IonCannon_BeamFire> BeamEffectClass;
                                var        float    StartHoldTime, MaxHoldTime, ShockMomentum, ShockRadius;
                                var        bool    bHoldingFire, bFireMode;
                                var        int        BeamCount, OldBeamCount;
                                
                                var    sound    ChargingSound, ShockSound;
                                
                                var    FX_IonPlasmaTank_AimLaser    AimLaser;
                                
                                replication
                                {
                                    reliable if ( bNetDirty && !bNetOwner && Role == ROLE_Authority )
                                        bFireMode, BeamCount;
                                }
                                
                                simulated function Destroyed()
                                {
                                    KillLaserBeam();
                                
                                    super.Destroyed();
                                }
                                
                                function PlayFiring()
                                {
                                    AmbientSound = None;
                                    PlaySound(sound'WeaponSounds.BExplosion5', SLOT_None, FireSoundVolume/255.0,,,, False);
                                }
                                
                                function PlayChargeUp()
                                {
                                    AmbientSound = ChargingSound;
                                }
                                
                                function PlayRelease()
                                {
                                    AmbientSound = None;
                                    PlaySound(sound'WeaponSounds.TranslocatorModuleRegeneration', SLOT_None, FireSoundVolume/255.0,,,, False);
                                }
                                
                                simulated event FlashMuzzleFlash()
                                {
                                    super.FlashMuzzleFlash();
                                
                                    if ( Level.NetMode != NM_DedicatedServer )
                                    {
                                        if ( !IsAltFire() && BeamCount != OldBeamCount )
                                        {
                                            OldBeamCount = BeamCount;
                                            PlayAnim('Fire', 0.5, 0);
                                            super.ShakeView();
                                        }
                                    }
                                }
                                
                                simulated function bool IsAltFire()
                                {
                                    if ( Instigator.IsLocallyControlled() )
                                        return bIsAltFire;
                                
                                    return bFireMode;
                                }
                                
                                simulated function ShakeView()
                                {
                                    if ( IsAltFire() )
                                        super.ShakeView();
                                }
                                
                                simulated function float ChargeBar()
                                {
                                    if ( bHoldingFire )
                                        return (FMin(Level.TimeSeconds - StartHoldTime, MaxHoldTime) / MaxHoldTime);
                                    else
                                        return 0;
                                }
                                
                                function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum)
                                {
                                    local FX_Turret_IonCannon_BeamFire Beam;
                                
                                    Beam = Spawn(BeamEffectClass,,, Start, Dir);
                                    if (ReflectNum != 0) Beam.Instigator = None; // prevents client side repositioning of beam start
                                    Beam.AimAt(HitLocation, HitNormal);
                                }
                                
                                function SpawnLaserBeam()
                                {
                                    CalcWeaponFire();
                                    AimLaser = Spawn(class'FX_IonPlasmaTank_AimLaser', Self,, WeaponFireLocation, WeaponFireRotation);
                                }
                                
                                function KillLaserBeam()
                                {
                                    if ( AimLaser != None )
                                    {
                                        AimLaser.Destroy();
                                        AimLaser = None;
                                    }
                                }
                                
                                simulated function UpdateLaserBeamLocation( out vector Start, out vector HitLocation )
                                {
                                    local vector    HitNormal;
                                    local rotator    Dir;
                                
                                    CalcWeaponFire();
                                    Start        = WeaponFireLocation;
                                    Dir            = WeaponFireRotation;
                                    HitLocation    = vect(0,0,0);
                                    SimulateTraceFire( Start, Dir, HitLocation, HitNormal );
                                    //log("UpdateLaserBeamLocation WFL:" @ WeaponFireLocation @ "WFR:" @ WeaponFireRotation
                                    //    @ "Start:" @ Start @ "HL:" @ HitLocation );
                                }
                                
                                event bool AttemptFire( Controller C, bool bAltFire )
                                {
                                    bFireMode = bAltFire;
                                    return super.AttemptFire( C, bAltFire );
                                }
                                
                                state ProjectileFireMode
                                {
                                    simulated function ClientStartFire(Controller C, bool bAltFire)
                                    {
                                        bFireMode    = bAltFire;
                                        bIsAltFire    = bAltFire;
                                        //log("ClientStartFire");
                                        if ( !bAltFire )
                                        {
                                            if ( Role < ROLE_Authority && FireCountdown <= 0 )
                                            {
                                                bHoldingFire    = true;
                                                StartHoldTime    = Level.TimeSeconds;
                                                SetTimer( MaxHoldTime, false );
                                            }
                                            else
                                                SetTimer( FireCountDown, false );    // synch to starthold matches server (done in timer)
                                            //super.ClientStartFire(C, bAltFire);
                                
                                
                                        }
                                        else
                                        {
                                            super.ClientStartFire(C, bAltFire);
                                        }
                                    }
                                
                                    simulated function Timer()
                                    {
                                        if ( !bHoldingFire )
                                        {
                                            if ( Role < Role_Authority && !bFireMode )
                                            {
                                                bHoldingFire    = true;
                                                StartHoldTime    = Level.TimeSeconds;
                                                SetTimer( MaxHoldTime, false );
                                            }
                                            return;
                                        }
                                
                                        bHoldingFire    = false;
                                        FireCountdown    = FireInterval;
                                        SetTimer(FireInterval, false);
                                
                                        if ( Role == ROLE_Authority )
                                        {
                                            KillLaserBeam();
                                            CalcWeaponFire();
                                            FlashCount++;
                                            PlayFiring();
                                
                                            if ( AmbientEffectEmitter != None )
                                                AmbientEffectEmitter.SetEmitterStatus( true );
                                
                                            TraceFire(WeaponFireLocation, WeaponFireRotation);
                                        }
                                        BeamCount++;
                                        FlashMuzzleFlash();
                                    }
                                
                                    simulated function ClientStopFire(Controller C, bool bWasAltFire)
                                    {
                                        //log("ClientStopFire");
                                        super.ClientStopFire(C, bWasAltFire);
                                
                                        if ( bHoldingFire )
                                        {
                                            bHoldingFire    = false;
                                            FireCountdown    = FireInterval;
                                            ClientPlayForceFeedback("BioRifleFire");
                                        }
                                        SetTimer(0, false);
                                    }
                                
                                    function Fire(Controller C)
                                    {
                                        NetUpdateTime = Level.TimeSeconds - 1;
                                        bFireMode = false;
                                        //log("Fire");
                                        if ( !bHoldingFire )
                                        {
                                            PlayChargeUp();
                                            StartHoldTime    = Level.TimeSeconds;
                                            bHoldingFire    = true;
                                            SetTimer( MaxHoldTime, false );
                                            SpawnLaserBeam();
                                        }
                                    }
                                
                                    function AltFire(Controller C)
                                    {
                                        local actor        Shock;
                                        local float        DistScale, dist;
                                        local vector    dir, StartLocation;
                                        local Pawn        Victims;
                                
                                        NetUpdateTime = Level.TimeSeconds - 1;
                                        bFireMode = true;
                                        //log("AltFire");
                                        StartLocation = Instigator.Location;
                                
                                        PlaySound(ShockSound, SLOT_None, 128/255.0,,, 2.5, False);
                                
                                        Shock = Spawn(class'FX_IonPlasmaTank_ShockWave', Self,, StartLocation);
                                        Shock.SetBase( Instigator );
                                
                                        foreach VisibleCollidingActors( class'Pawn', Victims, ShockRadius, StartLocation )
                                        {
                                            //log("found:" @ Victims.GetHumanReadableName() );
                                            // don't let Shock affect fluid - VisibleCollisingActors doesn't really work for them - jag
                                            if( (Victims != Instigator) && (Victims.Controller != None)
                                                && (Victims.Controller.GetTeamNum() != Instigator.GetTeamNum())
                                                && (Victims.Role == ROLE_Authority) )
                                            {
                                
                                                dir = Victims.Location - StartLocation;
                                                dir.Z = 0;
                                                dist = FMax(1,VSize(dir));
                                                dir = Normal(Dir)*0.5 + vect(0,0,1);
                                                DistScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/ShockRadius);
                                                Victims.AddVelocity( DistScale * ShockMomentum * dir );
                                                //Victims.Velocity = (DistScale * ShockMomentum * dir);
                                                //Victims.TakeDamage(0, Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight +
                                
                                Victims.CollisionRadius) * dir,
                                                //(DistScale * ShockMomentum * dir), None    );
                                                //log("Victims:" @ Victims.GetHumanReadableName() @ "DistScale:" @ DistScale );
                                            }
                                        }
                                    }
                                
                                    function CeaseFire(Controller C)
                                    {
                                        //log("CeaseFire");
                                
                                        KillLaserBeam();
                                
                                        if ( bHoldingFire )
                                        {
                                            if ( Role == Role_Authority )
                                                PlayRelease();
                                
                                            SetTimer(0, false);
                                            bHoldingFire    = false;
                                            FireCountdown    = FireInterval;
                                        }
                                    }
                                }
                                
                                defaultproperties
                                {
                                     BeamEffectClass=Class'H2_Vehicles.H2_Wraith_BeamFire',WeaponBone="TankTurret")
                                     MaxHoldTime=2.000000
                                     ShockMomentum=750.000000
                                     ShockRadius=1792.000000
                                     ChargingSound=AssaultSounds.AssaultRifle.IonPowerUp
                                     ShockSound=ONSVehicleSounds-S.AVRiL.AvrilFire01
                                     RedSkin=None
                                     BlueSkin=None
                                     FireInterval=1.500000
                                     AltFireInterval=1.500000
                                     EffectEmitterClass=None
                                     FireSoundClass=WeaponSounds.BaseImpactAndExplosions.BExplosion5
                                     DamageMin=0
                                     DamageMax=0
                                     TraceRange=20000.000000
                                     ProjectileClass=None
                                     AIInfo(0)=(WarnTargetPct=0.990000,RefireRate=0.990000)
                                     Mesh=SkeletalMesh'H2_Vehicles_A.H2_Wraith_Cannon'
                                     SoundPitch=112
                                     SoundRadius=512.000000
                                }
                                Last edited by Mega_Mad_Maxx; 02-15-2018, 07:32 PM.

                                Comment

                                Working...
                                X