cassius Posted May 17, 2016 Share Posted May 17, 2016 I have set up the footstep sound for when player moves, but it sounds more like a machine gun . How can I slow it down to walking pace. EDIT: is this something to do with SetLoopMode? Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
martyj Posted May 17, 2016 Share Posted May 17, 2016 There's a few ways to do this. The best way I think, Using Time::GetCurrent(), and checking if X amount of time has passed to call Sound::Play() or Source::Play(). You'd also want to check to see if the audio isn't playing. This is the best way as you can add velocity in with your sounds. For example, if the player is running, the footsteps would be faster. The second way, and by far the easiest, add the time delay in your audio file. With SetLoopMode(true). The audio file will play a walking sound until you call Pause(), or Stop() Quote Link to comment Share on other sites More sharing options...
cassius Posted May 17, 2016 Author Share Posted May 17, 2016 ok. Thanks. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Rick Posted May 18, 2016 Share Posted May 18, 2016 The 3rd way is to set a hook function for your animations. Allow the function to be called at any special frames you wish. Then setup this function to be called at the frames that best match when the feet are on the ground. Then inside this function play your footstep sound. This adjusts automatically with your animation speed too! 2 Quote Link to comment Share on other sites More sharing options...
gamecreator Posted May 18, 2016 Share Posted May 18, 2016 Rick, can you share an example of this? I'm trying to apply damage at a certain animation frame. Quote Link to comment Share on other sites More sharing options...
cassius Posted May 18, 2016 Author Share Posted May 18, 2016 I have changed my mind about having footstep sounds. My character is walking on soft grass anyway so footsteps would not be audible., but I need to get rid of the gliding effect as the character walks. A slight movement of the gun arms might be enough.What do you think? Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Rick Posted May 24, 2016 Share Posted May 24, 2016 @gamecreator Note that I did this in lua but a similar thing could be done if needed in C++. I reuse this idea for 1 time animations and continuous animations. For continuous if you specify a special frame callback it'll get called every frame and then you can do the work in there. All the work is done in AnimationManager.lua Below is the entire code for that: --[[ This script provides a programming interface to easily manage animation transitions. Just call the SetAnimationSequence() function from any other script and the entity's animation will be automatically blended from the previous sequence. It's okay to call this repeatedly with the same sequence. A new sequence will only be added in the animation stack when it is different from the previous sequence. ]]-- if AnimationManager~=nil then return end AnimationManager={} function AnimationManager:Create(entity) if entity==nil then Debug:Error("Entity cannot be nil.") end local animationmanager = {} animationmanager.entity = entity animationmanager.animations={} animationmanager.frameoffset = math.random(0,1000) local k,v for k,v in pairs(AnimationManager) do animationmanager[k] = v end return animationmanager end function AnimationManager:SetAnimationSequence(sequence, speed, blendtime, mode, endHookScript, endHook, specialFrameHook, specialFrame, endFrame) --Handle default parameters if speed==nil then speed=1.0 end if blendtime==nil then blendtime=500 end if mode==nil then mode=0 end --Check for redundant animation descriptor if mode==0 then if #self.animations>0 then if self.animations[#self.animations].sequence==sequence then if self.animations[#self.animations].speed==speed then --No change to blend time, so don't alter this? self.animations[#self.animations].blendtime=blendtime return end end end end --Create new animation descriptor and add to animation stack local animation={} animation.blendstart=Time:GetCurrent() animation.blendfinish=animation.blendstart+blendtime animation.sequence=sequence animation.speed=speed animation.mode=mode animation.starttime=animation.blendstart animation.endHookScript=endHookScript animation.endHook=endHook animation.endOfSequenceReached=false animation.endFrame = endFrame animation.specialFrameHook = specialFrameHook animation.specialFrame = specialFrame --Add a random offset to looped animations so they're not all identical --if mode==0 then -- animation.frameoffset = math.random(0,(self.entity:GetAnimationLength(sequence))) --end table.insert(self.animations,animation) end function AnimationManager:ClearAnimations() self.animations = {} end --[[ function Script:GetFrame(seq) local i,animation currenttime=Time:GetCurrent() for i,animation in ipairs(self.animations) do if animation.sequence == seq then return (currenttime-animation.blendstart) * animation.speed end end return -1 end ]]-- function AnimationManager:Update() local i,animation,blend,frame,n,completedanimation local doanimation=false local currenttime=Time:GetCurrent() local maxanim=-1 for i,animation in ipairs(self.animations) do --Lock the matrix before the first sequence is applied if doanimation==false then doanimation=true self.entity:LockMatrix() end --Calculate blend value blend = (currenttime-animation.blendstart)/(animation.blendfinish-animation.blendstart) blend = math.min(1.0,blend) if animation.mode==0 then frame = currenttime * animation.speed + self.frameoffset--animation.frameoffset local length = self.entity:GetAnimationLength(animation.sequence,true) if animation.specialFrameHook ~= nil then animation.specialFrameHook(animation.endHookScript, animation.sequence, frame, length) end else frame = (currenttime-animation.blendstart) * animation.speed local length = self.entity:GetAnimationLength(animation.sequence,true) -- trigger when special frame is hit if animation.specialFrame ~= nil then if frame > animation.specialFrame then animation.specialFrameHook(animation.endHookScript, animation.sequence) animation.specialFrame = nil end end --If a certain frame was specified, call the hook early and remove it --[[ if animation.endFrame~=nil then if frame>animation.endFrame then animation.endHook(animation.endHookScript, animation.sequence) animation.endFrame=nil animation.endHook=nil animation.endHookScript=nil end end ]] if frame>=length-1 then frame=length-1 maxanim = i+1--clears all animations up to this one, and then this one if (not animation.endOfSequenceReached) then animation.endOfSequenceReached=true if animation.endHookScript then if animation.endHook then animation.endHook(animation.endHookScript, animation.sequence) end end end end end --Apply the animation self.entity:SetAnimationFrame(frame, blend, animation.sequence, true) --If this animation is blended in 100%, all previous looping animation sequences can be dropped if blend>=1.0 then maxanim = math.max(maxanim,i) end end --Unlock entity matrix if any animations were applied if doanimation==true then self.entity:UnlockMatrix() end --Clear blended out animation - moved this out of the loop to prevent jittering if maxanim>-1 then local index=1 for n,completedanimation in ipairs(self.animations) do if n<maxanim then if completedanimation.mode==0 or completedanimation.endOfSequenceReached==true then table.remove(self.animations,index) else index=index+1 end else break end end end end function AnimationManager:GetAnimationStackSize() return #self.animations end Usage is: self.animMgr:SetAnimationSequence("Chop1", 0.04, 250, 1, self, self.EndAction, self.SpecialFrame, 14) function Script:SpecialFrame(seq) -- look into: I don't think I need to call the Use() of the current object each time if seq == "Chop1" then local sound = Math:Round(math.random(1, 4)) self.sounds.chop[sound]:Play() self.currentObject.script:Use(self.equippedItem) end end For walking, if anyone cares, I use the same AnimationManager.lua above but this is the callback that gets called each frame of the animation. Inside I check the frames (8 and 19 in this case which are the frames where the feet are hitting the ground) and toggle a left/right. This will sync up the footsteps sound. function Script:OnAnimationFrame(seq, frame, length) if seq == "Walk" then if math.floor(frame % length) == 8 and self.leftFoot == false then local sound = Math:Round(math.random(1, 5)) self.sounds.walk[sound]:Play() self.leftFoot = true end if math.floor(frame % length) == 19 and self.rightFoot == false then local sound = Math:Round(math.random(1, 5)) self.sounds.walk[sound]:Play() self.rightFoot = true end -- reset if math.floor(frame % length) == 0 then self.leftFoot = false self.rightFoot = false end end end[/code] 1 Quote Link to comment Share on other sites More sharing options...
gamecreator Posted May 24, 2016 Share Posted May 24, 2016 Thank you Rick. I think I'll need to implement something similar. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.