PDA

View Full Version : Player Footsteps That Can Be Heard By Others



Fish&Chips65
04-19-2012, 12:23 AM
How would one set this up? I've realized that I can hear footsteps when in first-person. However, when I am in third-person, no footsteps can be heard. I've found no tutorials on the matter. Could anyone give me a point in the right direction? Thanks in advance!

Crusha K. Rool
04-19-2012, 05:00 AM
Pawn.PlayFootStepSound() is called when your animation reaches the time code of an AnimNotify_FootStep (which are set up in the AnimSet editor).

However, since the frst person view does not have any actual third person mesh present that would play the walking animation, UTPawn defines another function ActuallyPlayFootStepSound() which is called by UpdateEyeHeight() regularly and also by the overwritten PlayFootStepSound():



/* UpdateEyeHeight()
* Update player eye position, based on smoothing view while moving up and down stairs, and adding view bobs for landing and taking steps.
* Called every tick only if bUpdateEyeHeight==true.
*/
event UpdateEyeHeight( float DeltaTime )
{
[]
if ( (Physics == PHYS_Walking) && (VSizeSq(Velocity) > 100) && IsFirstPerson() )
{
m = int(0.5 * Pi + 9.0 * OldBobTime/Pi);
n = int(0.5 * Pi + 9.0 * BobTime/Pi);

if ( (m != n) && !bIsWalking && !bIsCrouched )
{
ActuallyPlayFootStepSound(0);
}
}
}

simulated event PlayFootStepSound(int FootDown)
{
local PlayerController PC;

if ( !IsFirstPerson() )
{
ForEach LocalPlayerControllers(class'PlayerController', PC)
{
if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxFootstepDistSq) )
{
ActuallyPlayFootstepSound(FootDown);
return;
}
}
}
}

/**
* Handles actual playing of sound. Separated from PlayFootstepSound so we can
* ignore footstep sound notifies in first person.
*/
simulated function ActuallyPlayFootstepSound(int FootDown)
{
local SoundCue FootSound;

FootSound = SoundGroupClass.static.GetFootstepSound(FootDown, GetMaterialBelowFeet());
if (FootSound != None)
{
PlaySound(FootSound, false, true,,, true);
}
}

Fish&Chips65
04-19-2012, 08:08 PM
Just a quick question. I notice when my character runs around, he hovers off the ground, would this affect whether the sound plays or not?

Crusha K. Rool
04-19-2012, 08:12 PM
Not directly. The Footsteps themselves are played depending on the time code of the animation or by the frequency of view bobbing of the Pawn in first person respectively.
However, UTPawn uses short traces down below it to determine the PhysMat of the surface it is standing on to play different sounds depending on surfaces. But since it takes the center of the collision cylinder as starting point for that, I think you are fine.
But you can ground your mesh by changing the Translation.Z value in the DefaultProperties of your SkeletalMeshComponent in the Pawn.

Fish&Chips65
04-19-2012, 09:13 PM
Strange, I mustn't have set this up right. My walking sounds don't play when I'm in third-person. Do you know what I'm doing wrong?


class PlayerPawn extends UTPawn;

var AnimTree animTree;
var array<AnimSet> animSet;
var SkeletalMesh skMesh;
var PhysicsAsset physicsAsset;
var DynamicLightEnvironmentComponent LightEnvironment;
var AnimNodeSlot TopHalfSlot;

simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
{
if(SkelComp == Mesh)
{
TopHalfSlot = AnimNodeSlot(Mesh.FindAnimNode('TopHalfSlot'));
}
}

simulated event PostBeginPlay()
{
super.PostBeginPlay();
}

event UpdateEyeHeight( float DeltaTime )
{
local float smooth, MaxEyeHeight, OldEyeHeight, Speed2D, OldBobTime;
local Actor HitActor;
local vector HitLocation,HitNormal, X, Y, Z;
local int m,n;

if ( bTearOff )
{
// no eyeheight updates if dead
EyeHeight = Default.BaseEyeheight;
bUpdateEyeHeight = false;
return;
}

if ( abs(Location.Z - OldZ) > 15 )
{
// if position difference too great, don't do smooth land recovery
bJustLanded = false;
bLandRecovery = false;
}

if ( !bJustLanded )
{
// normal walking around
// smooth eye position changes while going up/down stairs
smooth = FMin(0.9, 10.0 * DeltaTime/CustomTimeDilation);
LandBob *= (1 - smooth);
if( Physics == PHYS_Walking || Physics==PHYS_Spider || Controller.IsInState('PlayerSwimming') )
{
OldEyeHeight = EyeHeight;
EyeHeight = FMax((EyeHeight - Location.Z + OldZ) * (1 - smooth) + BaseEyeHeight * smooth,
-0.5 * CylinderComponent.CollisionHeight);
}
else
{
EyeHeight = EyeHeight * ( 1 - smooth) + BaseEyeHeight * smooth;
}
}
else if ( bLandRecovery )
{
// return eyeheight back up to full height
smooth = FMin(0.9, 9.0 * DeltaTime);
OldEyeHeight = EyeHeight;
LandBob *= (1 - smooth);
// linear interpolation at end
if ( Eyeheight > 0.9 * BaseEyeHeight )
{
Eyeheight = Eyeheight + 0.15*BaseEyeheight*Smooth; // 0.15 = (1-0.75)*0.6
}
else
EyeHeight = EyeHeight * (1 - 0.6*smooth) + BaseEyeHeight*0.6*smooth;
if ( Eyeheight >= BaseEyeheight)
{
bJustLanded = false;
bLandRecovery = false;
Eyeheight = BaseEyeheight;
}
}
else
{
// drop eyeheight a bit on landing
smooth = FMin(0.65, 8.0 * DeltaTime);
OldEyeHeight = EyeHeight;
EyeHeight = EyeHeight * (1 - 1.5*smooth);
LandBob += 0.08 * (OldEyeHeight - Eyeheight);
if ( (Eyeheight < 0.25 * BaseEyeheight + 1) || (LandBob > 2.4) )
{
bLandRecovery = true;
Eyeheight = 0.25 * BaseEyeheight + 1;
}
}

// don't bob if disabled, or just landed
if( bJustLanded || !bUpdateEyeheight )
{
BobTime = 0;
WalkBob = Vect(0,0,0);
}
else
{
// add some weapon bob based on jumping
if ( Velocity.Z > 0 )
{
JumpBob = FMax(-1.5, JumpBob - 0.03 * DeltaTime * FMin(Velocity.Z,300));
}
else
{
JumpBob *= (1 - FMin(1.0, 8.0 * DeltaTime));
}

// Add walk bob to movement
OldBobTime = BobTime;
Bob = FClamp(Bob, -0.05, 0.05);

if (Physics == PHYS_Walking )
{
GetAxes(Rotation,X,Y,Z);
Speed2D = VSize(Velocity);
if ( Speed2D < 10 )
BobTime += 0.2 * DeltaTime;
else
BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/GroundSpeed);
WalkBob = Y * Bob * Speed2D * sin(8 * BobTime);
AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime));
WalkBob.Z = AppliedBob;
if ( Speed2D > 10 )
WalkBob.Z = WalkBob.Z + 0.75 * Bob * Speed2D * sin(16 * BobTime);
}
else if ( Physics == PHYS_Swimming )
{
GetAxes(Rotation,X,Y,Z);
BobTime += DeltaTime;
Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y);
WalkBob = Y * Bob * 0.5 * Speed2D * sin(4.0 * BobTime);
WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * BobTime);
}
else
{
BobTime = 0;
WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime));
}

if ( (Physics == PHYS_Walking) && (VSizeSq(Velocity) > 100) && IsFirstPerson() )
{
m = int(0.5 * Pi + 9.0 * OldBobTime/Pi);
n = int(0.5 * Pi + 9.0 * BobTime/Pi);

if ( (m != n) && !bIsWalking && !bIsCrouched )
{
ActuallyPlayFootStepSound(0);
}
}
if ( !bWeaponBob )
{
WalkBob *= 0.1;
}
}
if ( (CylinderComponent.CollisionHeight - Eyeheight < 12) && IsFirstPerson() )
{
// desired eye position is above collision box
// check to make sure that viewpoint doesn't penetrate another actor
// min clip distance 12
if (bCollideWorld)
{
HitActor = trace(HitLocation,HitNormal, Location + WalkBob + (MaxStepHeight + CylinderComponent.CollisionHeight) * vect(0,0,1),
Location + WalkBob, true, vect(12,12,12),, TRACEFLAG_Blocking);
MaxEyeHeight = (HitActor == None) ? CylinderComponent.CollisionHeight + MaxStepHeight : HitLocation.Z - Location.Z;
Eyeheight = FMin(Eyeheight, MaxEyeHeight);
}
}
}

simulated event PlayFootStepSound(int FootDown)
{
local PlayerController PC;

if ( !IsFirstPerson() )
{
ForEach LocalPlayerControllers(class'PlayerController', PC)
{
if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxFootstepDistSq) )
{
ActuallyPlayFootstepSound(FootDown);
return;
}
}
}
}

simulated function ActuallyPlayFootstepSound(int FootDown)
{
local SoundCue FootSound;

FootSound = SoundGroupClass.static.GetFootstepSound(FootDown, GetMaterialBelowFeet());
if (FootSound != None)
{
PlaySound(FootSound, false, true,,, true);
}
}

function SetAnimSet(int x)
{
if (x == 1)
{
Mesh.AnimSets[0]=AnimSet'CH_War_Player.Animations.War_Player_Anims ';
}
if (x == 0)
{
Mesh.AnimSets[0]=AnimSet'CH_War_Player.War_Melee_Anims';
}

Mesh.UpdateAnimations();
}

function UseRifleAnims()
{
Mesh.AnimSets[0]=AnimSet'CH_War_Player.Animations.War_Player_Anims ';
Mesh.UpdateAnimations();
}
function UseMeleeAnims()
{
Mesh.AnimSets[0]=AnimSet'CH_War_Player.War_Melee_Anims';
Mesh.UpdateAnimations();
}
defaultproperties
{
Begin Object Name=MyLightEnvironment
bSynthesizeSHLight=TRUE
bIsCharacterLightEnvironment=TRUE
End Object

Components.Add(MyLightEnvironment)
LightEnvironment=MyLightEnvironment

Begin Object class=SkeletalMeshComponent Name=SkeletalMeshComponent0
SkeletalMesh=SkeletalMesh'CH_War_Player.SKMesh.SK_ Mesh_CH_War_Player'
PhysicsAsset=PhysicsAsset'CH_War_Player.Physics.SK _Mesh_CH_War_Player_Physics'
AnimSets(0)=AnimSet'CH_War_Player.War_Melee_Anims'
AnimSets(1)=AnimSet'CH_War_Player.Animations.War_P layer_Anims'
AnimTreeTemplate=AnimTree'CH_War_Player.Animations .CH_War_Player_AnimTree'
LightEnvironment=MyLightEnvironment
bHasPhysicsAssetInstance=True
bEnableSoftBodySimulation=True
bSoftBodyAwakeOnStartup=True
End Object
Mesh=SkeletalMeshComponent0
Components.Add(SkeletalMeshComponent0)

SoundGroupClass=class'UTGame.UTPawnSoundGroup'
}

Crusha K. Rool
04-20-2012, 03:50 AM
Well, did you add AnimNotify_FootSteps to your anim sequence?

Fish&Chips65
04-20-2012, 07:28 PM
Ahhh, I see. I completely forgot that part.

Edit: Got it to work! Thank you so much!

I figured out how to set up the AnimNotify_Footstep. To set it up, look at the bottom of this thread: http://forums.epicgames.com/threads/813552-Animtree-SemiStrafe-problem