Tuesday, November 15, 2011

Collision in UnrealScript

Collision in UnrealScript is not always about complex physics in collision response. Sometimes we just want to know if two Actors are overlapping.

The 3D graphics of current games are very detailed and with many polygons, but the geometric shapes used to detect a collision remain simple because of performance. The cylinder is a common geometric shape used to detect collision. To define a cylinder we need the Radius of the base and its Height.

The Actor class has some Boolean properties related to collision, such as:
  • bCollideActors : If false, the actor does not respond to any type of collision.
  • bBlockActors: If true, the Unreal engine will not allow the two Actors to overlap.

And some events related to collision:
  • event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal): This event is called when two Actors are overlapping, but it will only happen if one of them has the bBlockActors property set to false.
  • event Bump(Actor Other, PrimitiveComponent OtherComp, Vector HitNormal): This event is called when two Actors are bumping into each other, but it will only happen if the two Actors have the bBlockActors property set to true.

As an example I created an UltraHealthPack. When the player collides with this UltraHealthPack its health max is increased by 50 and the new value of its health max is set to its current health.
class UltraHealthPack extends Actor
      placeable;

event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal)
{
   local Pawn pawnLocal;
   
   pawnLocal = Pawn( Other ); 
   
   if(pawnLocal != None)
   {
        //test if it is the Player
      if( pawnLocal.controller.bIsPlayer ) 
      {
         pawnLocal.HealthMax += 50;
         pawnLocal.Health = pawnLocal.HealthMax;
         
         //'self' is a reference to the current object (UltraHealthPack)
         self.Destroy();
      }
   }
}    
defaultproperties
{
    bCollideActors=true    
    bBlockActors=false
    
    Begin Object Class=CylinderComponent Name=CylinderComp
        CollisionRadius=32
        CollisionHeight=48
        CollideActors=true        
        BlockActors=false
    End Object
    
    Components.Add( CylinderComp )
    CollisionComponent=CylinderComp    
        
    Begin Object Class=DynamicLightEnvironmentComponent Name=LightEnvironmentComp
        bEnabled = true
    End Object
    
    Components.add( LightEnvironmentComp )
    
    Begin Object Class=StaticMeshComponent Name=StaticMeshComp
        StaticMesh = Pickups.Health_Large.Mesh.S_Pickups_Health_Large_Keg        
        LightEnvironment = LightEnvironmentComp
    End Object
    
    Components.add( StaticMeshComp )                
}


For more information about Collision:
Collision Reference