There is no enableInitCallback in AS 3. How do I automatically send MovieClips to UnrealScript?

In order for UnrealScript to get a reference to a MovieClip automatically, that MovieClip has to have enableInitCallback = true. I’ve been looking for that property unsuccessfully and now I can see from Help that enableInitCallback is no longer an inspectable in ActionScript 3. Now, according to that page, “it should be set within a class’s constructor or preInitialize() method.”

OK, so maybe I can make an AS class that sets enableInitCallback in the constructor. That might be a pain for everything I might possibly want to add to the scene, but whatever. But then when I go look at the ActionScript reference pages for UIComponent and MovieClip, I see that enableInitCallback just doesn’t exist at all.

So how do I make new MovieClips in an ActionScript 3 movie register themselves with UnrealScript?

You need to add the following to your UI component:

override protected function configUI():void {	
    super.configUI();
    enableInitCallback = true;//Allows this widget to notify unrealscript when it has been created (which gets picked up in WidgetInitialized()).
}

Then (once added to the stage) it will trigger the following event on it’s parent MC or GfxMoviePlayer:

event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
1 Like

Thank you so much. I made my custom widget extend UIComponent instead of MovieClip (I thought MovieClip was a child of UIComponent, but actually it’s the other way around), I added your code to the .as file, and I am now able to get this widget initialized in UScript when I create it in ActionScript. Unfortunately though, I have a new problem. I hope you don’t mind considering this one too:

When I add my custom class directly into the scene, I can see it, but it doesn’t initialize in UScript.

When I create an instance of my custom class in ActionScript, it does initialize in UScript, but I can’t see it.

Have you ever had that problem? Any idea how to make UIComponents visible?

// This is going to be my mouse cursor. I can't see it in the scene when I create it, but I can log it in WidgetInitialized.
var mCursor:MCursor = new MCursor();
addChild(mCursor);

// This makes a gray box and plops it down at 400, 400.  I can see this just fine.
var testSymbol:MovieClip = new TestSymbol();
addChild(testSymbol);
testSymbol.x = 400;
testSymbol.y = 400;

// I also tried creating a cursor as UIComponent instead of the custom child class MCursor. Still can't see it.
var mCursor2:UIComponent = new MCursor();
addChild(mCursor2);
mCursor2.x = 200;
mCursor2.y = 200;
mCursor2.visible = true;

You need to assign the MC a name before adding it to the stage. This is so you can identify it when WidgetInitialized() gets called and you can bind it to the correct US class.

So in AS3:

var mCursor:MCursor = new MCursor();
mCursor.name = "MyCursor";
addChild(mCursor);

Then in US (in the parent’s US object/class):

//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// Callback when a CLIK widget with enableInitCallback set to TRUE is initialized.  
// Returns TRUE if the widget was handled, FALSE if not. 
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
{    
	local bool bResult;
	bResult = false;

    switch(WidgetName)
    {
    	case ('YourMCName'):
            if (Nav == none) {
                Nav = ColdMainMenuGfx_Nav(Widget);
                ConfigureWidget(Nav, WidgetName, WidgetPath);             
                bResult = true;
            }            
            break;
       
        default:
            break;
    }

    return bResult;
}

//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
//Configures a view widget. Called from WidgetInitialized() as each widget is created.
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
final function ConfigureWidget(GFxObject InView, name WidgetName, name WidgetPath)
{	
    SetWidgetPathBinding(InView, WidgetPath);
    InView.ViewName = WidgetName;//optional
    InView.OnViewLoaded();//optional
}

...
defaultproperties
{    
WidgetBindings.Add((WidgetName="YourMCName",WidgetClass=class'ColdMainMenuGfx_Nav'));
}

And if your parent class is already a child of another class, use this in your default props instead:

defaultproperties
{
SubWidgetBindings.Add((WidgetName="WeaponsPanel",WidgetClass=class'ColdHudServerStatsGfx_WeaponsPanel'))
}

Setting up your US gfx classes like this is the key to truly breaking down your frontend classes into manageable code. That, as well as binding US delegates to AS function calls in US:

delegate RequestPlayerHuntingStatsDelegate();
function SetRequestPlayerHuntingStatsDelegate(delegate< RequestPlayerHuntingStatsDelegate> d) { ActionScriptSetFunction("US_RequestPlayerHuntingStats"); }

function RequestPlayerHuntingStats()
{
    //your code
}

So you can then call US from your AS3 UIComponent using:

if (this.US_RequestPlayerHuntingStats != null) {
     this.US_RequestPlayerHuntingStats();
}

After the widget has ran the WidgetInitializedfunction it will run this function next

      event PostWidgetInit()
      {
        // `log("PBGFxMPLoadingScreen::PostWidgetInit() Were starting the Loading Screen movie"); 
        super.PostWidgetInit(); 
     }

Then in your default properties you can store your movies you’ve made so you can access and use them when you need to.

Example:

    var array<SwfMovie> OurMovies; top of file
   DefaultProperties 
  { 
     OurMovies[0] = SwfMovie'UDKFrontEnd.udk_loading' //PATH TO YOUR MOVIE IN YOUR PAK.
     OurMovies[1] = SwfMovie'UDKFrontEnd.Compound'   //PATH TO YOUR MOVIE IN YOUR PAK.
     OurMovies[2] = SwfMovie'UDKFrontEnd.Compound2' //PATH TO YOUR MOVIE IN YOUR PAK.
     //SO ON.......
  }

Tip: Also when you name the widgets in action script when making the actual page make sure the WidgetName is all lower case or it will not read it in udk script. Example below when it is looking for that name to intialize it. Hope this makes sense. Was a problem we ran into.

    if( WidgetName == 'loadss' )//name of button in the flash menu must be lowercase to be found in 
       script.

Thank you @ and . I’m now able to get my mCursor initialized in UnrealScript just fine. The problem that I’m having now is that it is not visible on the screen.

If I drag and drop an MCursor from my library into the scene, I can see it, but it doesn’t initialize in UScript. If I create it in code with var mCursor:MCursor = new MCursor();, it initializes in UnrealScript, but I can’t see it.

I know the mouse cursor is getting created because I can log it in WidgetInitialized. I know that the mouse cursor is moving because I have a deproject in my HUD.PostRender that lets me interact with things when I move my mouse over them. So I know it got created and I know it’s moving. I just can’t see the cursor.

Any idea why I can’t see it? Any idea how I can make it visible?

Let me see if i can see how ours was did. If i can find it i will reply back, If i remeber right ours was done in the action script page in the code section, where you can add code to the action script page.

1 Like

I’m not sure why it’s not showing. Perhaps it’s movie is set to hidden?

Regarding using flash to display your mouse cursor. Have you considered using the hardware cursor instead? I used to use flash for my mouse cursor, but then it runs at the fps of your flash movie and always seems to be delayed and feel sluggish.

Try this to toggle the hardware mouse cursor (which will be as responsive as using Windows):

//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
//Turns the hardware mouse on and off.
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
simulated function ToggleMouse(bool bShow)
{
    LocalPlayer(GetALocalPlayerController().Player).ViewportClient.SetHardwareMouseCursorVisibility(bShow);
}
1 Like

@ I’m mostly doing this as an exercise before trying to make something much more complicated, loaded dynamically into the GFxMovie. I too noticed that the Flash cursor was lagging slightly behind the OS cursor when I tested it in Animate. And even worse, the deprojection lags slightly behind that. I’ll look into the hardware cursor. Thanks for the suggestion. But I’ll still keep investigating this problem.

Edit: Also, it’s visible, it has height and width… This is really strange. Whether we fix this right away or not, I’m still really thankful that you took the time to look and to respond. You guys are the best.

I think that’s what we did . I remember when they made the action script one it was laggy and sluggish. Then they changed it around and it was fast and responsive, We must have did what your saying.

Maybe start by just testing a simple movie clip (just a black square). Add it to the stage via AS3. See if you see it in game.

Then give it a class extended from UIComponent and add enableInitCallback = true (and give it a name) and see if triggers your WidgetInitialized in US (and that it is still visible).

Sounds like the problem is specifically related to the implementation of your mouse cursor.

1 Like

idea, are you putting everything on one layer in as? if so put the mouse on a different layer and retry that. We had problems with to many things on 1 layer and had to put stuff on different layers to get them to show up.

Edit: Here is some code that you can modify to use to have the player controller open a menu by a button push. PBGFxAdminMenu extends WPGFxMoviePlayer; WHICH EXTENDS GFxMoviePlayer

  var PBGFxAdminMenu AdminMenu;//at top of file


  exec function StartAdminMenu() //button push from input file
  { 
     if(bStoreGame || bIsInEndOfMap) return; 
     // `log("PlayerReplicationInfo.bAdmin = "$PlayerReplicationInfo.bAdmin); 
     if (PlayerReplicationInfo.bAdmin) 
     { 
        StartTheAdminMenu(); 
     }
  } 

 simulated reliable client function StartTheAdminMenu() 
 { 
     bIsInAdminMenu = false;

     if ( AdminMenu == none )
          AdminMenu = new class'PBGFxAdminMenu'; 

     AdminMenu.PlayerOwner = self; 
     AdminMenu.bAutoPlay = true; 
     AdminMenu.Init(LocalPlayer(self.Player)); 
     bIsInAdminMenu = true; 
 } 

simulated reliable client function StopAdminMenu() 
{
       AdminMenu.RenderTexture = None; 
       AdminMenu.Close(false);
       bIsInAdminMenu = false; 
       AdminMenu = none; 
}

That will open and close a menu for you once its set to your menu.

1 Like

Well, I think I figured it out. I started off simplifying it as much as possible and moving from there. I hadn’t mentioned that I had imported the symbol from a resource-sharing movie I had made. That turned out to be the key complication. So it seems these are my options:

  1. Import as a shared resource, place it directly into the scene. You can see it, but you can’t initialize it in UScript.
  2. Import as a shared resource, create it in AScript. It initializes in UScript, but you can’t see it.
  3. Create the symbol only in the movie you want to use it in, create it in AScript. You can see it, and it initializes in UScript. You just can’t share it with other files.

Thanks for your help guys.

Here is a function to close the menu with same button that you opened it with. figured you might need that down the road if using the button activated menu.

event bool FilterButtonInput(int ControllerId, name ButtonName, EInputEvent InputEvent)
{ 
   local bool WasButtonPressed; 
   local PBPlayerController PC; 
   local string WhatKey, WhatKey2; 
   local PBPlayerInput PBPI; 

     PC = PBPlayerController(Playerowner); 
     PBPI = PBPlayerInput(PC.PlayerInput); 
    WasButtonPressed = false;
     WhatKey = PBPI.GetUDKBindKeyFromBindName("GBA_StartAdminMenu"); 
     WhatKey2 = PBPI.GetUDKBindKeyFromBindName("GBA_ShowMenu"); 

    if((ButtonName == name(WhatKey) || ButtonName == name(WhatKey2)) && (InputEvent == IE_Pressed)) 
    { 
        WasButtonPressed = true; 
        PC.StopAdminMenu(); 
    } 
    //`log("PBGFxTeamMenu::FilterButtonInput() WasIPressed = "$WasIPressed); 
    return WasButtonPressed;
}
1 Like