*All U's Have been changed to You's
Hey dudes...I figured I should finally contribute to the Tutorial Band Wagon..
Modelling and skinning
First of all you're gonna want to create your mesh and skin it...I use Maya, so the modelling part will be maya oriented...
First person mesh
Make sure you have the root joint (first joint created) right where You want the character to hold the weapon...Preferably where the finger can reach the trigger. Name this Joint b_gun_root
Create the other joints for animation, and make sure You have a joint at the barrell. One important thing for the root joint and the Barrell joint is that they must be oriented properly, or you'd have your character holding the damn thing upside down and shooting at himself (well the muzzle flash will be frakked up). You might want to look at the weapon skeletal meshes in the content browser for this...this is what I have:
Uploaded with [URL=http://imageshack.us]ImageShack.us" target="_blank">
Uploaded with [URL=http://imageshack.us]ImageShack.us" width="400" alt="This Image Was Automatically Resized by using the Screenshot Tag. Click to view the full version">
Third Person Mesh
In this case you might not need to animate the weapon so all you really need are the joints b_gun_root and the barrel Joint. Which you might want to name b_gun_Barrel.
When you are done binding your mesh to the root joint (not to mention painting weights), you might want to animate the weapon. Then it's time to export your weapons and animations (you might want to name the anim sequence something like 'WeaponFire")...
Open up actorX and export you mesh(es)
I suggest you name the 1st person version something like: Rifle_1P and the 3rd person: Rifle_3P...
Then digest your animations and name the animation sequences...
Animation with character
If you want to create your own character animations...you'd have to import the 3rd person weapon (Joints included) to the characters scene. Pose the character in the default shooting pose and then move the weapon into position...you'd want to make sure that the weapon joint "b_gun_root" is in the same position as what ever joint you want the weapon attached to (in the default epic's Rig's case, "b_rightWeapon").
After that, you select "b_gun_root", then "b_rightweapon" and then constrain them...Make sure that "maintain offset" is unchecked. Then you'd want to make sure that the characters other hand is is the correct position..When this is done, select "b_rightweapon" and set a key at 1. After this you can delete the weapon and it's joints. Then go ahead and animate your run, crouch and jump animations, while making sure that both arms are in the same relative position to each other as they where when you constrained the weapon to the character.
Then you can export your characters animation and mesh via actorx if you haven't already.
If you still have questions about this part, see the UDN website: http://udn.epicgames.com/Three/CreatingAnimations.html
Importing to UDK
GO ahead and import your Mesh(es) and Textures...If you're using maya, make sure you have the box assume maya coordinates checked. This will also be a good time to go into the skeletal mesh properties of your weapons ann make sure that the joints are akin to the unreal weapons. Then create a new animset and name it e.g "Rifle_Anims" Double click on the animset and find your mesh in the dropdown menu. Click on file and import PSA...Then import your PSA files (you know...the ones you exported via actor X? :P).
After this you want to add asocket to the Barrel joint ("b_gun_barrell")...Make sure it's named : "MussleFlashSocket"... actually you can name it anything you want, but this is the default socket referenced in the sourcecode. (I think I named mine "MuzzleFlashSocket") save your package...
Scripting
For Me I just hacked the Shockrifles Basecode like Geodav's tut suggested...SO i'll ask you to do the same...Create a text file and name give it the name it something like: "Weapon.uc" (should be saved under: c:UDK\UDK-YYYY-MM\Development\"your project folder"\Classes). This is going to be the superclass of your weapon...copy and paste the shock rifle code (delete the default properties) or you could use mine:
Create another text file and U might want to name it after your weapon e.g:"Rifle.uc" Copy and paste the Shock rifles default properties to this file, but make sure you extend it from "Weapon.uc" This is mine (U might want to delete the parts in bold if u're using mine cos they're my annotations which might make screw you over when U go to compile):Code:/** * Copyright 1998-2008 Epic Games, Inc. All Rights Reserved. */ class Weapon extends UTWeapon; // AI properties (for shock combos) var UTProj_ShockBall ComboTarget; var bool bRegisterTarget; var bool bWaitForCombo; var vector ComboStart; var bool bWasACombo; var int CurrentPath; //----------------------------------------------------------------- // AI Interface function float GetAIRating() { local UTBot B; B = UTBot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) || Pawn(B.Focus) == None ) return AIRating; if ( bWaitForCombo ) return 1.5; if ( !B.ProficientWithWeapon() ) return AIRating; if ( B.Stopped() ) { if ( !B.LineOfSightTo(B.Enemy) && (VSize(B.Enemy.Location - Instigator.Location) < 5000) ) return (AIRating + 0.5); return (AIRating + 0.3); } else if ( VSize(B.Enemy.Location - Instigator.Location) > 1600 ) return (AIRating + 0.1); else if ( B.Enemy.Location.Z > B.Location.Z + 200 ) return (AIRating + 0.15); return AIRating; } /** * Overriden to use GetPhysicalFireStartLoc() instead of Instigator.GetWeaponStartTraceLocation() * @returns position of trace start for instantfire() */ simulated function vector InstantFireStartTrace() { return GetPhysicalFireStartLoc(); } function SetComboTarget(UTProj_ShockBall S) { if ( !bRegisterTarget || (UTBot(Instigator.Controller) == None) || (Instigator.Controller.Enemy == None) ) return; bRegisterTarget = false; bWaitForCombo = true; ComboStart = Instigator.Location; ComboTarget = S; ComboTarget.Monitor(UTBot(Instigator.Controller).Enemy); } function float RangedAttackTime() { local UTBot B; B = UTBot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( B.CanComboMoving() ) return 0; return FMin(2,0.3 + VSize(B.Enemy.Location - Instigator.Location)/class'UTProj_ShockBall'.default.Speed); } function float SuggestAttackStyle() { return -0.4; } // for bot combos simulated function Projectile ProjectileFire() { local Projectile p; p = Super.ProjectileFire(); if (UTProj_ShockBall(p) != None) { SetComboTarget(UTProj_ShockBall(P)); } return p; } simulated function rotator GetAdjustedAim( vector StartFireLoc ) { local rotator ComboAim; // if ready to combo, aim at shockball if (UTBot(Instigator.Controller) != None && CurrentFireMode == 0 && ComboTarget != None && !ComboTarget.bDeleteMe) { // use bot yaw aim, so bots with lower skill/low rotation rate may miss ComboAim = rotator(ComboTarget.Location - StartFireLoc); ComboAim.Yaw = Instigator.Rotation.Yaw; return ComboAim; } return Super.GetAdjustedAim(StartFireLoc); } simulated state WeaponFiring { /** * Called when the weapon is done firing, handles what to do next. */ simulated event RefireCheckTimer() { if ( bWaitForCombo && (UTBot(Instigator.Controller) != None) ) { if ( (ComboTarget == None) || ComboTarget.bDeleteMe ) bWaitForCombo = false; else { StopFire(CurrentFireMode); GotoState('Active'); return; } } Super.RefireCheckTimer(); } } function SetFlashLocation( vector HitLocation ) { local byte NewFireMode; if( Instigator != None ) { if (bWasACombo) { NewFireMode = 3; } else { NewFireMode = CurrentFireMode; } Instigator.SetFlashLocation( Self, NewFireMode , HitLocation ); } } simulated function SetMuzzleFlashParams(ParticleSystemComponent PSC) { local float PathValues[3]; local int NewPath; Super.SetMuzzleFlashparams(PSC); if (CurrentFireMode == 0) { if ( !bWasACombo ) { NewPath = Rand(3); if (NewPath == CurrentPath) { NewPath++; } CurrentPath = NewPath % 3; PathValues[CurrentPath % 3] = 1.0; PSC.SetFloatParameter('Path1',PathValues[0]); PSC.SetFloatParameter('Path2',PathValues[1]); PSC.SetFloatParameter('Path3',PathValues[2]); } else { PSC.SetFloatParameter('Path1',1.0); PSC.SetFloatParameter('Path2',1.0); PSC.SetFloatParameter('Path3',1.0); } } else { PSC.SetFloatParameter('Path1',0.0); PSC.SetFloatParameter('Path2',0.0); PSC.SetFloatParameter('Path3',0.0); } } simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation ) { if (FireModeNum>1) { Super.PlayFireEffects(0,HitLocation); } else { Super.PlayFireEffects(FireModeNum, HitLocation); } } /** * Skip over the Instagib rifle code */ simulated function SetSkin(Material NewMaterial) { Super(UTWeapon).SetSkin(NewMaterial); } simulated function AttachWeaponTo(SkeletalMeshComponent MeshCpnt, optional name SocketName) { Super(UTWeapon).AttachWeaponTo(MeshCpnt, SocketName); } defaultproperties { }
Now we create our attachment class...This is the 3rd person version of the weapon...Code:/** * Copyright 1998-2008 Epic Games, Inc. All Rights Reserved. */ class Rifle extends Weapon; defaultproperties { // Weapon SkeletalMesh Begin Object class=AnimNodeSequence Name=MeshSequenceA End Object // Weapon SkeletalMesh Begin Object Name=FirstPersonMesh SkeletalMesh=SkeletalMesh'yourPackage.Mesh.Rifle_1p' This is telling the engine what mesh to use Rotation=(Yaw=-16384) FOV=60.0 End Object AttachmentClass=class'Your Project folder.Rifle_Attachment' This is declaring the weapons attachment class for third person game play..."Your project folder is what ever folder you created under the Development folder Begin Object Name=PickupMesh SkeletalMesh=SkeletalMesh'yourPackage.Mesh.Rifle_3P ' This is the mesh displayed when a player gets pwned and drops his weapon, or when the weapon is on a pickup factory End Object InstantHitMomentum(0)=+60000.0 WeaponFireTypes(0)=EWFT_InstantHit *THis Determines what kind of weapon fire the Rifle will use. e.g Beam, Projectile...In this case we're using instant hit* InstantHitDamage(0)=14.0 *Change this if you want to adjust the damage your weapon inflicts* FireInterval(0)=0.100000 *Now this determins the rate of fire for your weapon* FireInterval(1)=0.280000 InstantHitDamageTypes(0)=class'UTDmgType_ShockPrimary' InstantHitDamageTypes(1)=None WeaponFireSnd[0]=SoundCue'Your Package.Sounds.Yourweaponfiresound_Cue' This is where you identify what sound cue you want played when you fire your weapon* MaxDesireability=0.65 AIRating=0.65 CurrentRating=0.65 bInstantHit=true bSplashJump=false bRecommendSplashDamage=false bSniping=true bAutoCharge=true RechargeRate=10.0 ShouldFireOnRelease(0)=0 ShouldFireOnRelease(1)=1 ShotCost(0)=1 ShotCost(1)=1 FireOffset=(X=20,Y=5) PlayerViewOffset=(X=17,Y=10.0,Z=-8.0) AmmoCount=50000 LockerAmmoCount=30 MaxAmmoCount=50000 FireCameraAnim(1)=CameraAnim'Camera_FX.ShockRifle.C_WP_ShockRifle_Alt_Fire_Shake' MuzzleFlashSocket=MuzzleFlashSocket *This Identifies the joint you want your muzzle flash to shoot from...It's the socket we gave to the joint "b_gun_barrel* MuzzleFlashPSCTemplate=ParticleSystem'yourpackage.Particles.your particle system'This is the particle system U want to use for your Muzzle flash MuzzleFlashAltPSCTemplate=ParticleSystem'WP_ShockRifle.Particles.P_ShockRifle_MF_Alt' MuzzleFlashColor=(R=200,G=120,B=255,A=255) MuzzleFlashDuration=.33 CrossHairCoordinates=(U=256,V=0,UL=64,VL=64) LockerRotation=(Pitch=32768,Roll=16384) IconCoordinates=(U=728,V=382,UL=162,VL=45) QuickPickGroup=0 QuickPickWeight=0.9 WeaponColor=(R=160,G=0,B=255,A=255) InventoryGroup=4 GroupWeight=0.5 IconX=400 IconY=129 IconWidth=22 IconHeight=48 Begin Object Class=ForceFeedbackWaveform Name=ForceFeedbackWaveformShooting1 Samples(0)=(LeftAmplitude=90,RightAmplitude=40,LeftFunction=WF_Constant,RightFunction=WF_LinearDecreasing,Duration=0.1200) End Object WeaponFireWaveForm=ForceFeedbackWaveformShooting1 }
Again, copy the file UTAttachment_Shockrifle and name it :Weapon_Attachment.uc"...Delete the default properties...This is mine:
Copy this file and name the copy: "Rifle_Attachment.uc". Delete everything after the line: class WeaponAttachment extends UTWeaponAttachment; Then change that to: class Rifle_Attachment extends WeaponAttachment;...Then copy the default properties of UTAttachment_ShockRifle below that...Here's mine:Code:/** * Copyright 1998-2008 Epic Games, Inc. All Rights Reserved. */ class Weapon_Attachment extends UTWeaponAttachment; var ParticleSystem BeamTemplate; var class<UTTExplosionLight> ImpactLightClass; var int CurrentPath; simulated function bool AllowImpactEffects(Actor HitActor, vector HitLocation, vector HitNormal) { return (HitActor != None && UTProj_ShockBall(HitActor) == None && Super.AllowImpactEffects(HitActor, HitLocation, HitNormal)); } simulated function SetMuzzleFlashParams(ParticleSystemComponent PSC) { local float PathValues[3]; local int NewPath; Super.SetMuzzleFlashparams(PSC); if (Instigator.FiringMode == 0) { NewPath = Rand(3); if (NewPath == CurrentPath) { NewPath++; } CurrentPath = NewPath % 3; PathValues[CurrentPath % 3] = 1.0; PSC.SetFloatParameter('Path1',PathValues[0]); PSC.SetFloatParameter('Path2',PathValues[1]); PSC.SetFloatParameter('Path3',PathValues[2]); // CurrentPath++; } else if (Instigator.FiringMode == 3) { PSC.SetFloatParameter('Path1',1.0); PSC.SetFloatParameter('Path2',1.0); PSC.SetFloatParameter('Path3',1.0); } else { PSC.SetFloatParameter('Path1',0.0); PSC.SetFloatParameter('Path2',0.0); PSC.SetFloatParameter('Path3',0.0); } } defaultproperties { }
Open unreal frontend and compile your scripts...Then open up udk, open a map, grab an actor factory and look at it's properties...you should see your weapon under "UTWeaponPickupFactory...Code:/** * Copyright 1998-2008 Epic Games, Inc. All Rights Reserved. */ class Rifle_Attachment_BerranoRifle extends Weapon_Attachment; defaultproperties { // Weapon SkeletalMesh Begin Object Name=SkeletalMeshComponent0 SkeletalMesh=SkeletalMesh'yourPackage.Mesh.Rifle_3P'*we're obviously using the 3rd person mesh* End Object MuzzleFlashSocket=MuzzleFlashSocket MuzzleFlashPSCTemplate(0)=ParticleSystem'yourPackage.Particles.yourparticlesystem' MuzzleFlashColor=(R=255,G=120,B=255,A=255) MuzzleFlashDuration=.33; MuzzleFlashLightClass=class'UTGame.UTShockMuzzleFlashLight' bMuzzleFlashPSCLoops=true WeaponClass=class'Rifle'*This is the weapon class"Rifle.uc"* ImpactLightClass=class'UTShockImpactLight' }




Reply With Quote



- Hopefully you'll bring that tutorial building train over to




Bookmarks