Mostly Harmless

Legacy:Attaching To Bones

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

A bone is part of a skeletal mesh. The standard skeletal mesh for the pawn includes the head, right leg, left leg, right foot, left foot, right hand, left hand, right shoulder, left shoulder, and the spine. Using UnrealScript, you can attach almost anything to any bone of a given mesh.

Here, we'll discuss how you can attach actors to bones. For instance if you wanted an actor to follow a pawn around, you could attach it to a bone of that pawn. Or, if you wanted to attach emitters to the legs of a pawn, you would have to attach the emitters to both leg bones. An example of this is the Speed Combo in UT2003.

Introduction[edit]

We'll start by putting you through a very basic walkthrough. We'll spawn a custom trigger, attach it to the 'spine' of the pawn and then we will spawn Emitters and attach them to both legs. I suggest making a new package and call it AttachingToBones or something easy (see Set Up Package Folders for help with this).

Step One[edit]

First, we need to create the custom trigger. Create the following:

class SpineTrigger extends Trigger;
 
//We aren't going to make this do anything because
//this is just a walkthrough on how you can attach something to a bone
 
DefaultProperties
{
      bHidden=False //We want this false so you can see that it actually attached itself to the spine.
}

Step Two[edit]

Now we need to spawn this trigger and attach it to the pawn. The following mutator code should do this with no problem at all.

class MutAttachToBones extends Mutator;
 
var trigger BoneTrigger; //We need this variable or, it won't recognize what your trying to attach.
 
function ModifyPlayer(Pawn Other)
{
  local xPawn x;
   x = xPawn(Other);
 
  BoneTrigger = Spawn(class'SpineTrigger', x,, x.Location, x.Rotation);
  x.AttachToBone(BoneTrigger, 'spine'); //AttachToBone I believe is a native function so it can work in all actors.
                             //'spine' is the bone name.  If you wanted you could replace this with any other bone name.
}
 
DefaultProperties
{
GroupName="AttachingStuffToBone"
FriendlyName="AttachingStuffToBone"
Description="Attaching Stuff ToBone.|| This will attach the triggers and the emitters to the pawn.."
}

Step Three[edit]

Next, we will put attaching emitters into the mix. Add the following bits of code. (pulled from the SpeedCombo source)

    var xEmitter LeftTrail, RightTrail; //Put this line just under the first variable
 
    //Put these lines of code just under your BoneTrigger lines of code.
    LeftTrail = Spawn(class'SpeedTrail', x,, x.Location, x.Rotation); //SpeedTrail is already created :).
    x.AttachToBone(LeftTrail, 'lfoot'); //lfoot = Left Foot
 
    RightTrail = Spawn(class'SpeedTrail', x,, x.Location, x.Rotation);
    x.AttachToBone(RightTrail, 'rfoot');//rfoot = Right Foot

Step Four[edit]

Compile :). Your basically done now. All you have to do is create our .INT file for the mutator and the package that you put the code in. When all is well, load up UT2003. Start a match with your Mutator selected. When the match starts, go to your console and type behindview 1. Now walk around. You should see the trigger attached to your spine and the emitters attached to your feet.

Related Topics[edit]

Discussion[edit]

EricBlade: I'm attempting to attach a beam emitter to a player, which works great, using the normal bHardAttach and SetBase(), however, I wanted a little more realism for attachment, so I attached it to the player's Right Hand bone. This works great, as long as I'm not in first person view. If I'm in first person view, the emitter is invisible. Is this because the player pawn isn't drawn, while in first person? Is there a way around that?

SuperApe: You guessed it. Third-person view draws the xPawn just like you see other teammates and enemies. But, First-person view draws entirely different meshes for your weapons and turns off your xPawn. If you want your beam emitter to be on the "weapon hand", first I'd make sure you know which one it is (since you can configure it to be Right, Left, Center or Hidden in UT200x), then I'd try two things: 1) try to "piggy back" on the First-Person Weapon mesh so you automatically get it's walk/run bobbing motion, then if not that, 2) try attaching your beam emitter to the Controller instead and make your own bobbing to try and match the First-Person weapon meshes. It seems #2 would be decidedly more difficult, but it's something to try.

Xian: Not sure how it works in UE2, since UE1 doesn't have bones (well it does, but no support for it from UScript), but I for one would keep a pointer to the attachemnt then use RenderOverlays and Canvas.DrawActor();

OK this is how I'd do it in UE1, IF I had bone support:

function AttachIt (PlayerController Other) // at least I think the PalyerController is the main "player" in UE2
{
  local Actor MyAttachment; // Obviously <Actor> here would be replaced by your Object type
 
  MyAttachment = Spawn(class'Actor', Other,, Other.Location, Other.Rotation);
  Other.AttachToBone(MyAttachment,'whatever');
  Xian(Other).MyAttachment = MyAttachment;
}

Ok that'd be the basic attachment (small reference, I didn't get the point of the xPawn conversion... it's just useless code since the function is available to all Actor class... anyway...)

And this is in a your PlayerPawn (I assume it's the PlayerController in UE2):

function RenderOverlays (Canvas Canvas) // if this function doesn't exist in UE2 use PostRender
{
  if (MyAttachment != None)
     Canvas.DrawActor(MyAttachment,False);
 
  // don't forget to call the super :)
}

I'm sorry I can't give you a detailed enough example but if you worked with both engines you'll know how to port what I showed you properly. Although I doubt it's the case but if it still doesn't work try setting bHidden to False in your attachment(s) :)

SuperApe: I see the economy of this suggestion. I think it depends on the detail you'd want from this attachment. If you want it to interact with the world in 3D, as a beam emitter shooting from the arm might, a HUDOverlay may not do it.

Xian: well Canvas.DrawActor() is limited to drawing ONLY the mesh itself. However... there are ways around it. Remember the Pulse Gun from UT ? It has the beam sprite/model, the green long one. You could use that in another effect or a "fake" projectile which would have 0 damage with a bit of adjusted code. This approach might work in UE2 if you have such a firing animation/sprite/model. So what I am saying is use DrawActor() for the mesh but the firing effect or whatever it does would be a separate thing... although you could prolly use a PostRender() call in that as well if it is all just texture drawing and not real animation (where Actor->Effects classes should be used). But I think you get the idea :) Such code "hacks" are quite efficient if done properly. Engine limitations should not stop you.

EricBlade: What I ended up doing is, since I'm moving a projector and emitter and light around every tick, anyway, I just made it so that the emitter gets reset to GetBoneCoords('rhand',1).Origin as it's position, and that works just about as well :)