| Home Page | Recent Changes | Preferences

Daemonica/Previous Problems

Previous Problems

I'm considering these problems resolved now :)

Menu Music

How to change the music that plays when the GUIPage Main Menu is shown.

Tarquin: If you've resolved this, could you write up the results on GUIPage please? The same goes for other things: please incorporate results into the main body of the wiki :)

Daemonica: Good point, these has been added to GUIPage hopefully clear enough, any suggestions where the tracing information should go? Probably somewhere near the trace function I suspect?

Why am I working on this problem

Because of [The Undying Curse] which is now a UT2003 Mod, playing the default KR-UT2003-Menu music just doesn't have the right feel.

Foxpaw: This might be a bit tricky to explain, depending on how well you understand the Unreal Engine, but here's the skinny:

There is always at least one, and at most two levels loaded in any given instance of an Unreal Engine game. The first level is generally referred to as the "Entry" level. The second level is the one that you generally play in, and is the one that is changed by the servertravel and start console commands.

The Entry level is loaded when the Engine starts, and cannot change to a different level or be unloaded in any way. (That's not entirely true, but generally speaking..) You can still play in it, it is a level in every respect, but generally for performance reasons (since it's going to be running at the same time as the map you're playing on) it is generally just a subtracted cube without any bells and whistles in it.

Now, one level or the other is "screened out" depending on the context. If the "active" level is the entry level, your input will go to your controller in that level, etc. It's almost like having a completely separate instance of the game, but it isn't really.

Now, how this relates to your question: when you first start UT2003, the "Entry" level is loaded. The music you hear during the menu, is actually just the level's music. When the context switches to another level, you no longer hear sounds from the "entry" level and start hearing them from the other level.

So: to change the menu music you have to change the entry level. The entry level for UT2003 is in your maps directory, and is called Entry.UT2. Make a copy of it, and name it whatever you like, then open it and change the map's music. Then you'll have to make a copy of UT2003.ini, and in it change the reference to Entry.UT2 to your map. (it might just be entry, I don't remember if the UT2 gets appended automatically or not) You will then have to run UT2003 with a commandline parameter to read your modified ini instead of the default UT2003.ini. Most mods that do this also include a batch file so that you don't have to manually specify the command line argument.

Daid303: Well, I tried to change the entry level, but I didn't have any luck. It just kept using the default Entry.ut2. So I made this crappy hack:

function InitComponent(GUIController MyController, GUIComponent MyOwner)
{
    Super.InitComponent(MyController, MyOwner);
    //Hack
    Controller.ViewPortOwner.Actor.GetEntryLevel().Song = "UMS_Main_Menu_Music";
}

in my mainmenu class.

Foxpaw: Hmm, it works fine on my mod. I use the "Entry" level as the workshop where you design your vehicles. That way you can very quickly switch back and forth between the combat simulator and the design level. It seems to have worked fine for me.

Daemonica: I encountered the same problems as Daid303, My own copy of Entry.UT2 (Entry-TUC.UT2) was totally ignored, the hack however worked a treat. The only entry in UT2003.ini that refers to Entry.UT2 is NetBrowseMap=Entry.ut2, but didn't make squat 'o' difference :( Thanks to you both. I'm happy this solution works

Foxpaw: Whoops! You're right. :P UT2003 has a separate entry level for network and local games. (not sure why) LocalMap is the local one. Unfortunately, that contains a call to start up the menu so you can't really replace it as easily. I'd say, continue using the hack method above. Alternatively, write your own GUI from scratch using Interactions like I did.. then you can replace the entry level without worrying. :D

Daemonica: Can I not and just pretend I did ;), besides the Hack works well, and I _really_ don't have the time to write a GUI from scratch. I'm _reasonably_ happy with the current implementation of menus but looking forward to the improvements from UT2004

GRAF1K: Can you say "UWindows returns" – or, more to the point – "YIPEE!"? ;-):D

Daemonica: YIPEE! :)

Ian Pilipski: There is a solution, you have to create your own Entry.ut2 map and save it in your mod path maps directory (with the name Entry.ut2). Then add your map path for your mod in your .ini file. I would recommend creating your own copy of the UT2003.ini file to something like MyModUT2003.ini. Then launch ut2003 with this command line switch UT2003.exe -ini=MyModUT2003.ini. The ini entry should look something like this:

[Core.System]
...
...
Paths=../MyMod/Maps/*.ut2
Paths=../Maps/*.ut2
Paths= ...
...
...

Now when you run your mod, it will use your Entry.ut2 file as the entry level because it finds it first when searching the paths. Using this method can also allow you to do interesting things on the menu screens. If you set the menu backgrounds to none, then you will actually see the Entry.ut2 level in play. You can add some Matinee scene in there and you now have a very interesting menu system. As Foxpaw points out, if this level is always loaded during game play, you should not overload it by making it too complex. That would affect the performance of your mod.

Useable Actors

How do I check to see if an Actor is useable (i.e. It has a function UsedBy(Pawn User))

Why am I working on this problem

I need a way of highlighting useable actors on the HUD, however there is now bUseable variable, defined in Actor (or something similar). The reason I need to check this is that these usable items include pickups, triggers & decorations!

Foxpaw: I don't believe that there is any way to check if it "has" the UsedBy function, because every actor has it. (I think) What you CAN do, however, is have every "useable" think spawn an invisible "tag" that points to that object. Then, when you want to highlight the actors that are "useable," you can iterate through all of your "tags" and you will essentially have a list of all the things that should be highlighted.

Daemonica: Foxpaw comes to the rescue again :) Thanks. I'm asuming then somewhere in the PostBeginPlay() function I would Spawn this TagActor, then I can do an Other.IsA('TagActor') to varify useable items? Now I'm trying to get trace to actually return the object I'm looking at and not just the world!

// Called from a HUD to determine if the player is looking at a hostile, useable item
//etc, so the crosshair colour can be changed :)
function string PlayerLookingAt()
{
    local vector HitLocation,HitNormal,StartTrace,EndTrace;
    local actor Other;

    StartTrace = Pawn.Location;
    StartTrace.Z += Pawn.BaseEyeHeight;
    EndTrace = StartTrace + vector(Pawn.GetViewRotation()) * 1000.0;

    Other=Pawn.Trace(HitLocation, HitNormal, EndTrace, StartTrace, True);
    if ( Other != none )
    {
        // Assumes that all useable items have spawned a UseableItem actor :)
        if ( Other.IsA('UseableItem') )
            return("Useable");
        else
            return("Hostile");
    }
    else
        return "None";
}

Foxpaw: Well, the implementation would depend on what exactly you had in mind. If you wanted the crosshair to respond to things underneath it, the code would be something like the following:

simulated function string PlayerLookingAt()
{
  local vector HitLocation,HitNormal,StartTrace,EndTrace;
  local actor Other;

  StartTrace = Pawn.Location;
  StartTrace.Z += Pawn.BaseEyeHeight;
  EndTrace = StartTrace + vector(Pawn.GetViewRotation()) * 1000.0;

  Other = Pawn.Trace(HitLocation, HitNormal, EndTrace, StartTrace, True);
  if ( Other != none )
  {
    if ( IsUseable( Other ) )
      return("Useable");
    else
      return("Hostile");
  }
  else
    return "None";
}

simulated function bool IsUseable( actor A )
{
  local UseableTag Tag;

  foreach AllObjects(class'UseableTag', Tag)
    if ( Tag.Actor == A )
      return true;

  return false;
}

That is of course a logical implementation, certainately not the fastest implementation. To speed it up you could make the UseableTags actors with bHidden true, then use DynamicActors instead of AllObjects. (would be much faster, not sure if you can do that in a HUD though anyway.) Even better, you could keep a list of all the UseableTags in the HUD, and just have every useabletag register itself with the HUD when it is created.

However, if you're going to do that (I'm kind of on a roll now :D) you might as well scrap the useabletags and just have the HUD keep a dynamic array pointing to all useable things, and then just iterate through that. Then when an actor wants to register itself as useable, it can find the HUD fairly easily by calling Level.GetLocalPlayerController().myHUD.. or something like that anyway. However, this method might not replicate very well because not only can you not replicate a dynamic array, but even if you worked around it you might constantly be adding and removing things as they become relevant or irrelevant.. so maybe just stick with the DynamicActors iterator for that reason.

Daemonica:You really went for it there :), I seem to have run into a bug at the moment, the trace is only colliding the world and not any actors, at all, ever. I think I've got my head round the implementation, if only there was a nifty bool bIsUsable back in actor this would be soooo much easier ;)

Foxpaw: Hmm, well, my first thought would be that the trace is not set to collide with actors. There's a bool in the trace function, bTraceActors, that sets it to do this. In both the code examples above it's set to true, but I would check to see if you accidentally omitted that in your code because that's what would normally cause that sort of behaviour.

Daemonica: Yup, that's what I thought, but the trace is acurate, it just don't like returning any actors :( The LookingAt() function now returns the actor the player is looking at (in theory) with the following definition

function actor PlayerLookingAt()
{
    local vector HitLocation,HitNormal,StartTrace,EndTrace;
    local actor Other;

    StartTrace = Pawn.Location + Pawn.EyePosition();
    EndTrace = StartTrace + vector(Pawn.GetViewRotation()) * 1000.0;

    Other=Pawn.Trace(HitLocation, HitNormal, EndTrace, StartTrace, true);
    if ( Other != none && !Other.bWorldGeometry )
       return Other;
    else
       return none;
}

This is defined in TUCPlayer (extends PlayerController) so as far as I can see it should work. It hits Static meshes correctly so I know the vectors for the trace are correct, it just needs to hit actors now!

Daemonica: And a little more work reveals that if the object I'm LookingAt() has bBlockPlayers set to True then the trace works, otherwise it fails, this to me is not usefull as I want know what actor I am looking at, even if this doesn't block the player (as most pickups won't actually block a player)..... which can be done by setting bProjTarget = True for those actors ;) Finally it works, but only because I'm working on a TC, I would hate to try and do this for mutators/etc. You would have to use ForEach type things as mentioned above (Eeeky, that's just nasty!)

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Image Uploads

Random Page

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

Mapping Topics

Mapping Lessons

UnrealEd Interface

Questions&Answers

Scripting Topics

Scripting Lessons

Making Mods

Class Tree

Questions&Answers

Modeling Topics

Questions&Answers

Log In