|
The purpose
of this tutorial is to 'enlighten' those who are new to the Unreal Engine
to how physics for objects work. This tutorial is not intended to be a
"how to" for any particular problem, but instead strives to explain the
physics types, how they operate, and how they are generally used.
Step 1 : Know your enumerations
The Actor class
houses the all important enumeration (for those who aren't familiar with
enumerations, I can at best refer you to Tim Sweeney's UnrealScript
Language Reference document, an excellent source for general information
on the UnrealScript language) : EPhysics, which is defined as such :
var(Movement) const enum EPhysics {
PHYS_None, PHYS_Walking,
PHYS_Falling, PHYS_Swimming,
PHYS_Flying, PHYS_Rotating,
PHYS_Projectile, PHYS_Rolling,
PHYS_Interpolating,
PHYS_MovingBrush, PHYS_Spider,
PHYS_Trailer } Physics;
| What
this means is that there are 12 Physics 'types', though in reality, you
really have 11 available to use (we'll get into why this is in a bit).
Let's get down to business.
Step 2 : PHYS_Huh?
Let's get PHYS with it.
PHYS_None - as you might
guess, this physics type does nothing. Nada. Zip, zilch, the calorie
content of celery. With this physics set, your object will not do anything
for you. It will sit there until you set it's velocity, and it will do
exactly as you say with no fear of native code doing funny things to it.
PHYS_Walking - this physics type is not reserved, per se,
but is useless to you unless you have a Pawn subclass, in which it is
vital and you pretty much can't use anything else. For Pawns, this physics
has a LOT of native code behavior - if the Pawn isn't on solid ground,
native code will change the physics to PHYS_Falling automatically. If the
Pawn is falling and hits ground (lands), native code will change the
physics to PHYS_Walking automatically. This physics type is responsible
for the movement and feeling of the players in Unreal / Unreal Tournament.
The variables involved with this physics type are : GroundSpeed (the
maximum speed the Pawn can move on the ground) and Acceleration (how
quickly the Pawn accelerates to GroundSpeed).
PHYS_Falling
- though this one was mentioned in conjunction with PHYS_Walking, don't be
fooled - if nothing else, this is the most common physics type (other than
projectile) among in-game objects. This physics type is responsible for
objects being affected by gravity. Native code automatically adjusts the
object's velocity in the direction and magnitude of the ZoneGravity vector
in the zone that the object is in. Sure, this is a pretty simple thing to
do on your own, but with native code doing the work for you, you're far
better off (as well as having the benefit of taking the current zone
properties into account). Be careful - if you have an object that, in
script code, has it's velocity set specifically, even if it's set each
Tick(), your object WILL (and this can't be emphasized enough, because it
demonstrates the overpowering nature of native code) slowly move with the
gravity of the zone it is in.
PHYS_Swimming - another Pawn
related physics, though this one is not set by native code. Instead, this
physics type is used to simulate swimming behavior and controls for the
pawns, simulating bouyancy, among other things. Though it may feel a like
flying, swimming physics also takes into account the zone's fluidfriction
(all handled in native code), something flying does not.
PHYS_Flying - yet another Pawn related physics type. Flying
tells the native code to do pretty much one thing - allow the player to
move in any direction, unhindered by gravity. This means the player can
move about freely, but still interacts (collides) normally with world
objects and level geometry. The variables involved with this physics type
are AirSpeed (the speed the Pawn can move through the air) and
Acceleration (how quickly the Pawn accelerates to AirSpeed).
PHYS_Rotating - the name is pretty clear, though it's
application isn't. Rotating is for objects that, that's right, rotate.
This would include inventory items (like weapons on the ground) or level
objects (like fans). The speed at with the object rotates is governed by a
variable called RotationRate, a rotator.
PHYS_Projectile -
this is the other most common physics type (other than falling) among
in-game objects. This physics type is responsible for simple movements -
straight paths of travel objects, like rockets or bullets. With this
physics, the object will move according to it's set Velocity, ignoring
gravity. Objects that use this physics type are very easy simulated and
predicted (referring to network behavior model). Variables involved with
this physics type are AirSpeed and Acceleration (same as flying).
PHYS_Rolling - the red headed step child of the physics
types. This, in technical parlance, is seriously b0rk3d. Dead. Ceased to
be. No more. An ex-physics type.
PHYS_Interpolating - a
physics type that is largely used by native code. It is used when moving
Movers between keypoints as well as players between set interpolation
points. This physics type is not something you are likely to ever need,
unless you are putting together a map fly-through or complex mover for a
map.
PHYS_MovingBrush - for Movers specifically, this
physics type is responsible for the movement of elevators, platforms,
doors.. i.e. any brush that moves around in a map, this physics (powered
by native code) makes it work.
PHYS_Spider - if your first
impression is to think of things walking on walls and ceilings, you'd be
partially right. This physics was intended to allow objects to treat any
level geometry surface as the 'ground'. This physics type is rarely used,
and even more rarely experimented with.
PHYS_Trailer - a
fairly common physics type. Trailer does one very nice thing - tells the
object that has the physics type of Trailer to stay with (location wise)
the object that owns it. Trailer is the easiest way to make sure that one
object is always at the location (or a nearby offset) of it's owner, and
because it's handled by native code, you won't see lag in locations in net
games. Variables involved with this physics type are bTrailerSameRotation
(tells the Trailer'd object's rotation to always be the same as the
owner), bTrailerPrePivot (tells the native code to offset the location of
the Trailer'd object from the Owner object by a vector, PrePivot), and
PrePivot (a vector which is the the offset measured in world coordinates
and is treated as an absolute vector offset, not relational to the Owner's
rotation).
Step 3 : Physics in Action - Collisions
Now that you have the physics you want, it's important to
understand how the Unreal engine detects collisions between objects. Level
geometry is referred to as BSP geometry, or Binary Space Partition
geometry. Without getting into too much detail, it's sufficed to say that
collision with level geometry happens on a per polygon hit detection.
Everything else (i.e. all Actor classes) works off of what's called a
Collision Cylinder. In the Actor class, you have several key variables :
CollisionHeight - the height, measured in Unreal units, of
the collision cylinder as measured from the middle of the actor to the
top. This means that in reality, the collision cylinder is really 2 *
CollisionHeight - the object's location is CollisionHeight off the ground
(or the bottom of the cylinder is CollisionHeight below Location.Z) and
the top of the cylinder is at Location.Z + CollisionHeight.
CollisionRadius - the radius of the cylinder
bCollideWorld - whether or not the object will collide with
level geometry
bCollideActors - whether or not the object
will collide with other actor objects
bBlockActors - whether
or not the object will stop a moving Actor when they
collide
bBlockPlayers - whether or not the object will stop
a moving player when they collide
It is important to note that the
collision cylinder does not rotate with the object - it is static and
stays perpendicularly upright at all times (greatly simplifies collision
detection calculations). Now, when a collision occurs, several functions
might get called, depending on variables set.
HitWall(vector
HitNormal, Actor HitWall) - if bCollideWorld is on, this event
function gets called by the engine, letting the object know the normal to
the collision plane between the level polygon and the object (the
HitNormal points towards the object), as well as an Actor reference, which
would let you know a couple things - if HitWall == Level, you've hit
normal level geometry, if it's a Mover, then you've hit a mover.
Landed(vector HitNormal) - if the object physics is
PHYS_Falling, this event function gets called by the engine when the
object lands on level geometry while falling. HitNormal is the surface
normal of the level geometry landed on.
Bump(Actor Other) -
if bBlockActors or bBlockPlayers is on, this event function gets called
for both objects. This event function gets called by the engine only once
- at the initial time of the collision.
Touch(Actor Other)
- if bCollideActors is on, this event function gets called by the engine
for both objects. This event function gets called every Tick() that the
collision still occurs. When collision happens the first time, there is an
array of actors, called Touching[], which is a list of other actors
touching this one. Other is put into the array if it isn't already there
by native code. Touching[] is defined as const, meaning you cannot
manually change any values of the array within UScript.
UnTouch(Actor Other) - if bCollideActors is on, this event
function gets called by the engine for both objects. This event function
is called when colliding objects are no longer colliding (as soon as the
collision isn't occuring any more, this even function is called, but only
once).
When it comes to event functions being called, be
forewarned. Sometimes, the engine will not call both Touch() and Bump() -
if both objects are bBlockPlayers, Bump() will be called, Touch() won't.
If one object is bCollideActors and the other is bBlockActors, the object
being bumped (the bCollideActors object) will get a Bump() event while the
other will simply get a Touch() call.
Now you should at least have
a good handle on the basics of physics and collision with the Unreal
engine. There is a lot you can do with the rather simple tools given.
Enjoy what you've learned here and experiment! |