Announcement

Collapse
No announcement yet.

Hearbteat while health is low (problem with code)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Hearbteat while health is low (problem with code)

    Based on a certain tutorial I found on this forum, I modified my pawn code so that the player could hear a heartbeat when his health is low. For some reason no sound is heard at all on my player. Is this code ok?

    Code:
    class TTSPawn extends UTPawn;
    
     
    
    var(NPC) class NPCController;
    var AudioComponent HealthSound;
     
    event
     TakeDamage(int DamageAmount, Controller EventInstigator, vector 
    HitLocation, vector Momentum, class<DamageType> DamageType, 
    optional TraceHitInfo HitInfo, optional Actor DamageCauser)
    {
        super.TakeDamage(DamageAmount, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
        if (Health <= 25)
        {
            HealthSound.Play();
        }
    }
     
    function Tick(float DeltaTime)
    {
        Super.Tick(DeltaTime);
     
        if (Health > 25)
             HealthSound.Stop();
    }
     
    simulated event Destroyed()
    {
        HealthSound = None;
        super.Destroyed();
    }
     
    
     
    
    defaultproperties
    
    {
    
    Begin Object class=AudioComponent name=MenuAudioComponent
            SoundCue = SoundCue'kicc_props_02b.Alien'
        End Object
        HealthSound = MenuAudioComponent
        Components.Add(MenuAudioComponent)
    
    
    WalkingPct=+0.4
    
    CrouchedPct=+0.4
    
    BaseEyeHeight=38.0
    
    EyeHeight=38.0
    
    GroundSpeed=400.0
    
    AirSpeed=440.0
    
    WaterSpeed=220.0
    
    DodgeSpeed=200.0
    
    DodgeSpeedZ=295.0
    
    AccelRate=2048.0
    
    JumpZ=322.0
    
    CrouchHeight=29.0
    
    CrouchRadius=21.0
    
    WalkableFloorZ=.75
    
     
    
    AlwaysRelevantDistanceSquared=+1960000.0
    
    //InventoryManagerClass=class'UTGame.UTInventoryManager'
    
     
    
    //ControllerClass=class'TTSGame.TTSPlayerController'
    
    NPCController=class'TTSGame.TTSPlayerController'
    
     
    
    MeleeRange=+20.0
    
    bMuffledHearing=true
    
     
    
    Buoyancy=+000.99000000
    
    UnderWaterTime=+00020.000000
    
    bCanStrafe=True
    
    bCanSwim=true
    
    RotationRate=(Pitch=20000,Yaw=20000,Roll=20000)
    
    MaxLeanRoll=2048
    
    AirControl=+0.35
    
    DefaultAirControl=+0.35
    
    bCanCrouch=true
    
    bCanClimbLadders=True
    
    bCanPickupInventory=True
    
    bCanDoubleJump=true
    
    SightRadius=+3000.0
    
     
    
    FireRateMultiplier=5.0
    
     
    
    MaxMultiJump=3
    
    MultiJumpRemaining=10
    
    MultiJumpBoost=-95.0
    
     
    
    SoundGroupClass=class'UTGame.UTPawnSoundGroup'
    
     
    
    TransInEffects(0)=class'UTEmit_TransLocateOutRed'
    
    TransInEffects(1)=class'UTEmit_TransLocateOut'
    
     
    
    MaxStepHeight=35.0
    
    MaxJumpHeight=69.0
    
    MaxDoubleJumpHeight=87.0
    
    DoubleJumpEyeHeight=43.0
    
     
    
    SuperHealthMax=9000
    
     
    
    Begin Object Name=WPawnSkeletalMeshComponent
    
    bOwnerNoSee=false
    
    End Object
    
    Name="Default__TTSPawn"
    
    }

    #2
    Hearbteat while health is low (problem with code)

    In your default properties:

    It says healthsound = menuaudiocomponent.

    That should be the path to the soundcue or soundnode wave in your content browser.
    E.g

    Healthsound = soundcue'ch_yourcharacter.yourpachage.soundcuename .


    Sent from my iPhone using Tapatalkpp

    Comment


      #3
      You may need to run a check statement and maybe refer to an initial state.
      -^^ not sure about that, but this bit should fix things for you " && Health > 0)"
      - Here is a working example:
      Code:
      var SoundCue HeartBeat;
      
      
      // PLAY HEARTBEAT SOUND BEGIN
      
      
      // KEEP ALL THIS
      reliable client function PlayHeartBeat() 
      {
      SetPawnAmbientSound(HeartBeat);
      } 
      
      
      reliable client function StopHeartBeat() 
      {
      SetPawnAmbientSound(None);
      } 
      
      
      event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
      {   
              Health = Health - DamageAmount;
          
              WorldInfo.Game.Broadcast(self, "Taking Damage" @ DamageAmount);
              
              if(Health <= 15 && Health > 0)
                  {
                  WorldInfo.Game.Broadcast(self, " health is low");
                  PlayHeartBeat();
                  }
          
              if(Health <= 0)
                  {
                  WorldInfo.Game.Broadcast(self, "You are Dead");
                  Destroy();
                  }
              
              //GroundSpeed = 300;
              //jumpz=50
      }
      
      
      simulated event Tick(float DeltaTime)
      {
          super.Tick(DeltaTime);
                  
              if(Health >= 15)
                  {
                  StopHeartBeat();
                  }
      }
      
      
      // PLAY HEARTBEAT SOUND END
      
      
      
      
      Defaultproperties
      {
          //HeartBeat=SoundCue'A_Pickups_Powerups.PowerUps.A_Powerup_Berzerk_PowerLoopCue'
          HeartBeat=SoundCue'Unr_SoundFX.Sounds.HEARTB1Cue'
          
      }

      Comment


        #4
        You defined HealthSound as a global variable and you set its initial value in your default properties.
        This does not work: to initialize global variables in DefaultProperties, you must add parenthesis in variable declaration.

        Code:
        var() AudioComponent HealtSound;
        However i don't know if this is the main problem, because i never handled sound (for now).

        Enjoy.

        Comment


          #5
          The parenthesis have nothing to do with the defaultproperties assignment. They are used to show that field into the properties in the editor (or remote console).

          I highly suspect that it has to do something with the additional space/line after the defaultproperties keyword. Fix it like:
          Code:
          defaultproperties
          {
          
          }

          Comment


            #6
            Originally posted by RattleSN4K3 View Post
            The parenthesis have nothing to do with the defaultproperties assignment. They are used to show that field into the properties in the editor (or remote console).
            Yes this is another thing that parenthesis do, but not the only one. You can also initialize variables in defaultproperties. Have you ever tried?

            Comment


              #7
              Just wanted to add

              - I had the same problem as the OP
              - i fixed it using the code above and it was solely because of the " && Health > 0)" AND Health = Health - DamageAmount;
              @vinkald
              RattleSN4K3 is probably aware of that, but he would have given the best answer available, not just things you might be able to do, just things you should do.
              @ Reverrb; just use my code or try RattleSN4K3's idea.

              Comment


                #8
                Originally posted by TKBS View Post
                You may need to run a check statement and maybe refer to an initial state.
                -^^ not sure about that, but this bit should fix things for you " && Health > 0)"
                - Here is a working example:
                Code:
                var SoundCue HeartBeat;
                
                
                // PLAY HEARTBEAT SOUND BEGIN
                
                
                // KEEP ALL THIS
                reliable client function PlayHeartBeat() 
                {
                SetPawnAmbientSound(HeartBeat);
                } 
                
                
                reliable client function StopHeartBeat() 
                {
                SetPawnAmbientSound(None);
                } 
                
                
                event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
                {   
                        Health = Health - DamageAmount;
                    
                        WorldInfo.Game.Broadcast(self, "Taking Damage" @ DamageAmount);
                        
                        if(Health <= 15 && Health > 0)
                            {
                            WorldInfo.Game.Broadcast(self, " health is low");
                            PlayHeartBeat();
                            }
                    
                        if(Health <= 0)
                            {
                            WorldInfo.Game.Broadcast(self, "You are Dead");
                            Destroy();
                            }
                        
                        //GroundSpeed = 300;
                        //jumpz=50
                }
                
                
                simulated event Tick(float DeltaTime)
                {
                    super.Tick(DeltaTime);
                            
                        if(Health >= 15)
                            {
                            StopHeartBeat();
                            }
                }
                
                
                // PLAY HEARTBEAT SOUND END
                
                
                
                
                Defaultproperties
                {
                    //HeartBeat=SoundCue'A_Pickups_Powerups.PowerUps.A_Powerup_Berzerk_PowerLoopCue'
                    HeartBeat=SoundCue'Unr_SoundFX.Sounds.HEARTB1Cue'
                    
                }
                TKBS, I replaced my old heartbeat code with yours but still nothing happens..even the broadcast messages don't appear when health is low/player is dead..I have no Idea what's going on and I'm still learning UnrealScript so I'm kinda frustrated..

                Comment


                  #9
                  What does your GameInfo class look like, and how are you running it?

                  Comment


                    #10
                    Originally posted by Angel_Mapper View Post
                    What does your GameInfo class look like, and how are you running it?
                    Here is my gameinfo class:

                    Code:
                        class TTSGameInfo extends UTGame;
                    
                     
                    
                    var TTSPlayerController currentPlayer;
                    
                     
                    
                    function RestartPlayer(Controller aPlayer)
                    
                    {
                    
                    super.RestartPlayer(aPlayer);
                    
                    `Log("Player restarted");
                    
                    currentPlayer = TTSPlayerController(aPlayer);
                    
                     
                    
                    currentPlayer.resetMesh();
                    
                    currentPlayer.rSetBehindView(false);
                    
                    currentPlayer.rSetCameraMode('FirstPerson');
                    
                    }
                    
                     
                    
                    simulated function PostBeginPlay() {
                    
                    local UTGame Game;
                    
                    Super.PostBeginPlay();
                    
                     
                    
                    Game = UTGame(WorldInfo.Game);
                    
                     
                    
                    if (Game != None)
                    
                    {
                    
                    Game.PlayerControllerClass=Class'TTSGame.TTSPlayerController';
                    
                    }
                    
                    }
                    
                     
                    
                    defaultproperties
                    
                    {
                    
                     
                    
                    PlayerControllerClass=Class'TTSGame.TTSPlayerController';
                    
                     
                    
                    }

                    Comment


                      #11
                      Some additional explanations:
                      • No need to use the package name TTSGame in the class literal (in defaultproperties or code). Normally, all class names are unique and once you use class'TTSPlayerController', it will automatically refer to the class in the package TTSGame. It's easier to manage code as once you would need to rename the package, you have to fix all the reference as class'TTSGame.TTSPlayerController' cannot be found if the package TTSGame is not existing but class'TTSPlayerController' can be found (if the class exists) no matter what the package is called.
                      • Why are you casting the WorldInfo.Game reference to game and set its value?
                        Code:
                        Game = UTGame(WorldInfo.Game);
                        
                        if (Game != None)
                        {
                        Your class (TTSGameInfo) is already extending UTGame. If the engine is processing that code you write into that class, self-object is type of UTGame. You can then easily access any field of UTGame (and any parent classes) without an additional reference:
                        Code:
                        class TTSGameInfo extends UTGame;
                        
                        simulated function PostBeginPlay()
                        {
                            PlayerControllerClass=Class'TTSPlayerController';
                        }
                      • The GameInfo class doesn't look good to me as why would need to set the PlayerControllerClass field when you already set it in the default properties.
                      • Use local variables. Why would you need to store the current player into a class field if you can store it locally. It reduces the memory usage but also cleans up your code.

                        Instead of having:
                        Code:
                        var TTSPlayerController currentPlayer;
                        ...use a locally declared variable. That local variable is only available in the scope of the called method:
                        Code:
                        function RestartPlayer(Controller aPlayer)
                        {
                            local TTSPlayerController currentPlayer;
                      • Before accessing variables with references, check if the reference is still valid.
                        Code:
                            currentPlayer = TTSPlayerController(aPlayer);
                            if (currentPlayer != none)
                            {
                                currentPlayer.resetMesh();
                                //...
                            }
                        Otherwise you will get a ton of error messages if a class is not available anymore. In your case, aPlayer should be always valid and the cast would never fail, but there's basically no reason to not check for the valid reference in any case.


                      If you new to UnrealScript, i've heard Angel_Mapper's book is really good. You might check it out. It should help a lot.
                      https://www.packtpub.com/game-develo...eginners-guide




                      Your initial code doesn't look bad to me, and could work. I'm not sure what you intend, but in that code you are only triggering the play sound on the server side. I created a minimal version featuring a fully network compatible heartbeat sound. The sound is only played for the own player (not the ones of other clients/bot) (not sure if you intend some ambient sound for heartbeats so you can hear the sound from other players as well).

                      TTSGameInfo
                      Code:
                      class TTSGameInfo extends UTGame;
                      
                      function RestartPlayer(Controller aPlayer)
                      {
                          local TTSPlayerController currentPlayer;
                          super.RestartPlayer(aPlayer);
                      
                          `Log("Player restarted");
                      
                          currentPlayer = TTSPlayerController(aPlayer);
                          if (currentPlayer != none)
                          {
                              currentPlayer.resetMesh();
                              currentPlayer.rSetBehindView(false);
                              currentPlayer.rSetCameraMode('FirstPerson');
                          }
                      }
                      
                      defaultproperties
                      {
                          PlayerControllerClass=class'TTSPlayerController'
                          DefaultPawnClass=class'TTSPawn'
                      }
                      TTSPawn
                      Code:
                      class TTSPawn extends UTPawn;
                      
                      var AudioComponent HealthSound;
                      
                      simulated event Destroyed()
                      {
                          HealthSound.Stop();
                          HealthSound = None;
                      
                          super.Destroyed();
                      }
                      
                      simulated function PlayTakeHitEffects()
                      {
                          super.PlayTakeHitEffects();
                          
                          if (IsLocallyControlled() && IsHumanControlled() && Health <= 25 && !HealthSound.IsPlaying())
                          {
                              HealthSound.Play();
                      
                              // as HealDamage is not called by the UTGame code, we need to check for Health changes
                              // we can do this in a tick, or use a slow timer
                              if (!IsTimerActive('CheckHealth'))
                              {
                                  SetTimer(0.25, true, 'CheckHealth');
                              }
                          }
                      }
                      
                      simulated function CheckHealth()
                      {
                          if (Health > 25)
                          {
                              HealthSound.Stop();
                              ClearTimer(GetFuncName());
                          }
                      }
                      
                      defaultproperties
                      {
                          Begin Object class=AudioComponent name=MenuAudioComponent
                              //SoundCue=SoundCue'kicc_props_02b.Alien'
                              SoundCue=SoundCue'A_Vehicle_Generic.Vehicle.VehicleChargeLoopCue'
                          End Object
                          HealthSound=MenuAudioComponent
                          Components.Add(MenuAudioComponent)
                      }

                      Comment


                        #12
                        It works now, thanks!!

                        Also one problem I kept getting into was that UDK would suddenly just stop playing all audio for no reason at all. So I ended up having to delete "udkeditorusersettings.ini" and after this everything works perfectly.

                        Comment


                          #13
                          Originally posted by reverrb View Post
                          It works now, thanks!!

                          Also one problem I kept getting into was that UDK would suddenly just stop playing all audio for no reason at all. So I ended up having to delete "udkeditorusersettings.ini" and after this everything works perfectly.
                          Another solution to the sound loss is to start a blank project then toggle the Speaker icon on the taskbar on / off, then shut down UDK. Then create a blank project once more, and open your own personal project file from there. The problem appears to crop up when repeatedly opening personal projects directly in the editor, so this is just another way to 'reset' the sound in UDK, but without having to delete the editor INI file...

                          Comment

                          Working...
                          X