terça-feira, 15 de novembro de 2011

Colisão em UnrealScript

Colisão em UnrealScript nem sempre se trata de física complexa como resposta à uma colisão. As vezes queremos apenas saber se dois Actors estão se sobrepondo.

Apesar de os gráficos 3D dos personagens nos jogos atuais serem bem complexos e com muitos polígonos, as formas geométricas utilizadas para detectar uma colisão continuam sendo simples para poder manter um bom desempenho. O cilindro é uma das formas geométricas mais utilizadas para detectar colisão. Para definirmos um cilindro precisamos apenas informar o Raio da base e sua Altura.

A classe Actor possui algumas propriedades booleanas relacionadas a colisão, como:
  • bCollideActors : Se for falso, o Actor não responderá a nenhum tipo de colisão.
  • bBlockActors: Se for verdadeiro, a Unreal engine não permitirá que os dois Actors ocupem o mesmo lugar.
E alguns eventos relacionados à colisão:
  • event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal): Este evento é chamado quando dois Actors estão se sobrepondo, mas só ocorrerá se em um deles a propriedade bBlockActors for falso.
  • event Bump(Actor Other, PrimitiveComponent OtherComp, Vector HitNormal): Este evento é chamado quando dois Actors estão se encostando, mas só ocorrerá se nos dois Actors a propriedade bBlockActors for verdadeiro.
Como exemplo criei um UltraHealthPack. Quando o jogador colide com este UltraHealthPack a sua energia máxima é aumentada em 50 e a sua energia atual recebe o novo valor de sua energia máxima.
class UltraHealthPack extends Actor
      placeable;

event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal)
{
   local Pawn pawnLocal;
   
   pawnLocal = Pawn( Other ); 
   
   if(pawnLocal != None)
   {
        //verifica se é o Jogador
      if( pawnLocal.controller.bIsPlayer ) 
      {
         pawnLocal.HealthMax += 50;
         pawnLocal.Health = pawnLocal.HealthMax;
         
         //'self' é uma referencia ao objeto atual (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 )                
}


Para mais informações sobre Colisão:
Collision Reference