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!
Announcement
Collapse
No announcement yet.
Looking for a video tutorial on vehicles
Collapse
X
-
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
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); } } }
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' }
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.
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.
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' }
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
-
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")
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")
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")
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
Comment