Announcement

Collapse
No announcement yet.

"Trap": won't trigger

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

    "Trap": won't trigger

    Hi everyone,

    I'm very new to using UnrealScript so please bear with me This is my first script other than ones which have simply modified defaultproperties.

    I'm trying to figure out how to make an Actor which, on impact, will damage whatever has impacted it. My end result will be a trip wire or pressure pad which detonates a bomb, but in the meantime I've made a very simple class which has no graphics (as I don't know how to give actors geometry or textures yet ), and which is inactive for a few seconds before it changes to the "Active" state, where it deals 100 damage to a pawn which collides with it, and is then destroyed.

    Unfortunately it doesn't work. Touch() never seems to be triggered (not even out of a state, I tested this while fiddling with the class), and postNetBeginPlay never seems to be called either.

    Code:
    class GiftigTrap extends Actor;
    
    var float activation_delay;
    
    var class<DamageType> damage_type;
    
    event postNetBeginPlay()
     {
     super.postNetBeginPlay();
     activate();
     }
    
    function activate()
     {
     GotoState('Activating');
     }
    function deactivate()
     {
     GotoState('Inactive');
     }
    
    state Active
     {
     function touch(Actor a)
      {
      local Pawn p;
      super.touch(a);
      p=Pawn(a);
      
      if(p==None)
       return;
      
      p.TakeDamage(100,p,vect(0,0,0),vect(0,1,0),damage_type);
      Destroy();
      }
     }
    
    state Inactive
     {
     
     }
    state Activating
     {
     Begin:
      sleep(activation_delay);
      spawn(class'RedeemerWarhead'); //Debug statement to see if this point reached: can't exactly not notice a redeemer blast
      GotoState('Active');
     }
    
    DefaultProperties
     {
     activation_delay=3.0;
     damage_type=class'DamTypeRocket';
     
     
     DrawType=DT_StaticMesh;
     bWorldGeometry=true;
     CollisionHeight=+10.0;
     CollisionRadius=+100.0;
     
     bCollideActors=true;
     }
    Any ideas why my class doesn't work? I also tried making it extend HealthPack to make sure I could see what I was colliding with, to no avail.

    Thanks in advance.

    #2
    Ok, so it looks like the first step is getting the actor to go into the Active state. As you want the actor to go into this state straight away we can use the very helpful "auto" command. A state with the word "Auto" before it means, it will automatically go into that state when it is first created.

    To check it is working lets put in a log. (remember to remove log lines in the final versions). Type "showlog" without the quotes whilst in game to view the log as you play. Otherwise it can be found in the System folder.
    Code:
    Auto State Active
    {
    //touch function
    Begin:                                                           
         log("The begin label in my State Active was passed");
    }
    Also include a StaticMesh=StaticMesh'SomeStaticMesh' in the defaultproperties

    Comment


      #3
      Originally posted by INIQUITOUS View Post
      As you want the actor to go into this state straight away we can use the very helpful "auto" command.
      Thanks; I figured there would be a way of doing this but I didn't know what it was.

      Originally posted by INIQUITOUS View Post
      To check it is working lets put in a log. (remember to remove log lines in the final versions). Type "showlog" without the quotes whilst in game to view the log as you play. Otherwise it can be found in the System folder.
      Code:
      Auto State Active
      {
      //touch function
      Begin:                                                           
           log("The begin label in my State Active was passed");
      }
      Again, thanks that's helpful I've seen code with log commands, but since I had no idea how to view the log, I didn't use them, opting for spawning a redeemer warhead or something equally blatant instead

      I'll try again with the changes you mentioned to double-check where the error is occuring and post the results in a few minutes.

      Thanks.

      Comment


        #4
        Okay, I modified the code as follows:

        Code:
        class GiftigTrap extends Actor;
        
        var float activation_delay;
        
        var class<DamageType> damage_type;
        
        function activate()
         {
         GotoState('Activating');
         }
        function deactivate()
         {
         GotoState('Inactive');
         }
        
        state Active
         {
         function touch(Actor a)
          {
          local Pawn p;
          log("[Active]touch(Actor) called");
          super.touch(a);
          p=Pawn(a);
          
          if(p==None)
           return;
          
          log("[Active]touch(Actor) had argument of type Pawn");
          
          p.TakeDamage(100,p,vect(0,0,0),vect(0,1,0),damage_type);
          Destroy();
          }
         
         Begin:
          log("State Active reached");
         }
        
        auto state Inactive
         {
         Begin:
          log("State Inactive reached");
          activate(); //will be changed later
         }
        state Activating
         {
         Begin:
          log("State Activating reached");
          
          sleep(activation_delay);
          spawn(class'RedeemerWarhead'); //clearly not as noticeable as I'd hoped
          GotoState('Active');
         }
        
        DefaultProperties
         { 
         activation_delay=3.0;
         damage_type=class'DamTypeRocket';
         
         DrawType=DT_StaticMesh;
         StaticMesh=StaticMesh'E_Pickups.MidHealth';
         
         bWorldGeometry=true;
         CollisionHeight=+10.0;
         CollisionRadius=+100.0;
         
         bCollideActors=true;
         }
        As expected, the statements "State Inactive reached" and "State Activating reached" are printed to the log, followed by "State Active reached" after the level-loading stuff. But after that, nothing further is printed. So it seems that the problem is that touch() is never called, and without more knowledge of UnrealScript, I have no idea why. No amount of walking into / stamping on / shooting at / driving over the objects will cause anything further to be printed into the log.

        Any ideas what I'm missing?

        Thanks for the help so far.

        Comment


          #5
          have u tried bUseCylinderCollision=True ??

          Comment


            #6
            Originally posted by iwanpompier View Post
            have u tried bUseCylinderCollision=True ??
            Just tried it; no change.

            Comment


              #7
              Sometimes its hard to know which version of the function "touch" will be accessed. First you should make sure that it is touching things properly. I would make the normal "touch" function outside of the state and put a log in like...

              Code:
              function Touch(Actor Other)
              {
                   log("I was touched by" @ Other);
              }
              Another way to do this could be to use the GetState or IsInState functions like so.

              Code:
              function Touch(Actor Other)
              {
                   if(Pawn(Other) != None)
                   {
                             if(GetStateName() == 'Active')
                            {
                                     Pawn(Other).TakeDamage //etc....
                            }
                            //OR
                            if(IsInState('Active'))
                            {
                                     Pawn(Other).TakeDamage //etc....
                            }
                    }
              }
              You should have lots of ideas now

              Comment


                #8
                Originally posted by INIQUITOUS View Post
                Sometimes its hard to know which version of the function "touch" will be accessed.
                Ah, I see. I had assumed that the function defined within the state would be declared since it is more specific than one not defined inside a state. I'll try adding to the log from outside of states.


                EDIT: Just tried it. Still no log entry, so touch(Actor) doesn't seem to ever be called.

                Comment


                  #9
                  Ok so its not colliding. Try these defaults instead. (Your bWorldGeometry value I think might be wrong.)

                  Code:
                  defaultproperties
                  {
                       activation_delay=3.0
                       damage_type=class'DamTypeRocket'
                       DrawType=DT_StaticMesh
                       StaticMesh=StaticMesh'E_Pickups.MidHealth'
                       DrawScale=1.000000
                       CollisionRadius=100.000000
                       CollisionHeight=10.000000
                       bCollideActors=True 
                       bCollideWorld=True //might need this so it doesnt fall through the world
                       bUseCylinderCollision=True
                  }
                  (you don't need the ";" at the end of defaultproperty lines ) Triggers use the Touch function and have very few defaultproperties different to Actor. Might be worth comparing and seeing where you went wrong.

                  Comment


                    #10
                    Originally posted by INIQUITOUS View Post
                    (you don't need the ";" at the end of defaultproperty lines )
                    I noticed that, but it feels inconsistent and it doesn't complain if I do use semicolons, so it will survive the only time I don't use semi-colons is when I'm using python, but at least there you consistently don't need to use them

                    By the way, about the falling through the world thing, I can still see them, so they don't seem to have fallen through? Though I accidentally put them embedded halfway through the floor in UnrealEd and I'm too lazy to correct it. There is a very obvious lump in the floor when you walk over them though, so it seems to suggest that they're where they appear to be. I'll give it a go with the modified defaultproperties though.

                    No change. Also, about the Trigger thing, I tried making this class extend Trigger before, though some of the properties were a bit confusing. I couldn't get it working when extending Trigger either.

                    Comment


                      #11
                      Interestingly, I just made it extend Trigger instead of Actor, and commented out the properties related to collision, as well as bWorldGeometry, and the object is no longer visible, and no longer causes any log messages to be printed at all (not even the ones I placed in the Begin: section of the Inactive state).

                      Comment


                        #12
                        I just compiled my own version. It works great. The original Touch function in the state was also working fine. Here is the code I used.

                        Code:
                        class GiftigTrap extends Actor placeable;
                        
                        var float activation_delay;
                        var class<DamageType> damage_type;
                        
                        function activate()
                        {
                        	GotoState('Activating');
                        }
                        
                        function deactivate()
                        {
                        	GotoState('Inactive');
                        }
                        
                        /*function Touch(Actor Other)
                        {
                        	log("I was touched by" @ Other);
                        }*/
                        
                        state Active
                        {
                        	function touch(Actor Other)
                        	{
                        		local Pawn p;
                        		log("[Active]touch(Actor) called");
                        
                        		super.touch(Other);
                        
                        		p=Pawn(Other);
                        
                        		if(p==None)
                        		return;
                        
                        		log("[Active]touch(Actor) had argument of type Pawn");
                        
                        		p.TakeDamage(100,p,vect(0,0,0),vect(0,1,0),damage_type);
                        		Destroy();
                        	}
                        
                        Begin:
                        	log("State Active reached");
                        }
                        
                        auto state Inactive
                        {
                        
                        Begin:
                        	log("State Inactive reached");
                        	activate(); //will be changed later
                        }
                        
                        state Activating
                        {
                        
                        Begin:
                        	log("State Activating reached");
                        	sleep(activation_delay);
                        	GotoState('Active');
                        }
                        
                        DefaultProperties
                        {
                        	activation_delay=3.0
                        	damage_type=class'DamTypeRocket'
                        	DrawType=DT_StaticMesh
                        	StaticMesh=StaticMesh'E_Pickups.MidHealth'
                        	CollisionHeight=+10.0
                        	CollisionRadius=+100.0
                        	bCollideActors=true
                        	bUseCylinderCollision=true
                        }

                        Comment


                          #13
                          So after all that, it was bWorldGeometry which caused the issue... any idea why?

                          Thanks, it works for me as well now. Now I just need to improve it

                          Comment


                            #14
                            If I recall, an actor with bWorldGeometry has its collision calculated differently and I think Hitwall() is called, instead of Touch() but I might be wrong. The unreal wiki can shed more light!

                            Comment


                              #15
                              Originally posted by INIQUITOUS View Post
                              Sometimes its hard to know which version of the function "touch" will be accessed.
                              No, it's not. If an actor is in a state and that state contains a Touch() event, that one will be called instead of a non-state Touch().


                              bWorldGeometry means the actor is world geometry. Falling through world geometry can only happen if the actor can move (e.g. Physice=PHYS_Falling) and does not bCollideWorld. It doesn't apply to immobile actors at all unless they are placed inside solid BSP.

                              Comment

                              Working...
                              X