| Home Page | Recent Changes | Preferences

# Vehicles

## Introduction

Everything about vehicles, can't find something? ask. or add it yourself. (this isn't about Cars, but about all vehicles)

A lot of stuff needs to be created. So add it if you can.

## Info

The most importat thing that vehicles have is the ability to enter and exit them. Further thay have some code that controls firing, and some variables that get set when someone wants to stear or throttle.

## Code

### Don't kill driver

The TakeDamage can be changed so that if the vehicle is destroyed, the driver doesn't die, but takes a lot of damage. This is useful for smaller vehicles like bikes.

    function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation,
                            Vector momentum, class<DamageType> damageType)
    {
        Local Pawn OldDriver; //The driver that just exited

        // Avoid damage healing the car!
        if(Damage < 0)
            return;

        if(damageType == class'DamTypeSuperShockBeam')
            Health -= 100; // Instagib doesn't work on vehicles
        else
            Health -= 0.5 * Damage; // Weapons do less damage

        // The vehicle is dead!
        if(Health <= 0)
        {
            if ( Controller != None )
            {
                OldDriver = Driver;
                KDriverLeave(True); // Get the player out (forced)
                //Let the driver take a lot of damage
                OldDriver.TakeDamage(120, instigatedBy, hitlocation, momentum, damageType);
            }
            Destroy(); // Destroy the vehicle itself (see Destroyed)
        }
        KAddImpulse(momentum, hitlocation);
    }

### Getting more passengers in your vehicle

This is a lot of code, and it needs a custom ControllerClass. All this code is experimental, but has been tested in multiplayer. In multiplayer the camera of the Passengers has an message "viewing from ...." i'll look into that later. If you have any problems with this code, you should contact me (sneakeye_@hotmail.com)

Code is here Vehicles/Passengers

### 6 Wheels? Rear-Wheel Steering?

Adding extra wheels is pretty easy. And usefull for making tanks or hovercrafts. :]

Also Rear Steering with forward steering allows for some sharp turns and cool looking vehicle :]

    //=============================================================================
    // KHoverTank.
    // Base class for 6-invisable wheeled 'hover' vehicles using Karma
    // Assumes negative-X is forward, negative-Y is right
    //=============================================================================
    class KHoverTank extends KCar
        abstract;

    var KTire       midLeft, midRight;
    var (KHoverTank)    class<KTire>    MidTireClass;
    // Wheel positions
    var const float     WheelMidAlong;
    var const float     WheelMidAcross;

    replication
    {
        // We replicate the Gear for brake-lights etc.
        unreliable if(Role == ROLE_Authority)
            CarState, Gear;

        reliable if(Role == ROLE_Authority)
            FlipTimeLeft;
    }

    // When new information is received, see if its new. If so, pass bits off the the wheels.
    // Each part will then update its rigid body position via the KUpdateState event.
    // JTODO: This is where clever unpacking would happen.
    simulated event VehicleStateReceived()
    {
        local vector ChassisY, SteerY, ChassisZ, calcPos, WheelY, lPos;
        local vector chassisPos, chassisLinVel, chassisAngVel, WheelLinVel, wPosRel;
        local Quat relQ, WheelQ;

        // Don't do anything if car isn't started up.
        // Shouldn't need to worry about Fron or Rear as its done in Super.
        if( midLeft == None || midRight == None )
            return;

        Super.VehicleStateReceived()

        ////////////////////////// MID LEFT //////////////////////////
        midLeft.KGetRigidBodyState(midLeft.ReceiveState);

        // Position
        lPos.X = WheelMidAlong;
        lPos.Y = WheelMidAcross;
        lPos.Z = CarState.WheelHeight[2];
        calcPos = chassisPos + QuatRotateVector(CarState.ChassisQuaternion, lPos);
        midLeft.ReceiveState.Position = KRBVecFromVector(calcPos);

        // Rotation
        wheelQ = midLeft.KGetRBQuaternion();
        WheelY = QuatRotateVector(wheelQ, vect(0, 1, 0));
        relQ = QuatFindBetween(WheelY, ChassisY);
        midLeft.ReceiveState.Quaternion = QuatProduct(relQ, wheelQ);

        // Velocity
        wPosRel = calcPos - chassisPos;
        WheelLinVel = chassisLinVel + (chassisAngVel Cross wPosRel);
        WheelLinVel += CarState.WheelVertVel[2] * ChassisZ;
        midLeft.ReceiveState.LinVel = KRBVecFromVector(WheelLinVel);

        midLeft.bReceiveStateNew = true;

        ////////////////////////// MID RIGHT //////////////////////////
        midRight.KGetRigidBodyState(midRight.ReceiveState);

        // Position
        lPos.X = WheelMidAlong;
        lPos.Y = WheelMidAcross;
        lPos.Z = CarState.WheelHeight[3];
        calcPos = chassisPos + QuatRotateVector(CarState.ChassisQuaternion, lPos);
        midRight.ReceiveState.Position = KRBVecFromVector(calcPos);

        // Rotation
        wheelQ = midRight.KGetRBQuaternion();
        WheelY = QuatRotateVector(wheelQ, vect(0, 1, 0));
        relQ = QuatFindBetween(WheelY, ChassisY);
        midRight.ReceiveState.Quaternion = QuatProduct(relQ, wheelQ);

        // Velocity
        wPosRel = calcPos - chassisPos;
        WheelLinVel = chassisLinVel + (chassisAngVel Cross wPosRel);
        WheelLinVel += CarState.WheelVertVel[3] * ChassisZ;
        midRight.ReceiveState.LinVel = KRBVecFromVector(WheelLinVel);

        midRight.bReceiveStateNew = true;

        ////// OTHER //////

        // Update control inputs
        Steering = CarState.ServerSteering;
        OutputTorque = CarState.ServerTorque;
        OutputBrake = CarState.ServerBrake;
        OutputHandbrakeOn = CarState.ServerHandbrakeOn;

        // Update flags

        CarState.bNewState = false;
        bNewCarState = true;

    }

    // Pack current state of whole car into the state struct, to be sent to the client.
    // Should only get called on the server.
    function PackState()
    {
        local vector lPos, wPos, chassisPos, chassisLinVel, chassisAngVel, wPosRel, WheelLinVel;
        local vector ChassisX, ChassisZ, WheelY, oldPos, oldLinVel;
        local KRigidBodyState ChassisState, WheelState, TurrState;

        Super.PackState();

        ////////////////////////// MID LEFT //////////////////////////
        midLeft.KGetRigidBodyState(WheelState);
        wPos = KRBVecToVector(WheelState.Position);
        lPos = QuatRotateVector(QuatInvert(CarState.ChassisQuaternion), wPos - chassisPos);
        CarState.WheelHeight[2] = lPos.Z;

        wPosRel = KRBVecToVector(WheelState.Position) - chassisPos;
        WheelLinVel = chassisLinVel + (chassisAngVel Cross wPosRel);

        CarState.WheelVertVel[2] =
            ((WheelState.LinVel.X - WheelLinVel.X)* ChassisZ.X) +
            ((WheelState.LinVel.Y - WheelLinVel.Y)* ChassisZ.Y) +
            ((WheelState.LinVel.Z - WheelLinVel.Z)* ChassisZ.Z);

        WheelY = QuatRotateVector(WheelState.Quaternion, vect(0, 1, 0));

        ////////////////////////// MID RIGHT //////////////////////////
        midRight.KGetRigidBodyState(WheelState);
        wPos = KRBVecToVector(WheelState.Position);
        lPos = QuatRotateVector(QuatInvert(CarState.ChassisQuaternion), wPos - chassisPos);
        CarState.WheelHeight[3] = lPos.Z;

        wPosRel = KRBVecToVector(WheelState.Position) - chassisPos;
        WheelLinVel = chassisLinVel + (chassisAngVel Cross wPosRel);

        CarState.WheelVertVel[3] =
            ((WheelState.LinVel.X - WheelLinVel.X)* ChassisZ.X) +
            ((WheelState.LinVel.Y - WheelLinVel.Y)* ChassisZ.Y) +
            ((WheelState.LinVel.Z - WheelLinVel.Z)* ChassisZ.Z);

        WheelY = QuatRotateVector(WheelState.Quaternion, vect(0, 1, 0));

        // OTHER
        CarState.ServerSteering = Steering;
        CarState.ServerTorque = OutputTorque;
        CarState.ServerBrake = OutputBrake;
        CarState.ServerHandbrakeOn = OutputHandbrakeOn;

        // This flag lets the client know this data is new.
        CarState.bNewState = true;

    }

    simulated function PostNetBeginPlay()
    {
        local vector RotX, RotY, RotZ, lPos;

        Super.PostNetBeginPlay();

        // Set up suspension graphics
        GetAxes(Rotation,RotX,RotY,RotZ);

        frontLeft.bHidden = True;  // Invisable wheels for hovercrafts
        frontRight.bHidden = True;  // Invisable wheels for hovercrafts
        rearLeft.bHidden = True;  // Invisable wheels for hovercrafts
        rearRight.bHidden = True;  // Invisable wheels for hovercrafts
        midLeft = spawn(MidTireClass, self,, Location + WheelMidAlong*RotX - WheelMidAcross*RotY + (256 /*WheelVert*/)*RotZ, Rotation);
        midLeft.SetDrawScale3D(vect(1, 1, 1));
        midLeft.bHidden = True; // Invisable wheels for hovercrafts

        midRight = spawn(MidTireClass, self,, Location + WheelMidAlong*RotX - WheelMidAcross*RotY + (256 /*WheelVert*/)*RotZ, Rotation);
        midRight.SetDrawScale3D(vect(1, -1, 1));
        midRight.bHidden = True; // Invisable wheels for hovercrafts

        lPos.X = WheelMidAlong;
        lPos.Y = -WheelMidAcross;
        midRight.WheelJoint = spawn(class'KCarWheelJoint', self);
        midRight.WheelJoint.KPos1 = lPos/50;
        midRight.WheelJoint.KPriAxis1 = vect(0, 0, 1);
        midRight.WheelJoint.KSecAxis1 = vect(0, 1, 0);
        midRight.WheelJoint.KConstraintActor1 = self;
        midRight.WheelJoint.KPos2 = vect(0, 0, 0);
        midRight.WheelJoint.KPriAxis2 = vect(0, 0, 1);
        midRight.WheelJoint.KSecAxis2 = vect(0, 1, 0);
        midRight.WheelJoint.KConstraintActor2 = midRight;
        midRight.WheelJoint.SetPhysics(PHYS_Karma);

        lPos.Y = WheelMidAcross;
        midLeft.WheelJoint = spawn(class'KCarWheelJoint', self);
        midLeft.WheelJoint.KPos1 = lPos/50;
        midLeft.WheelJoint.KPriAxis1 = vect(0, 0, 1);
        midLeft.WheelJoint.KSecAxis1 = vect(0, 1, 0);
        midLeft.WheelJoint.KConstraintActor1 = self;
        midLeft.WheelJoint.KPos2 = vect(0, 0, 0);
        midLeft.WheelJoint.KPriAxis2 = vect(0, 0, 1);
        midLeft.WheelJoint.KSecAxis2 = vect(0, 1, 0);
        midLeft.WheelJoint.KConstraintActor2 = midLeft;
        midLeft.WheelJoint.SetPhysics(PHYS_Karma);

        // Initially make sure parameters are sync'ed with Karma
        KVehicleUpdateParams();

    }

    // Clean up wheels etc.
    simulated event Destroyed()
    {

        // Destroy joints holding wheels to car
        midLeft.WheelJoint.Destroy();
        midRight.WheelJoint.Destroy();

        // Destroy wheels themselves.
        midLeft.Destroy();
        midRight.Destroy();

        Super.Destroyed();

    }

    // Call this if you change any parameters (tire, suspension etc.) and they
    // will be passed down to each wheel/joint.
    simulated event KVehicleUpdateParams()
    {

        Super.KVehicleUpdateParams();

        midLeft.WheelJoint.bKSteeringLocked = true;
        midRight.WheelJoint.bKSteeringLocked = true;

        // unlock rear wheels for steering
        rearLeft.WheelJoint.bKSteeringLocked = false;
        rearLeft.WheelJoint.KProportionalGap = SteerPropGap;
        rearLeft.WheelJoint.KMaxSteerTorque = SteerTorque;
        rearLeft.WheelJoint.KMaxSteerSpeed = SteerSpeed;

        // unlock rear wheels for steering
        rearRight.WheelJoint.bKSteeringLocked = false;
        rearRight.WheelJoint.KProportionalGap = SteerPropGap;
        rearRight.WheelJoint.KMaxSteerTorque = SteerTorque;
        rearRight.WheelJoint.KMaxSteerSpeed = SteerSpeed;

        midLeft.WheelJoint.KSuspHighLimit = SuspHighLimit;
        midLeft.WheelJoint.KSuspLowLimit = SuspLowLimit;
        midLeft.WheelJoint.KSuspStiffness = SuspStiffness;
        midLeft.WheelJoint.KSuspDamping = SuspDamping;

        midRight.WheelJoint.KSuspHighLimit = SuspHighLimit;
        midRight.WheelJoint.KSuspLowLimit = SuspLowLimit;
        midRight.WheelJoint.KSuspStiffness = SuspStiffness;
        midRight.WheelJoint.KSuspDamping = SuspDamping;

        // Sync params with Karma. even front and rear wheels. just incase. :P
        frontLeft.WheelJoint.KUpdateConstraintParams();
        frontRight.WheelJoint.KUpdateConstraintParams();
        midLeft.WheelJoint.KUpdateConstraintParams();
        midRight.WheelJoint.KUpdateConstraintParams();
        rearLeft.WheelJoint.KUpdateConstraintParams();
        rearRight.WheelJoint.KUpdateConstraintParams();

        // Mass
        frontLeft.KSetMass(TireMass+2); // maybe increase front wheels mass to simulte engine weight??
        frontRight.KSetMass(TireMass+2); // maybe increase front wheels mass to simulte engine weight??
        midLeft.KSetMass(TireMass);
        midRight.KSetMass(TireMass);

        midLeft.RollFriction = TireRollFriction;
        midLeft.LateralFriction = TireLateralFriction;
        midLeft.RollSlip = TireRollSlip;
        midLeft.LateralSlip = TireLateralSlip;
        midLeft.MinSlip = TireMinSlip;
        midLeft.SlipRate = TireSlipRate;
        midLeft.Softness = TireSoftness;
        midLeft.Adhesion = TireAdhesion;
        midLeft.Restitution = TireRestitution;

        midRight.RollFriction = TireRollFriction;
        midRight.LateralFriction = TireLateralFriction;
        midRight.RollSlip = TireRollSlip;
        midRight.LateralSlip = TireLateralSlip;
        midRight.MinSlip = TireMinSlip;
        midRight.SlipRate = TireSlipRate;
        midRight.Softness = TireSoftness;
        midRight.Adhesion = TireAdhesion;
        midRight.Restitution = TireRestitution;

    }

    // Car Simulation
    simulated function Tick(float Delta)
    {
        local float tana, sFactor;

        Super.Tick(Delta);

        WheelSpinSpeed = (frontLeft.SpinSpeed
                + frontRight.SpinSpeed
                + rearLeft.SpinSpeed
                + midLeft.SpinSpeed
                + midRight.SpinSpeed
                + rearRight.SpinSpeed)/6;

        // Motor
        // MID .. make them wheel spin :]
        midLeft.WheelJoint.KMotorTorque = 0.5 * OutputTorque * TorqueSplit;
        midRight.WheelJoint.KMotorTorque = 0.5 * OutputTorque * TorqueSplit;

        // Braking

        if(OutputBrake)
        {
            midLeft.WheelJoint.KBraking = MaxBrakeTorque;
            midRight.WheelJoint.KBraking = MaxBrakeTorque;
        }
        else
        {
            midLeft.WheelJoint.KBraking = 0.0;
            midRight.WheelJoint.KBraking = 0.0;
        }

        // Steering
        tana = Tan(6.283/65536 * Steering * MaxSteerAngle);
        sFactor = 0.5 * tana * (2 * WheelFrontAcross) / Abs(WheelFrontAlong - WheelRearAlong);

        // Make rear wheel turn in opposite direction to turn properly: -65536/6.283
        RearLeft.WheelJoint.KSteerAngle = -65536/6.283 * Atan(tana, (1-sFactor));
        RearRight.WheelJoint.KSteerAngle = -65536/6.283 * Atan(tana, (1+sFactor));

        // Handbrake
        if(OutputHandbrakeOn == true)
        {

            midLeft.LateralFriction = TireLateralFriction + TireHandbrakeFriction;
            midLeft.LateralSlip = TireLateralSlip + TireHandbrakeSlip;

            midRight.LateralFriction = TireLateralFriction + TireHandbrakeFriction;
            midRight.LateralSlip = TireLateralSlip + TireHandbrakeSlip;
        }
        else
        {
            midLeft.LateralFriction = TireLateralFriction;
            midLeft.LateralSlip = TireLateralSlip;

            midRight.LateralFriction = TireLateralFriction;
            midRight.LateralSlip = TireLateralSlip;
        }

    }

    defaultproperties
    {
    }

### Adding a driver to the vehicle

I've added a driver to the speeder bike (I created a trike from it) this is how i've done it:

(this isn't all the code for the trike, because it's a little much to put it all here)

    class Trike extends KCar;

    var CarDummyDriver MyDummy;

    simulated function PostNetBeginPlay()
    {
        local vector RotX, RotY, RotZ;

        Super.PostNetBeginPlay();

        GetAxes(Rotation,RotX,RotY,RotZ);

        MyDummy = spawn(class'UMS_CarDummyDriver', self,, Location + DummyOffset.X * RotX + DummyOffset.Y * RotY + DummyOffset.Z * RotZ);
        MyDummy.SetBase(self);
        MyDummy.bHidden = True;
    }

    simulated function Destroyed()
    {
        Super.Destroyed();
        MyDummy.Destroy();
    }

    function KDriverEnter(Pawn p)
    {
        Super.KDriverEnter(p);
        p.bHidden = True;
        MyDummy.bHidden = False;
        MyDummy.LinkMesh(p.Mesh);
        MyDummy.Skins = p.Skins;
        //Set the rotation of bones, so it looks like it's sitting on the trike
        MyDummy.SetBoneRotation('bip01 spine', rot(0,8000,0));
        MyDummy.SetBoneRotation('Bip01 L UpperArm', rot(0,-14000,0));
        MyDummy.SetBoneRotation('Bip01 R UpperArm', rot(0,-14000,0));
    }

    function bool KDriverLeave(bool bForceLeave)
    {
        local Pawn OldDriver;

        OldDriver = Driver;
        // If we succesfully got out of the car, make driver visible again.
        if( Super.KDriverLeave(bForceLeave) )
        {
            MyDummy.bHidden = True;
            return true;
        }
        else
            return false;
    }

    defaultproperties
    {
        DummyOffset=(X=-26,Y=0,Z=10)
    }

And the dummy:

    class CarDummyDriver extends Actor;

    defaultproperties
    {
        Mesh=Mesh'Jugg.JuggMaleA'
        Skins(0)=Texture'PlayerSkins.JuggMaleABodyA'
        Skins(1)=Texture'PlayerSkins.JuggMaleAHeadA'

        bHardAttach=True
        DrawType=DT_Mesh
    }

## Bugs

The vehicle code has some small and big bugs, we try to list them all here, and fix them.

### Getting out under water

When you drive/fly/float your vehicle under water, and you get out, you can't move anymore, this is becouse your Physics is set to Falling, but it has to be Swimming. This can be fixed easy:

    function bool KDriverLeave(bool bForceLeave)
    {
        local Pawn OldDriver;

        OldDriver = Driver;

        // If we succesfully got out of the car, make driver visible again. And check if in water.
        if( Super.KDriverLeave(bForceLeave) )
        {
            OldDriver.bHidden = false; //Also seen in the bulldog, so can't be bad :)
            //If we are in water, set the physics to swimming
            if (OldDriver.TouchingWaterVolume())
            {
                OldDriver.SetPhysics(PHYS_Swimming);
            }
            return true;
        }
        else
            return false;
    }

### Replication

The replication of a struct doesn't seem to work always, i won't go into vehicle replication, but when it doesn't work, replicate a variable after the struct, that seems to help (don't forget to chance the AVar in game, or it won't get replicated)

    var int AVar; //Just for replication, else the VehicleState doesn't get replicated

    Replication
    {
        unreliable if(Role == ROLE_Authority)
            VehicleState, AVar;
    }

Maybe epic fixes this in the next patch.

### Suicide

If you suicide whilst in a vehicle, you die, but remain in the vehicle so you can't respawn. To fix it you would need to continually check that the driver still exists, and exit the vehicle if not.

## Tips

### Tuning vehicles

If you run the game in a window, then type at the console 'editactor class=bulldog', it should pop up a big properties dialog like in the editor that will let you tweak numbers while driving around. Also, try typing 'graph show' at the console with a vehicle in the level, and you should see a scrolling line-graph pop up. The data on the graph is from the GraphData function - see line 681 of KCar.uc.

## Links

Modifying The Bulldog

Cars Everything about cars

KVehicle The complete info about the KVehicle class

KCar The complete info about the KCar class

Alternative Vehicle Control Vehicles with visible driver

External:

[VehicleTest] copy into your URL bar

### New Vehicles

How about adding links to all new vehicles we find?

Daid303: This is my first wiki page, comments are welcome.

Icedude: Wow, pretty descriptive. I wonder if it would be possible to make a Half Life-style train...

Daid303: I just copied the tip from the beyondunreal forum (so it isn't really mine) And about the train, i was planning to try a truck (with a trailer) so if that works, a train would also be possible, but would give some problems to stick it on a track.

ProjectX: Isn't it a bit pointless to have a link to "modifying the bulldog" on the page "modifying the bulldog"?

Daid303: Yes, it is, luckly this isn't the page "modifying the bulldog" but the page "vehicles"

ProjectX: Woah weird glitch with my Internet Exploder. Sed I was on Modifying the Bulldog, and i selected the "Modifying the Bulldog" link too.

Flashman: The train in Halflife wasn't a "controlable" vehicle, it was more like a Mover actually. To do a train in unreal would simply be setting up a mover to follow a path, but you'd be limited to the number of keyframes and the general speed of the mover between those keyframes. I was working on a map in UT1 that had a subway train coming out of a tunnel and into another on one side of the map, it only did this when someone got close to the track though It makes a great interactive boundary, and when used at the edge of the map you can set it up so the player is electricuted even if he dodges the train and crosses the tracks !!!

Daid303: The train in HL was controlable (i know, not a real vehicle like in UT2003) but limit of keyframes (8?) can be overcome with some coding, setting the mover up would be a lot harder then, but it would work.

Legal: See Mover for more. It's just Key 0-9 when you rightclick, if you go to Actor Properties> Mover> KeyNum and set NumKeys to the equal + 1 you'll get (i think) 64 keys.

AlphaOne: How about modifying the bulldog to make it more realistic? I don't think that the special "wheel joint" is good enought. It just lets the wheel go up and down when it hits something. I want to see stuff like in Mobile forces. Where there are ACTUAL arms and springs holding the wheels of a car. BTW: how does the car drive anyways? Is it because the wheels spin, or just because some variable is changing inside the code? Sometimes it seems to me that the car is not responding when I want to turn; it keeps on going straight (no it's not like a power slide).

Daid303: Legal, is that mover trick tested? the mover in UT (not UT2003) couldn't have more keyframes if i'm right, becouse it has an array size of 8

Legal: I'm quite sure, somebody else know maybe? Oh, and while on Vehicles page, why have I not yet seen an MC

AlphaOne: I was playing around with UED lately and this is what I have come up with: (http://www.geocities.com/thematrixhunter/vehicletest1.zip - right click→Save As...) If the link does not work, ask me to e-mail you.

This is a very ugly vehicle, but it has an important part: independent suspension system. My idea was that someone codes an "engine" actor that can be attached to the body of the car. Then it should be told which wheels are powered by the "engine" and which are turnable (any combination of those). Also positions for passengers and a drivers should be attached to the vehicle. I think that would simplify the building of new vehicles becuase you don't have to code each one by hand - just build it in UED.

AlphaOne: I would like some feedback on my "vehicles" please...

Mychaeel: Geocities doesn't like to be (ab)used as a mere download mirror and thus has referrer checking just like the Unreal Wiki's image database. – Copy the link to an empty browser window's address bar to download the file.

Legal: Ok, forgot that, doh! I'll try when get home

btw, this means I can model a car and wheels separatly and just change basic stuff like suspension, max speed, acceleration etc? Is there a way to make a, say tricycle or a speedbike in an easy way? Can I add turrets? I want more info

AlphaOne: EVEN easier: all you have to change is how much power(torque) is transmitted to wach wheel. Suspension is changed in the properties of the Karma constraints.

For bikes just apply a force to keep the vehicle from tipping.

To add turrents and stuff I think you would have to create a separate actor and just attach it to the vehicle - not hard.

Each vehicle would have to have at least one driver position attached, which is in turn linked to the engine it controls.

I have not started coding yet - I have to learn UScript 1ST.

Foxpaw: I took a look at that vehicle, but there is an inherent problem with the way it is set up: well, a couple of ways, the main one being it can't be respawned. The Bulldog already has 'real' independant suspension on it though, so I think Epic beat you to the punch. They use coil-over suspension though instead of leaf springs..

Having said that, the KCar class was actually created with that sort of thing in mind. It has a lot of configurability for torque distribution, wheel position, and whatnot, though I don't know if those properties are aviailible to the editor or just script. Either way, it wouldn't be difficult to open up.

Erdrik: I tried attaching a simple 'turret' actor to a vehicle but it was beyond my abilities to keep its rotation reletive to the vehicle AND follower the Drivers Rotation... So I tried making it a subclass of KTire, and it just slid off the vehicle and started sliding uncontrolably along the ground. I beleive this is becuase I needed to spawn a 'WheelJoint' for it but I haven't tried yet.

Foxpaw: Turrets are possible, but making them track targets as the vehicle moves around can be quite a challenge. But yes, you do need a karma constraint to make it rotation, but I would HIGHLY recommend KHinge, not KCarWheelJoint. Also KTire uses a special Tire simulation when it touches things, which is definately NOT what you want it to do.

SnowCrash: I just wanted to know how I can simply take a static mesh of a car that I've imported, and apply vehicle properties to it (if that is possible). Maybe even take the chassis of the car and apply the properties and import some wheels that I can apply properties to and align on the car like the bulldog does.

Erdrik: sub-class Bulldog, and BulldogTire, and change they're staticmesh to your custom staticmesh

Ccx: I'm making Aircraft vehicle, but it doesn't work, it's not moving, not even falling.

Source: [4kb rar]

Mesh: [293kb rar]

Foxpaw: If you want to use Karma with an actor, you have to set a simplified collision hull for it. Polygon to polygon collision works for the proprietary physics, but not for Karma. If you don't set any collision then the karma object believes it is lodged deeply within the world, even if it shouldn't be touching anything. As a result, it is unable to move. I'm not sure if that's the problem or not, I only got to 94% on the static mesh download when it froze, and I have to get going to work. However, if it doesn't fall, then that's probrably the problem.

Your code appears to be heavily derived from code for cars, which is radically different. As a result there's really no need for things like the handbrake. I'd recommend that if you are writing something so different from a car that you start from scratch, deriving from KVehicle, or look at KShip, which has a working (supposedly, I haven't tried it though) implementation of a spacecraft.

MythOpus: Ccx: I've downloaded both the source and the mesh. I think I fixed the mesh to allow it to work properly with Karma, however, the source did not compile properly so I couldn't actually implement it. The error says something about FowardVel is a bad command or expression in KAircraft

Darmatage: Foxpaw, MythOpus, others: My situation is similar to Ccx's, but from a different angle. I am wondering if there is anything I need to do when exporting the static mesh from 3D Studio MAX so that it will work as a vehicle. Currently, I am simply exporting the selected mesh using the ascii exporter, which works great for the architecture in my scene. I am using a friend's script for the vehicle, and swapping out the static mesh under "Properties/Display". It works great on any mesh that came with Unreal 2003 (such as the DirtChunk) but every mesh I create from scratch refuses to move. Any suggestions for what I need to do when creating the mesh/exporting to make it work, or is it just the collision hull issue mntioned above? Do all Unreal 2003 meshes automatically come with this hull, and that is why my meshes need to be set?

Foxpaw: It is probrably the karma collision hull. I don't believe that all the built-in meshes have a collision hull, but many do. I believe that there is a page on the wiki somewhere that details exporting a collision hull from max. Failing that, you can export the hull as a DXF and import it as a brush, then set the brush as the hull, but that's not as good because then you can't use cylindrical or spherical parts of the hull, which will speed up collision calculations greatly.

MythOpus: The problem is the collision hull, but there are other ways of making one If you know how to use UED, subtract a cube (you might not need this step actuallyO_o) about as big as the static mesh and place your static mesh in the center of that cube. Then make a brush (anything but a flat brush), that is as close to the same size as the static mesh as you would life/possible. Then right click on the static mesh and click on ... Use As Collision.. or something to that effect (too lazy to open UED up)

Refactor Me - And then some!

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Image Uploads

Random Page

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

Mapping Topics

Mapping Lessons

UnrealEd Interface

Questions&Answers

Scripting Topics

Scripting Lessons

Making Mods

Class Tree

Questions&Answers

Modeling Topics

Questions&Answers

Log In