About Store Forum Documentation Contact
Donations:
309$/mo



Post Reply 
trigger footsteps on embedded object
Author Message
yvanvds Offline
Silver Supporter

Post: #1
trigger footsteps on embedded object
Hello agian.

I'm working on footsteps now. Basically I play a sound file when animateStepOccured is called, so that part is easy. But to decide on the type of sound, i look at the material below the user. Also very easy:

PHP Code:
Game::World.hmMaterial(p.xz())->user_type

I even found some code to play a different sound when the character walks through shallow water.

But what I cannot find out: if the character walks on an object, like a bridge or a wall, how to find out the material type?

That kind of objects is typically embedded in the terrain. Having custom classes for every building, bridge and other object just because I want to know what kind of footstep to play doesn't seem like the right solution. On the other hand, playing a 'wooden' footstep if on a bridge and a more 'soggy' one when walking below it seems not too far fetched, or does it?

So far i tried:
1. doing a physics ray below the character. But I don't get the objects that are imbedded with the terrain, is that correct?
2. Going through all embedded objects in the current Area and see if there is a Cuts(posBelowActor, embeddedObjectShape). I never get a hit though. I tried the same with terrain_objs instead of embed_objs, but still no hits.

I have included the code for 2. below, for reference. Still, I'd think an easy method to find out the material you walk on, even if it is a terrain object, could be useful for about any game. I hope i've just overlooked something.

Regards,

yvan


PHP Code:
void character::character::animateStepOccured() {
  
Vec p pos();
  
p.Game::World.hmHeight(p.xz());
  
Int type MUT_DEFAULT;
  if(
Game::World.waterUnder(p)) {
    
// this means we're just below water level, but still walking
    
type MUT_WATER;
  } else {
    
    
ctrl.actor.pos();
    
p.-= ctrl.radius() + 0.05;
    if(
p.Game::World.hmHeight(p.xz(), true)) {
      
// get material from the terrain we're walking on
      
type Game::World.hmMaterial(p.xz())->user_type;
    } else {
      
// char is somewhere above terrain, but walking
      // so check for object right below character
      
Int type MUT_VOID;   
      
Game::Area area Game::World.areaActive(Game::World.worldToArea(pos().xz()));
      if (
area != NULL) {
        
REPA(area->data()->embed_objs) {
          if(
Cuts(parea->data()->embed_objs[i].actor.shape(false))) {
            const 
MeshPtr m area->data()->embed_objs[i].mesh();
            
REPAD(jm->parts) {
              if (
Equal(m->parts[j].name"material")) {
                
type =  m->parts[j].material()->user_type;
                break;
              }
            }
            break;
          }
        }
      }
    }
    switch(
type) {
      case 
MUT_WATER: {
        
_stepsWater[Random(7)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }  
      case 
MUT_STONE:
      case 
MUT_ROAD: {
        
_stepsStone[Random(5)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
      case 
MUT_PLANT: {
        
_stepsGrass[Random(5)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
      case 
MUT_METAL: {
        
_stepsMetal[Random(4)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
      case 
MUT_WOOD: {
        
_stepsWood[Random(4)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
      case 
MUT_SNOW:
      case 
MUT_ICE: {
        
_stepsSnow[Random(5)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
      case 
MUT_VOID: break;
      default: {
        
_stepsWoodland[Random(8)].play().pos(YSEVec(T.pos())).speed(RandomF(0.951.05));
        break;
      }
    }
  }

09-05-2013 09:33 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Silver Supporter

Post: #2
RE: trigger footsteps on embedded object
So it works like this:

PHP Code:
void character::character::animateStepOccured() {
  
Vec p pos();
  
p.Game::World.hmHeight(p.xz());
  
Int type MUT_DEFAULT;
  if(
Game::World.waterUnder(p)) {
    
// this means we're just below water level, but still walking
    
type MUT_WATER;
  } else { 
    
ctrl.actor.pos();
    
p.-= ctrl.radius() + 0.01;
    if(
p.Game::World.hmHeight(p.xz(), true)) {
      
// get material from the terrain we're walking on
      
type Game::World.hmMaterial(p.xz())->user_type;
    } else {
      
// char is somewhere above terrain, but walking
      // first, check if the previous found object is still below
      
if(Inside(ppreviousObject)) {
        
type lastType;
      } else {
        
// see if we're on another object
        
type MUT_WOOD// default is wood   
        
Game::Area area Game::World.areaActive(Game::World.worldToArea(pos().xz()));
        if (
area != NULL) {
          
REPA(area->data()->embed_objs) {
            if (
area->data()->embed_objs[i].phys == NULL) continue;
            
previousObject area->data()->embed_objs[i].phys->box;
            if(
Inside(ppreviousObject)) {
              const 
MeshPtr m area->data()->embed_objs[i].mesh();
              if(
m->parts.elms() == 1) {
                
type m->parts[0].material()->user_type;
                
lastType type;
              } else {
                
REPAD(jm->parts) {
                  if (
Equal(m->parts[j].name"step")) {
                    
type =  m->parts[j].material()->user_type;
                    
lastType type;
                    break;
                  }
                }
              }
              break;
            }
          }
        }
      }
    }
    switch(
type) {
      case 
MUT_WATER: {
      
// now play footstep sound according to material 

If you're using EE2.0 i think you have use terrain_objs instead of embed_objs.

There's still one problem left to solve: if an object is too big, it will not be included in embed_objs. Instead mesh and physics are loaded into the area meshgroup and physbody objects. I have not figured out how they relate to each other.

Cheers,

yvan
(This post was last modified: 09-07-2013 10:29 AM by yvanvds.)
09-06-2013 10:10 PM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #3
RE: trigger footsteps on embedded object
Thanks again yvanvds. I'm just getting round to coding sound support for the first time and this is a useful illustration. wink

I'm starting with lip synced NPC speech (tied into my animation module) but overall sound support including footsteps will be next.
09-21-2013 08:29 AM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Silver Supporter

Post: #4
RE: trigger footsteps on embedded object
Good luck with that!

You'll be amazed how much a few sounds contribute to the overal feel of your game world. After walking around in a silent world for more than a year, i was impressed by the difference after adding environment sounds and footsteps.
09-21-2013 11:48 AM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #5
RE: trigger footsteps on embedded object
Agreed, I added a lot when developing with my previous game engine and it really does breath life into a game and noticeably adds to the feeling of immersion.
09-21-2013 11:56 AM
Find all posts by this user Quote this message in a reply
gdalex Offline
Member

Post: #6
RE: trigger footsteps on embedded object
This seems awesome. I'll try that quickly, thanks for sharing, Yvands smile
Related question: how did you implement local sounds in your game ?
For example the sound of a forge when you approach a blacksmith's house ?
09-21-2013 04:17 PM
Find all posts by this user Quote this message in a reply
Post Reply