Monday, October 1, 2012

Cookbook: Triggering events, uscript -> kismet

Imagine you want to have a custom unrealscript actor (e.g. button). Obviously you want that button to introduce some interactivity to your scene/level. Let's say you want it to trigger some event for kismet (universal event that you want to be able to hook to any action available - play a matinee movie, toggle light, etc.)

What do we need?

1. create simple Seq_Event

All we need is a super simple event without any internal functionality. It's a good habit to organize it into some category (ObjCategory).


   1:  class SeqEvent_ButtonSet extends SequenceEvent;
   2:   
   3:  defaultproperties
   4:  {
   5:      ObjName="ButtonSet"       //kismet event name
   6:      ObjCategory="MyGame" //kismet event menu category
   7:      bPlayerOnly = false       //only pawn based actor can trigger?
   8:  }


2. trigger it from script

In our ButtonActor we need to trigger the given event somewhere. In this example it is triggered whenever touch event occurs (it'd be better to have some checks whether it's triggered by our pawn, some specific actor, etc.). To make our life easier, event is added to SupportedEvents in defaultproperties (this way it'll show in kismet right click menu when buttonActor is selected in scene).



   1:  class ButtonActor extends Actor
   2:      ClassGroup(MyGame) //group for actor classes menu (content browser)
   3:      placeable;
   4:   
   5:  ...
   6:   
   7:  //========================================================================
   8:  event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
   9:  {
  10:      //trigger event with myself as instigator
  11:      TriggerEventClass(class'SeqEvent_ButtonSet', self);
  12:  }
  13:   
  14:  ...
  15:   
  16:  defaultproperties
  17:  {  
  18:      SupportedEvents.Add(class'SeqEvent_ButtonSet') //to see it in kismet (selected actor, add event using actor...)
  19:  }

3. connect it to some kismet action

Here we need to insert an instance of our button into scene and (with button selected) in kismet right click Add event using actor -> you'll see our new event in submenu, add it! After that, all that is left is to connect it to whatever action you want. Example image shows button that plays open the door animation and turns matching color lights connected to door and button off.




5 comments:

  1. Your example uses a placeable actor. If you wanted to have an object that gets spawned by an 'Actor Factory' action (rigidbody for instance) have its own event for touch (ie, it touches some other object such as another kactor), while under physics_rigidbody mode, how can it be done, particularly so it uses its StaticMesh actor component's collision not a cylinder component?

    ReplyDelete
    Replies
    1. Hi, Tom!

      I don't have much time for some thorough research right now but I think you can connect ActorFactory "Spawned" node with "Instigator" of your kismet event (to create a connection between your dynamic, spawned actor and some event). Insert particular kismet event by simply selecting New Event -> Your Event. That event can be called similarly from Touch method.

      Anyway, you can run into problems with touch not being triggered, don't forget to try setting NoEncroachCheck property of your actor (can be done directly in uscript defaultproperties) to false

      And last but not least, you can try using bNotifyRigidBodyCollision = true and reacting on event RigidBodyCollision (PrimitiveComponent HitComponent, PrimitiveComponent OtherComponent, const out CollisionImpactData RigidCollisionData, int ContactIndex)

      Delete
  2. Great tutorial here, thanks. I'm working on a game for the Candy Jam and am using this as an excuse to learn ground up UnrealScript. (I only know some piecemeal stuff from the programmer, mostly related to HUDs, I usually work with.)

    ReplyDelete
    Replies
    1. I'm glad you like it! Good luck with your game!

      Delete
  3. How to create event with parameter (out from event in kismet).

    ReplyDelete