A random sentence for a random mind.

How are 1st person weapons done?

For questions and discussion about UnrealEd, UnrealScript, and other aspects of Unreal Engine design.

Moderators: ividyon, Semfry, zYnthetic

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: How are 1st person weapons done?

Post Posted: 25 Aug 2016, 17:36

I'm trying to locate a script example that does two things: 1) attach a mesh to the camera 2) set only owner see. 1p weapons do exactly that but unless I'm reading what i can find wrong, the only script example I can find only involves drawing the hud icons (drawing to canvas in weapon.uc). I thought it would be the same class responsibe for calculating weaponoffset but I can't seem to find anything there either. Is it a native function that I can use or did I miss a significant portion of uscript somewhere?
Image

User avatar Buff Skeleton
>:E >:E
Posts: 4042
Joined: 15 Dec 2007, 00:46

Subject: Re: How are 1st person weapons done?

Post Posted: 26 Aug 2016, 03:18

I'm not sure off the top of my head, but it seems like it would be more easy to locate if you dumped all source files from Engine, UnrealI, and UnrealShare and stuff into a big folder, then grepped it for that kind of thing. I do that a bunch instead of hunting down classes in the class tree in UED and it's awesome.

Assuming you haven't already done exactly that, that is :X
Image

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 26 Aug 2016, 06:06

Yeah, that's what I'm doing. I'm just not sure if I'm looking for the right thing since the terms I'm using lead to dead ends. I could peg a mesh to the player location+rotation in a tick function but I've been avoiding that since I don't think the result would be as good as the system weapons use. Unless that is what they use and I just haven't found it.
Image

watcher_of_the_skies
Skaarj Warrior Skaarj Warrior
Posts: 60
Joined: 17 Aug 2015, 10:27

Subject: Re: How are 1st person weapons done?

Post Posted: 26 Aug 2016, 07:00


medor
Skaarj Assassin Skaarj Assassin
Posts: 148
Joined: 07 Jun 2009, 22:58

Subject: Re: How are 1st person weapons done?

Post Posted: 26 Aug 2016, 08:46

My translator doing may be acting up and I am not coder.

There is weapons with camera.
here one i have other if this help you http://unrealtournament.99.free.fr/utfi ... archMode=f

Image

User avatar []KAOS[]Casey
Skaarj Berserker Skaarj Berserker
Posts: 425
Joined: 25 Sep 2008, 07:25

Subject: Re: How are 1st person weapons done?

Post Posted: 26 Aug 2016, 19:39

Check defaultproperties in display of a weapon. there are several meshes. one is first person, one is third person, and one is "held" i.e. what you see the player holding in their weapon triangle.

edit: also note the draw offsets/scale. Those are important too. Weapons do not do anything special to render really. If I remember right, a decent portion of this is in native code land.

Z-enzyme
White Tusk White Tusk
Posts: 2135
Joined: 13 Nov 2007, 20:01

Subject: Re: How are 1st person weapons done?

Post Posted: 28 Aug 2016, 15:36

So, first thing, only owner see - this is a native code driven by default properties of an Actor class

Code: Select all

// Advanced.
var(Advanced) bool   bOwnerNoSee;   // Everybody but the owner can see this actor.
var(Advanced) bool   bOnlyOwnerSee;   // Only owner can see this actor.


Then, there is this Inventory class where you have the ThirdPersonMesh (driven entirely by native code, can't do much about it), pickup mesh, which just changes the Display mesh when an item becomes a pickup.

Code: Select all

 // Pickup view rendering info.
var() mesh        PickupViewMesh;     // Mesh to render.
var() float       PickupViewScale;    // Mesh scale.

//
// Become a pickup.
//
function BecomePickup()
{
   if ( Physics != PHYS_Falling )
      RemoteRole    = ROLE_SimulatedProxy;
   Mesh          = PickupViewMesh;
   DrawScale     = PickupViewScale;
   bOnlyOwnerSee = false;
   bHidden       = false;
   bCarriedItem  = false;
   NetPriority   = 2;
   SetCollision( true, false, false );
}


And then there is this Player View Mesh which you are interested in.

Code: Select all

// Player view rendering info.
var() vector      PlayerViewOffset;   // Offset from view center.
var() mesh        PlayerViewMesh;     // Mesh to render.
var() float       PlayerViewScale;    // Mesh scale.
var() float        BobDamping;        // how much to damp view bob

//
// Become an inventory item.
//
function BecomeItem()
{
   RemoteRole    = ROLE_DumbProxy;
   Mesh          = PlayerViewMesh;
   DrawScale     = PlayerViewScale;
   bOnlyOwnerSee = true;
   bHidden       = true;
   bCarriedItem  = true;
   NetPriority   = 2;
   SetCollision( false, false, false );
   SetPhysics(PHYS_None);
   SetTimer(0.0,False);
   AmbientGlow = 0;
}


But this makes the item totally hidden, this is an inventory item, no mesh viewing from the viewport. Inventory items don't really have PlayerViewMesh. As it comes to drawing the weapon mesh I haven't found any code in UScript. So - probably native. BUT! There is this Enforcer from UT. It draws 2 meshes. Why won't we look there? (I'm typing and looking at the same time, so, yea, kind of adventure really :P)

Code: Select all

function bool HandlePickupQuery( inventory Item )
{
   local Pawn P;
   local Inventory Copy;

   if ( (Item.class == class) && (SlaveEnforcer == None) )
   {
      P = Pawn(Owner);
      // spawn a double
      Copy = Spawn(class, P);
      Copy.BecomeItem();
      ItemName = DoubleName;
      SlaveEnforcer = Enforcer(Copy);
      SetTwoHands();
      AIRating = 0.4;
      SlaveEnforcer.SetUpSlave( Pawn(Owner).Weapon == self );
      SlaveEnforcer.SetDisplayProperties(Style, Texture, bUnlit, bMeshEnviromap);
      SetTwoHands();
      P.ReceiveLocalizedMessage( class'PickupMessagePlus', 0, None, None, Self.Class );
      Item.PlaySound(Item.PickupSound);
      if (Level.Game.LocalLog != None)
         Level.Game.LocalLog.LogPickup(Item, Pawn(Owner));
      if (Level.Game.WorldLog != None)
         Level.Game.WorldLog.LogPickup(Item, Pawn(Owner));
      Item.SetRespawn();
      return true;
   }
   return Super.HandlePickupQuery(Item);
}

function SetUpSlave(bool bBringUp)
{
   bIsSlave = true;
   ItemName = DoubleName;
   GiveAmmo(Pawn(Owner));
   AmbientGlow = 0;
   if ( bBringUp )
      BringUp();
   else
      GotoState('Idle2');
}


Well, it seems that UT "copies" the Enforcer, and player is actually holding 2 guns, one is driven by the other enforcer. Well, that sucks really. But, don't be afraid, there is something...

So, after 5 minutes search I've found that these two:

Code: Select all

simulated function PreRender( canvas Canvas );
simulated function PostRender( canvas Canvas );

in Weapon class render the weapon and the crosshair. They are called UnrealHUD

Code: Select all

simulated function PreRender( canvas Canvas )
{
   if (PlayerPawn(Owner).Weapon != None)
      PlayerPawn(Owner).Weapon.PreRender(Canvas);
}


But there is a function in Canvas for rendering meshes. I just don't really remember it.
The Pawn however is calling the overlay render for muzzle flashes.

Code: Select all

simulated event RenderOverlays( canvas Canvas )
{
   local rotator NewRot;
   local bool bPlayerOwner;
   local int Hand;
   local PlayerPawn PlayerOwner;

   if ( bHideWeapon || (Owner == None) )
      return;

   PlayerOwner = PlayerPawn(Owner);
   if ( PlayerOwner != None )
   {
      bPlayerOwner = true;
      Hand = PlayerOwner.Handedness;
   }

   if (  (Level.NetMode == NM_Client) && bPlayerOwner && (Hand == 2) )
   {
      bHideWeapon = true;
      return;
   }

   if ( !bPlayerOwner || (PlayerOwner.Player == None) )
      Pawn(Owner).WalkBob = vect(0,0,0);

   if ( (bMuzzleFlash > 0) && bDrawMuzzleFlash && Level.bHighDetailMode && (MFTexture != None) )
   {
      MuzzleScale = Default.MuzzleScale * Canvas.ClipX/640.0;
      if ( !bSetFlashTime )
      {
         bSetFlashTime = true;
         FlashTime = Level.TimeSeconds + FlashLength;
      }
      else if ( FlashTime < Level.TimeSeconds )
         bMuzzleFlash = 0;
      if ( bMuzzleFlash > 0 )
      {
         if ( Hand == 0 )
            Canvas.SetPos(Canvas.ClipX/2 - MuzzleScale * FlashS + Canvas.ClipX * (-0.2 * Default.FireOffset.Y * FlashO), Canvas.ClipY/2 - MuzzleScale * FlashS + Canvas.ClipY * (FlashY + FlashC));
         else
            Canvas.SetPos(Canvas.ClipX/2 - MuzzleScale * FlashS + Canvas.ClipX * (Hand * Default.FireOffset.Y * FlashO), Canvas.ClipY/2 - MuzzleScale * FlashS + Canvas.ClipY * FlashY);

         Canvas.Style = 3;
         Canvas.DrawIcon(MFTexture, MuzzleScale);
         Canvas.Style = 1;
      }
   }
   else
      bSetFlashTime = false;

   SetLocation( Owner.Location + CalcDrawOffset() );
   NewRot = Pawn(Owner).ViewRotation;

   if ( Hand == 0 )
      newRot.Roll = -2 * Default.Rotation.Roll;
   else
      newRot.Roll = Default.Rotation.Roll * Hand;

   setRotation(newRot);
   Canvas.DrawActor(self, false);
}


No playermesh anywhere I can see... Hope I helped a bit at least.


Big post, sorry for that.

Edith:

Found it - https://wiki.beyondunreal.com/Legacy:Canvas_(UT)

You probably can render meshes/actors on screen.

Code: Select all

DrawActor (Actor (UT) A, bool WireFrame, optional bool ClearZ)
Draws the actor A at its current location, whether it's actually visible or not. The actor can be drawn as wire frame or how it actually looks. ClearZ causes the actor to be drawn on top of everything else, i.e. it will be visible even if it would normally be (partially or completely) obscured by other objects.


So, the weapon might be bHidden but still rendered. It's a blind guess here.

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 29 Aug 2016, 18:36

Thanks, I'll take a look into that. I originally glossed over anything pointing to canvas since I though it was just for drawing HUD stuff but it makes sense that with the ability to draw meshes, 1p weapons would be associated with it.

ed:
Some minor progress. Seems I already assigned owner and forgot about it. All I needed was bOnlyOwnerSee=True in defaults to get that working properly.
Working on mesh based HUD notifications. I wanted to not go through all the effort of using canvas to have it still look bad. :p
Image

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 30 Aug 2016, 02:00

Admittedly I tried tying to an owner's loc/rot in tick and using setbase. They both worked to a degree but in both cases vertical rotation seems to have a limit as the mesh will stop moving along z after hitting a threshold. Time to suck it up and experiment with drawactor.
Image

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 30 Aug 2016, 18:31

Turns out DrawActor is pretty cool. I "accidentally" used it on a spawned actor and it's always visible since it's drawn on top of everything else. After I get done with this HUD stuff it could turn out to be useful for making L4D style silhouettes on non-visible players.
Image

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 31 Aug 2016, 02:09

OK, think I have it now. All based on functions in inventory/weapon.uc.
To get this to work I've got a parent class with just drawcalls in a PostRender function. This draws the actor on top of everything so it doesn't clip through stuff it hits but it only works when a RenderOverlays event is called by a child with RegisterHUDMutator running in tick. RenderOverlays also handles positioning with a little help from CalcDrawOffset to allow adjustment of the PlayerViewOffset.

Here's what I've been using this for. It's a notification icon I cooked up to go off for CoopSuite whenever a checkpoint is reached. A similar concept to Borderlands and that logo, but Unreal. Testing was six but release will be down to three pulses, which I think is enough to get the message across.

Thanks everyone for helping me chase this down.
Image

Z-enzyme
White Tusk White Tusk
Posts: 2135
Joined: 13 Nov 2007, 20:01

Subject: Re: How are 1st person weapons done?

Post Posted: 31 Aug 2016, 13:08

Huh... Cool.

User avatar Buff Skeleton
>:E >:E
Posts: 4042
Joined: 15 Dec 2007, 00:46

Subject: Re: How are 1st person weapons done?

Post Posted: 03 Sep 2016, 02:52

Nice! Ideally you could even make the num pulses configurable with an ini setting. I would probably leave it at 2, but some might want 3 or 6 of 8,192 or something. If you are feeling really saucy, add RGB value controls to change the drawcolor of the icon on the HUD since the base texture looks like it's grayscale, which is perfect for rendering color.
Image

User avatar zYnthetic
Trustee Member Trustee Member
Posts: 506
Joined: 12 Nov 2007, 00:10

Subject: Re: How are 1st person weapons done?

Post Posted: 03 Sep 2016, 06:02

Buff Skeleton wrote:Nice! Ideally you could even make the num pulses configurable with an ini setting. I would probably leave it at 2, but some might want 3 or 6 of 8,192 or something. If you are feeling really saucy, add RGB value controls to change the drawcolor of the icon on the HUD since the base texture looks like it's grayscale, which is perfect for rendering color.


Pulse count is an int so it's possible to add it to config. I'll need to check if it can be a client side option though. I haven't tried altering RGB and it being a mesh, I'm not sure if it'll work. I might provide config access to its lighting properties though, which might work.
Image

User avatar Buff Skeleton
>:E >:E
Posts: 4042
Joined: 15 Dec 2007, 00:46

Subject: Re: How are 1st person weapons done?

Post Posted: 05 Sep 2016, 19:35

Oh it's a mesh and not a texture -- derp. Yeah, that would be harder to config.
Image

Next

Who is online

Users browsing this forum: No registered users and 2 guests