Announcement

Collapse
No announcement yet.

Capturing Keyboard Input in Kismet

Collapse
This is a sticky topic.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Capturing Keyboard Input in Kismet

    This tutorial explains how to capture keyboard input via Kismet, thus allowing a GFx movie to use that captured input to do something, without needing to write any UnrealScript at all!

    NOTE: This tutorial was written using the November 2010 UDK build. However, it was last confirmed working in May 2011 UDK

    Possible Use Case: A GFx movie in the level that you want the player to be able to interact with when he walks up to it, such as a computer console.

    Step 1 - Setup

    Create a simple red square in the middle of the stage of a new Flash file. Convert the square to a movie clip, and give it an instance name of 'myGraphic' in the properties panel. Save the Flash file in the proper location of your UDK install. (See: Importing SWFs into UDK)

    Step 2 - ActionScript

    Put this code on a new layer called 'actions' on frame 1 of your Flash file:

    ActionScript 2.0 Code

    Code:
    _global.gfxExtensions = true;
    _perspfov = 25; // Used in 3D transformations. Can be any value from 1 to 179.
    
    var keyboardInput:Object = new Object(); // creates a new object to hold keyboard input.
    Key.addListener(keyboardInput); // uses the object to listen for keyboard input.
    
    /* when a key is pressed, execute this function. */
    keyboardInput.onKeyDown = function() 
    {
        /* store the keyboard input ASCII code inside 'keyPressed'. */
        var keyPressed:Number = Key.getCode();
     
        /* if LEFT ARROW was pressed... */
        if (keyPressed == 37) 
        { 
            /* rotate the movie clip by +5 degrees. */
            myGraphic._yrotation += 5; 
        }
        /* if RIGHT ARROW was pressed... */
        else if (keyPressed == 39) 
        { 
            /* rotate the movie clip by -5 degrees. */
    	myGraphic._yrotation -= 5;
        }
    }

    NOTE: Scaleform does not currently support getAscii(). Instead, be sure to use getCode().


    Save and Publish the movie.

    Step 3 - UDK Initial Setup

    In UDK, create a simple test level. One room with a light and a player start should do. Then do the following:
    1. Create a BSP cube inside the room somewhere. We'll display the GFx movie on one face of this cube.
    2. Add a Trigger right in front of one of the faces of the cube.
    3. Now, import the SWF file into the Content Browser.
    4. Create a new TextureRenderTarget2D in the same package as the newly imported SWF. Name it 'myRT'.
    5. Create a new Material in the same package. Name it 'myMat'.
    6. Add a new TextureSample in the Material Editor window.
    7. Attach the black (RGB) output of the Texture Sample to the Diffuse input of the Material, and the white (alpha channel) output to the Opacity input of the Material.
    8. Select the Material and set the Blend Mode to BLEND_AlphaComposite in the Material drop down.
    9. Leave the Material Editor open, and go back into the Content Browser and select 'myRT'.
    10. Back in the Material Editor, select the Texture Sample, then insert 'myRT' into the Texture field with the green arrow.
    11. Close the Material Editor window and save changes.
    12. Save the package that contains the SWF file, render texture, and material.
    13. Select a face of the BSP cube, preferably the one next to the Trigger, and with 'myMat' selected in the Content Browser, right click, then choose: Apply Material : myMat.
    14. Build all and save the level.


    Step 4 - Kismet Setup

    Open Kismet and do the following:
    1. Add a Level Loaded event.
    2. Add an Open GFx Movie action.
    3. Connect Loaded and Visible to In on Open GFx Movie.
    4. Create a new Object Variable and attach it to the Movie Player output of Open GFx Movie.
    5. Select Open GFx Movie, and insert the SWF from the Content Browser in the Movie field.
    6. Insert 'myRT' from the Content Browser in the Render Texture field.
    7. Set the Render Texture Mode to RTM_AlphaComposite.
    8. Now, select the Trigger in the level, then right click in Kismet and select: New Event Using Trigger_x -> Touch.
    9. In the new Trigger node's Sequence Event drop down, set the Max Trigger Count to 0.
    10. Add a new Set GFx Captured Keys action.
    11. Connect the Movie Player input to the Object Variable you created above in Step 4.
    12. Connect the Touched output of the Trigger node to the Activate input of the Captured Keys node, then connect the UnTouched output to the DeActivated input.
    13. Select the Captured Keys node, and add two Capture Keys using the green plus icon.
    14. Set [0] to Left and set [1] to Right.


    Save the level, then play in editor.

    You should be able to walk up to the GFx movie, which shows a red square, then use the Left Arrow and Right Arrow keys of your keyboard to alter its rotation in 3D space. Walking away from the movie will release the Left and Right arrow keys.

    You could just as easily put the material 'myMat' on a static mesh instead of a BSP.

    #2
    just tried it, works perfectly though it's kind of weird by the fact my flash file is ugly \0/

    anyways, thanks for the tut

    Comment


      #3
      I can't afford Adobe Flash Pro, so I tried your code using a program called Sothink SWF Quicker.

      Unfortunately, it caused a syntax error.

      Here's my screenshot:
      http://imageshack.us/f/706/swferror.jpg/

      I made the following changes and it does now compile:

      // Sothink SWF Quicker Actionscript test

      import flash.external.ExternalInterface;
      _global.gfxExtensions = true;

      var keyboardInput:Object = new Object();
      Key.addListener(keyboardInput);

      function rotAction()
      {
      var keyPressed:Number = Key.getCode(); //store input

      if (keyPressed == 89) //if the key pressed was 'Y'
      {
      testGraphic._yrotation += 5; //rotate the graphic element
      }
      else if (keyPressed == 85) //if the key pressed was 'U'
      {
      testGraphic._yrotation -= 5;
      }
      }

      keyboardInput.onKeyDown = rotAction;
      testGraphic.focusEnabled = true;

      Comment


        #4
        Not working for me.

        I have the 2011 April version if that's any different :S

        Somehow it won't receive any input and it won't rotate. I followed all the steps properly and the code exactly. Any ideas?

        I also checked to see if the code wasn't right so I copied the mouse rotation code from the Inventory example and that didn't work either. Is it something else?

        Comment


          #5
          Just tested it in May 2011 UDK - works perfectly.

          Comment


            #6
            For those who want to access keyboard events in Kismet without dealing with UnrealScript or Scaleform:

            Here's how I accessed keyboard input thru Kismet. This example is the spacebar...

            Edit DefaultInput.ini -- make sure your changes are in the "Game Keyboard/Mouse Bindings" section, then change from this:
            .Bindings=(Name="SpaceBar",Command="GBA_Jump")
            to this:
            .Bindings=(Name="SpaceBar",Command="GBA_Jump | CauseEvent Jump | OnRelease CauseEvent JumpStop")

            Shut down & restart UDK Editor if you had it open to re-read the ini file we just edited. Open Kismet and add two console events. In one console event set Console Event Name to Jump, and in the other set Console Event Name to JumpStop.

            That allowed keyboard presses and releases to trigger Kismet via console events...

            Comment


              #7
              Matt Doyle,

              Please, I want, from a flash movie, can type a name for my player. Example: I type my nick in a input text box and when I hit ENTER the game begins with my nick instead of "player 236".
              How I do it?

              Thanks.

              Comment


                #8
                I just started trying Scaleform with the May 2012 UDK version, and this doesn't seem to work for me. Is it known to still work? I see the commands, I'm even receiving the commands.

                Here is my ActionScript, which should be about the same. I am GETTING those fscommands, but the rotation isn't happening.

                The image is "facehugger.png", the movie's name is default, and the InstanceName of the movie is "facehuggerImage". It is my understanding that this should be working, yet I am seeing no rotation.

                Code:
                _global.gfxExtansions = true;
                _perspfov = 25;
                
                var keyboardInput:Object = new Object();
                Key.addListener(keyboardInput);
                
                keyboardInput.onKeyDown = function() {
                	var keyPressed:Number = Key.getCode();
                	
                	if (keyPressed == 89) {
                		facehuggerImage._yrotation += 5;
                		fscommand("test");
                	} else if (keyPressed == 85) {
                		facehuggerImage._yrotation -= 5;
                		fscommand("test");
                	}
                }

                Comment


                  #9
                  The first problem I see is that you have misspelled extensions in the first line. It should read:

                  Code:
                  _global.gfxExtensions = true;

                  Comment


                    #10
                    Originally posted by Matt Doyle View Post
                    The first problem I see is that you have misspelled extensions in the first line. It should read:

                    Code:
                    _global.gfxExtensions = true;
                    Yes, yes... of course I would do that...

                    Thank you. That fixed it.

                    [bows head in shame]

                    Comment


                      #11
                      No problem sir. Typos and syntax errors are the most common type of programming error. No need to be shamed.

                      Comment


                        #12
                        Thanks for the help, im going to be using this later to do it myself, much appreciated!

                        Comment


                          #13
                          Hi there, as my posts counter says, I'm really new here (as I am to UDK development in general)

                          I'm currently using the November 2012 (DX11 renderer) release and, while I followed step-by-step both this written guide and the video one (multiple times), I'm experiencing the same problem.

                          While I get the texture correctly applied to the BSP face, I can't get it to move as the ActionScript should tell it to do. I'm using the very same lines of code posted here with the very same "linkage names" suggested.

                          Sure is that the game knows that it has to take the player's input since, when I'm touching the trigger and I click left and right arrow keys, it doesn't move the camera left\right as it would normally do.

                          Has something changed, in this process, during the latest UDK releases?

                          ------------------

                          Ok, my fault
                          It seems that I had set the name and the linkage for the 'myGraphic' Movie Clip, but NOT the Instance Name. Now it's working. It does not rotate on its "central axis" but at least it rotates

                          Comment


                            #14
                            Considering that this is a very helpful thread and it's stickied, I'd like to add the AS3 translation for his little red block!

                            Code:
                            /*Create the Listener that waits for keyboard Input,
                            then tell it what function to call when a key
                            is pressed down*/
                            stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
                            stage.focus=stage;
                            //What happens when a key is pressed!
                            function KeyDownHandler(keyEvent:KeyboardEvent)
                            {
                            	/*Convenient Switch statement allows for
                            	quicker key presses.  All you need is
                            	to use the correct Key Code!*/
                            	switch(keyEvent.keyCode)
                            	{
                            		case 37 :// Left Arrow was Pressed
                            			myGraphic.rotation += 5;
                            		break;
                            		case 39 :// Right Arrow was Pressed
                            			myGraphic.rotation -= 5;
                            		break;
                            	}
                            }

                            Comment

                            Working...
                            X