Announcement

Collapse
No announcement yet.

Checking states, Checking vertical distance, Checking checking checking

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

    Checking states, Checking vertical distance, Checking checking checking

    How do you detect a state in an if statement? For instance the Leviathan has something called "state Deployed" etc. How do you make an if statement under Tick so that at a certain height it goes into a different state?

    Also, does State function like Tick? As in it constantly runs through the functions in the state in a way similar to Tick?

    Finally, how do you detect how far away from the ground you are? I'm thinking of using KRepulsors and making them drop like how the Manta detects distance before using its dust emitters. I need a vehicle to change to a certain state when it is X distance in the air.

    #2
    Detecting State:
    Code:
    function Tick(float deltatime) {
            Super.Tick(deltatime);
            if ( isInState('Deployed') && DeployedHeight > 1000) {
                      GotoState('TooHigh');
            }
    }
    Guess you need to change the DeployedHeight > 1000 to your version of coding to check it's height, but this will work.

    Next...
    States are like sub classes of a class, they make use of allowing the same function to do many different things without checking what the function has to do.

    if you have the following, then the state 'LowerDeployment' will override the base Tick() function. Guess you could say it's a way of making use of dublicating functions without the hassle of checking what the function is going to do this time round.

    Code:
    var float DeployedHeight;
    
    // BASE FUNCTION
    function Tick(float deltatime) {
            Super.Tick(deltatime);
            DeployedHeight += deltatime;
    }
    
    State LowerDeployment{
          // STATE FUNCTION
          function Tick(float deltatime) {
                 DeployedHeight -= deltatime;
         }
    }

    Lastly, you could use FastTrace() or Trace() to check how far you are up in the air, by pointing the trace Z directly downwards from your vehicle, the same way weapon traces are done, and bot dodging to make sure they don't hit walls.

    Hope this helps.

    Comment


      #3
      Whoa thanks! That just solved about 30 problems I had! :up:

      EDIT: And unfortunately created 20 more...

      Also, do you know how to change the gravity scale of a vehicle under state? I basically want to make it so that during a certain state, gravity does not affect the vehicle and at others it does.

      Erhmm, I can't get the distance checking to work. It seems to being screwing up which state it is in a lot...hmm...

      EDIT: It seems to think that it is always flying, or at least 1000 above the ground for DeployedHeight. GAH checking distances is killing me.

      Comment


        #4
        Your could modify the KActorGravScale in the vehicles Karma Properties, that may help.

        Comment


          #5
          Any tips about the state changing? It seems to think it is in one state and doesn't change. I can't get the altitude detection thingy working right, I think. Also, when I type in for it to log all kinds of info, it doesn't show up in the log!

          Comment


            #6
            *bump* problem still is here

            Comment


              #7
              T, post the script or PM me with it - I wanna see if I can help you with this.

              Comment


                #8
                Code:
                
                class Lotus extends ONSChopperCraft;
                
                //Don't compile this; it's not complete!
                
                
                //This variable supposedly detects the height above ground at which the vehicle is at during any given time
                var float DeployedHeight;
                
                
                
                //Here we have our states! There are a lot. These ones are used most of the time.
                auto state UnDeployed
                {
                          function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                    function VehicleFire(bool bWasAltFire)
                    {
                    	if (bWasAltFire)
                    	{
                            if (PlayerController(Controller) != None)
                                GotoState('Deploying');
                        }
                    	else
                    		bWeaponIsFiring = True;
                    }
                }
                
                state Deployed
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                    function VehicleFire(bool bWasAltFire)
                    {
                    	if (bWasAltFire)
                            GotoState('UnDeploying');
                    	else
                    		bWeaponIsFiring = True;
                    }
                }
                
                state FlyingUndeployed
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                    function VehicleFire(bool bWasAltFire)
                    {
                    	if (bWasAltFire)
                            GotoState('FlyingDeploying');
                    	else
                    		bWeaponIsFiring = True;
                    }
                }
                
                state FlyingDeployed
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                    function VehicleFire(bool bWasAltFire)
                    {
                    	if (bWasAltFire)
                            GotoState('FlyingUndeploying');
                    	else
                    		bWeaponIsFiring = True;
                    }
                }
                
                
                //Here we have more states! These are used as transitions between the above states with animations, etc.
                
                state FlyingDeploying
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(HideSound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(HideForce);
                	}
                        Weapons[0].bForceCenterAim = False;
                        Weapons[0].PlayAnim('GotoSword');
                        sleep(2.03);
                        //Weapons[0].ProjectileClass=TimLotus.LotusPistolProjectile;
                    	bStationary = false;
                    	SetActiveWeapon(0);
                	bDeployed = False;
                	bFlyingDeployed = True;
                	bFlying = True;
                
                     bPCRelativeFPRotation=False;
                
                        GotoState('FlyingDeployed');
                    }
                }
                
                state FlyingUndeploying
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(HideSound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(HideForce);
                	}
                        Weapons[0].bForceCenterAim = False;
                        Weapons[0].PlayAnim('GotoGun');
                        sleep(2.03);
                        //Weapons[0].ProjectileClass=TimLotus.LotusPistolProjectile;
                    	bStationary = false;
                    	SetActiveWeapon(0);
                	bDeployed = False;
                	bFlyingDeployed = False;
                	bFlying = True;
                
                     bPCRelativeFPRotation=False;
                
                        GotoState('FlyingUndeployed');
                    }
                }
                
                state UnDeploying
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(HideSound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(HideForce);
                	}
                        Weapons[0].bForceCenterAim = False;
                        Weapons[0].PlayAnim('GotoGun');
                        sleep(2.03);
                        //Weapons[0].ProjectileClass=TimLotus.LotusPistolProjectile;
                    	bStationary = false;
                    	SetActiveWeapon(0);
                	bDeployed = False;
                	bFlyingDeployed = False;
                	bFlying = False;
                
                     bPCRelativeFPRotation=False;
                
                        GotoState('UnDeployed');
                    }
                }
                
                state Deploying
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	bStationary = false;
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(DeploySound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(DeployForce);
                	}
                        Weapons[0].PlayAnim('GotoSword');
                        //Weapons[0].ProjectileClass=TimLotus.DudProjectile;
                        sleep(2.03);
                        Weapons[0].bForceCenterAim = False;
                        SetActiveWeapon(0);
                	bWeaponisFiring = false; //so bots don't immediately fire until the gun has a chance to move
                	bDeployed = True;
                	bFlyingDeployed = False;
                	bFlying = False;
                
                     bPCRelativeFPRotation=False;
                
                        GotoState('Deployed');
                    }
                }
                
                state DeployedLiftoff
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	SetPhysics(PHYS_Flying);
                    	ServerPhysics = PHYS_Flying;
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(DeploySound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(DeployForce);
                	}
                        PlayAnim('LegsU');
                        MaxRiseForce = 300;
                   //     Weapons[0].PlayAnim('GotoSword',100);
                        Weapons[0].PlayAnim('GravDeploy');
                        sleep(2.03);
                
                	bEnableProximityViewShake = False;
                	bDeployed = False;
                	bFlyingDeployed = True;
                	bFlying = True;
                
                     bPCRelativeFPRotation=False;
                     bCanFly=True;
                     bCanBeBaseForPawns=False;
                
                        GotoState('FlyingDeployed');
                    }
                }
                
                state UndeployedLiftoff
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	SetPhysics(PHYS_Flying);
                    	ServerPhysics = PHYS_Flying;
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(DeploySound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(DeployForce);
                	}
                        PlayAnim('LegsU');
                        MaxRiseForce = 300;
                   //     Weapons[0].PlayAnim('GotoGun',100);
                        Weapons[0].PlayAnim('GravDeploy');
                        sleep(2.03);
                
                	bEnableProximityViewShake = False;
                	bDeployed = False;
                	bFlyingDeployed = False;
                	bFlying = True;
                
                     bPCRelativeFPRotation=False;
                     bCanFly=True;
                     bCanBeBaseForPawns=False;
                
                        GotoState('FlyingUndeployed');
                    }
                }
                
                state DeployedLand
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	SetPhysics(PHYS_Karma);
                    	ServerPhysics = PHYS_Karma;
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(DeploySound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(DeployForce);
                	}
                        PlayAnim('LegsD');
                        MaxRiseForce = 0;
                 //       Weapons[0].PlayAnim('GotoSword',100);
                        Weapons[0].PlayAnim('GravUndeploy');
                        sleep(2.03);
                
                	bEnableProximityViewShake = True;
                	bDeployed = True;
                	bFlyingDeployed = False;
                	bFlying = False;
                
                     bPCRelativeFPRotation=False;
                     bCanFly=False;
                     bCanBeBaseForPawns=True;
                
                        GotoState('Deployed');
                    }
                }
                
                state UndeployedLand
                {
                      function Tick(float deltatime) {
                             DeployedHeight -= deltatime;
                             Super.Tick( DeltaTime );
                     }
                Begin:
                    if (Controller != None)
                    {
                    	SetPhysics(PHYS_Karma);
                    	ServerPhysics = PHYS_Karma;
                    	if (PlayerController(Controller) != None)
                    	{
                	        PlayerController(Controller).ClientPlaySound(DeploySound);
                        	if (PlayerController(Controller).bEnableGUIForceFeedback)
                			PlayerController(Controller).ClientPlayForceFeedback(DeployForce);
                	}
                        PlayAnim('LegsD');
                        MaxRiseForce = 0;
                 //       Weapons[0].PlayAnim('GotoGun',100);
                        Weapons[0].PlayAnim('GravUndeploy');
                        sleep(2.03);
                
                	bEnableProximityViewShake = True;
                	bDeployed = False;
                	bFlyingDeployed = False;
                	bFlying = False;
                
                     bPCRelativeFPRotation=False;
                     bCanFly=False;
                     bCanBeBaseForPawns=True;
                
                        GotoState('Undeployed');
                    }
                }
                
                
                
                //We're all familiar with this simulated function!
                
                simulated function Tick(float DeltaTime)
                { 
                local float EnginePitch; 
                local float LinTurnSpeed; 
                local KRigidBodyState BodyState;
                local KarmaParams KP; 
                local bool bOnGround; 
                local int i;
                local int Division;
                local int Division2;
                local Emitter JumpEffect;
                
                
                //This is for animation rates on walking. Doesn't really affect anything.
                Division=500;
                Division2=1000;
                
                KP = KarmaParams(KParams);
                
                // Increase max karma speed if falling
                bOnGround = false;
                for(i=0; i<KP.Repulsors.Length; i++)
                {
                //log("Checking Repulsor "$i);
                if( KP.Repulsors[i] != None && KP.Repulsors[i].bRepulsorInContact )
                bOnGround = true;
                //log("bOnGround: "$bOnGround);
                }
                
                //Change physics and thrust, etc. if below 1000 deployedheight (i have absolutely no idea how much 1000 is ;) )
                if (DeployedHeight<1000) {
                KP.kMaxSpeed = MaxGroundSpeed;
                MaxThrustForce = 4000;
                MaxStrafeForce = 2000;
                MaxRiseForce = 0;
                bCanFly=False;
                bCanBeBaseForPawns=True;
                SetPhysics(PHYS_Karma);
                ServerPhysics = PHYS_Karma;
                KP.KActorGravScale = 1;
                }
                else {
                KP.kMaxSpeed = MaxAirSpeed;
                MaxThrustForce = 150;
                MaxStrafeForce = 100;
                MaxRiseForce = 200;
                bCanFly=True;
                bCanBeBaseForPawns=False;
                SetPhysics(PHYS_Flying);
                ServerPhysics = PHYS_Flying;
                KP.KActorGravScale = 0.01;
                }
                
                //I suppose this does something important.
                DeployedHeight += deltatime;
                
                //Switch between states if above or below certain heights
                if ( isInState('Deployed') && bFlying==false && DeployedHeight > 1000) {
                                  GotoState('DeployedLiftoff');
                        }
                
                if ( isInState('Undeployed') && bFlying==false && DeployedHeight > 1000) {
                                  GotoState('UndeployedLiftoff');
                        }
                
                if ( isInState('FlyingDeployed') && bFlying==True && DeployedHeight < 1000) {
                                  GotoState('DeployedLand');
                        }
                
                if ( isInState('FlyingUndeployed') && bFlying==True && DeployedHeight < 1000) {
                                  GotoState('UndeployedLand');
                        }
                        
                Super.Tick( DeltaTime ); 
                }
                This is what I think is relevant.
                The vehicle looks like it is only in one state, one of the flying ones.
                Deployed means using the swords.
                UnDeployed means using the pistols.
                Flying is, well, DUH!
                I commented out the "GotoGun" and "GotoSword" animations because I needed to test the Grav(Un)Deploy ones, etc.
                For some reason the Grav(Un)Deploy ones don't work.

                Comment


                  #9
                  No problems. I'll look at it in detail tomorrow.

                  Just now thow, I'm a little suspicious about this line:

                  Code:
                  //I suppose this does something important.
                  DeployedHeight += deltatime;
                  AFAIK, in Tick(), delta time is the amount of real time that passed between this tick and the last (thats just an assumption I made seeing as though Delta usually means the change in something, and seems to hold true every time I have used Deltatime in calculations). Based on this, what this is saying is that every tick, lets increase the minimum required height to deploy or whatever by DeltaTime. Basically, at the moment your code doesn't do a lot. I think.

                  I'm no genius, but if you want to detect the deployed height, you could do:

                  Code:
                  class Lotus extends ONSChopperCraft;
                  
                  var float DeployedHeight;
                  var float CurrentHeight;
                  var float MaxTraceHeight;
                  var Actor Ground; //this is global for a reason
                  
                  // other variables
                  
                  function GetHeight(float TraceLimit) //max distance is the maximum distance to trace downwards - make sure it is more than the DeployedHeight
                  {
                  	local vector HitLocation, HitNormal, End;
                  	
                  	End = Location;
                  	End.Z = Location.Z - TraceLimit; //sets the end of the trace to be TraceLimitunits directly below us 
                  	
                  	Ground = Trace(HitLocation, HitNormal, End, Location); //does the actual trace
                  	
                  	if ((Ground != None) && (HitActor == Level))
                  		CurrentHeight = Location.Z - HitLocation.Z; /* returns the distance between us and the ground 
                  											 		   (only if the hit actor was world geometry) */
                  }
                  
                  function Tick (float DeltaTime)
                  {
                  	//other stuff
                  	GetHeight(MaxTraceHeight);
                  	
                  	if ((Ground == None) || (CurrentHeight > DeployedHeight))
                  		GoToState('Whatever');
                  }
                  
                  //other functions and states
                  
                  defaultproperties
                  {
                  	DeployedHeight=4000
                  	MaxTraceHeight=2000
                  	//other properties
                  }
                  That should work in theory. Obviously you have to work it into your own code and not just use this (I'm sure you are smart enough to have figured that out already :P).

                  Oh and I noticed in your comments that you aren't sure how high DeployedHeight actually is. Open unrealed open Torlan. zoom out in one of the side views so that the central tower runs from the top of the viewport to the bottom. While holding down control, shift and the middle mouse button, drag in this view from the top of the torlan tower to the bottom. You will notice a little ruler appears with a little number. This number is the distance in unreal units. Co-incidentally, so is the DeployedHeight in unreal units! That should give you an idea of scale.

                  Comment


                    #10
                    Well how convenient DeployedHeight is in UUs. I just wasn't too sure at the time.

                    Error alert!!!

                    C:\UT2004\TimLotus\Classes\Lotus.uc(116) : Error, Bad or missing expression in parenthesis

                    Line 116:
                    if ((Ground != None) && (HitActor == Level))

                    Comment


                      #11
                      Sorry (I wrote that code at 3am :P)

                      change
                      if ((Ground != None) && (HitActor == Level))

                      to
                      if (Ground == Level)

                      sorry about that

                      Comment


                        #12
                        Good (sorta) news! Now it switches properly between states, and the Grav(Un)Deploy animations play! Of course not everything is proper yet :sour: (*cough* animation problems! *cough* and wrong anims playing *cough*). However, this got me past a major barrier! I should have few problems tweaking things out. Thanks MarZer! :up: I'll post again if I run into any more brick walls.

                        Comment


                          #13
                          No problem.

                          One improvement I would suggest is using a timer that goes off every 0.25 seconds to do GetHeight() instead of Tick as one trace on its own is a fast thing but many, many traces (like one every tick) is expensive. Doing one every quarter of a second would help keep performance neat whilst remaining effective. You should also add in checks to do GetHeight() only when the current position is not within a certain X, Y, Z distance of the last position recorded at the timer and only when the vehicle is occupied etc... these sorts of things really help with performance.

                          something like this (reworked version of the last code):
                          Code:
                          var float DeployedHeight;
                          var float CurrentHeight;
                          var float MaxTraceHeight;
                          var float TimerInterval;
                          var	float LocationBufferZ;
                          var	float LocationBufferXY;
                          
                          var vector LastLocation;
                          
                          var Actor Ground;
                          
                          function PostBeginPlay()
                          {
                          	//other stuff that happens on spawn
                          	LastLocation = Location;
                          	SetTimer(TimerInterval,true);
                          }
                          	
                          function GetHeight(float TraceLimit)
                          {
                          	local vector HitLocation, HitNormal, End;
                          	
                          	End = Location;
                          	End.Z = Location.Z - TraceLimit; 
                          	
                          	Ground = Trace(HitLocation, HitNormal, End, Location);
                          	
                          	if (Ground == Level) // <-----------------------//note this should be Level,  
                          		CurrentHeight = Location.Z - HitLocation.Z; //else the height will get calculated off 
                          		                                            //any vehicles that might be flying underneath!
                          }
                          
                          function Timer()
                          {
                          	if( (Abs(Location.Z - LastLocation.Z) >= LocationBufferZ) 
                          		|| (Abs(Location.X - LastLocation.X) >= LocationBufferXY)
                          		|| (Abs(Location.Y - LastLocation.Y) >= LocationBufferXY) )
                          			GetHeight(MaxTraceHeight);
                          	
                          	if ( ((Ground == None) || (CurrentHeight > DeployedHeight)) && (IsInState('OldState')) )
                          		GoToState('Whatever');
                          	
                          	LastLocation = Location;  //after doing GetHeight(), we refresh this value for the next timer to use
                          }
                          
                          defaultproperties
                          {
                          	DeployedHeight=4000
                          	MaxTraceHeight=2000
                          	TimerInterval=0.25
                          	LocationBufferZ=25 //because here Z change is more important than XY change
                          	LocationBufferXY=100	
                          }
                          Again, there are still some things you will have to add in yourself. These are just some ideas.

                          Note though, the changes I made to GetHeight(). Important stuff.

                          Comment


                            #14
                            Hmmm...The switching of modes seems very inconsistent. Sometimes it switches properly, sometimes it switches very very late in time, sometimes it doesn't switch at all, sometimes it switches back and forth without stopping to say hello. I suspect this has something to do with detection of height.

                            Comment


                              #15
                              That could be for any number of reasons... perhaps the trace height is not set long enough (adjust MaxTraceHeight), perhaps the trace is not being consistently resolved in time (try the Timer() solution I propsed above), perhaps you should introduce a delay time between the states so as to not instantly change states... lots of ideas...

                              Comment

                              Working...
                              X