Announcement

Collapse
No announcement yet.

Pawn Wall walking and directional gravity

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

    #16
    what about bCrawler in the Pawn class?

    Comment


      #17
      I've tried enabling that, it doesnt do anything. My pawns physics is set to PHYS_Spider that might be why but I've tried it with PHYS_Walking too, still no effect.

      EDIT: I feel that someone must know how to do this; Orientate the pawn so that its feet are on the surface using the normal of that surface from Pawn.Floor?

      Because obviously my

      BaseRot = Rotator(Pawn.Floor);
      BaseRot.Pitch -= 16384;

      doesnt work properly.

      Comment


        #18
        There are two possible causes that I can think of:

        1) Pawns may use some sort of tracing algorithm to determine foot placement - this is common in most games, although I believe that UT3 didn't use it, on the proviso that the game was fairly fast paced and thus wasn't all that noticeable anyway.

        2) The most likely problem. Collision cylinders don't rotate, so when your player is sideways on a wall, his collision cylinder doesn't rotate to follow him. You cannot solve this problem, only work around it.

        Comment


          #19
          I worked on ledge climbing, not exactly wall walking. What I did is modifying the AnimTree, adding new bone controllers to the feet. The new bone controllers are used in aligning pawn feet against the wall. I used existing hip & root bone controllers to control pawn's rotation (reference frame can be chosen in bone controller).
          This maybe not an easy/correct way to do.

          Comment


            #20
            Originally posted by ambershee View Post
            2) The most likely problem. Collision cylinders don't rotate, so when your player is sideways on a wall, his collision cylinder doesn't rotate to follow him. You cannot solve this problem, only work around it.
            This second issue I am already aware of, it makes the pawns legs go into the wall. I haven't yet attempted to solve this, but were you suggesting this has something to do with the rotation problem or just pointing out that theres more headache to come?

            Peam if I were to add the modifications to the AnimTree how would I use the bone controllers to calc the needed rotation?

            Comment


              #21
              Originally posted by mwadelin View Post
              The pawn orientates to the floor fine, but obviously now I cant do the additional rotation.
              http://www.youtube.com/watch?v=WPKQoR5XFU8
              Well, in this video, it looks like the only problem is the sinking into the wall issue? The collision cylinder is a pain though, you cannot make it rotate with the player - you'll have to define custom collision for your pawn.

              Originally posted by peam View Post
              I worked on ledge climbing, not exactly wall walking. What I did is modifying the AnimTree, adding new bone controllers to the feet. The new bone controllers are used in aligning pawn feet against the wall. I used existing hip & root bone controllers to control pawn's rotation (reference frame can be chosen in bone controller).
              This maybe not an easy/correct way to do.
              I've just started looking at and playing with animation trees, and would love to see how this is set up, if you don't mind sharing?

              Comment


                #22
                Originally posted by mwadelin View Post
                Well my base rotation is calculated using the floor normal.

                BaseRot = Rotator(Pawn.Floor);
                BaseRot.Pitch -= 16384;

                How does your sonic GDK do it, as I guess you pawn uses the surface normal to orientate itself.
                When dealing with walls and ceilings, you can't use only 1 vector as a reference, you need 2 at least.

                Floor normal vector would be the local Z axis and the controller face rotation would be the local X axis; then you get the local Y axis with cross product and make a rotator.

                Code:
                local vector X,Y,Z;
                
                Z = Pawn.Floor;
                X = vector(Controller.Rotation);
                Y = Z cross X;
                
                BaseRot = OrthoRotation(X,Y,Z);

                Comment


                  #23
                  Originally posted by ambershee View Post
                  Well, in this video, it looks like the only problem is the sinking into the wall issue? The collision cylinder is a pain though, you cannot make it rotate with the player - you'll have to define custom collision for your pawn.
                  Ah, yeah I'm completely aware of that. No idea how I'm going to approach that yet. I may just change the collision to a sphere with a diameter of the pawns height, so regardless of what surface I'm on he shouldn't end up burred in the wall.

                  Xaklse I'm gonna give that a go now and see what happens. Currently my controller doesnt rotate with player input so ill have to update that.

                  EDIT: Oh and thanks a lot guys, you've been really helpful.

                  Comment


                    #24
                    I'd probably use a collision mesh, a sphere is a dodgy representation for a player.

                    Comment


                      #25
                      Yeah your right, there would be a whole lot of space in front and behind the pawn colliding with things before the pawn got to them.

                      I'm still a noob to UDK, how would I set up a collision mesh instead of a cylinder?

                      This is what I have at the minute btw:
                      Code:
                          Mesh=InitialSkeletalMesh;
                          Components.Add(InitialSkeletalMesh); 
                      	CollisionType=COLLIDE_BlockAll
                      	Begin Object Name=CollisionCylinder
                      		CollisionRadius=+0023.000000
                      		CollisionHeight=+0050.000000
                      	End Object
                      	CylinderComponent=CollisionCylinder

                      Comment


                        #26
                        If you just control root rotation, there is no need to modify the AnimTree.
                        Use RootRotControl of UDKPawn for May UDK. In previous releases, it is in UTPawn.
                        Controlling bone, you can freely choose its rotation space, for example: World, Actor, Bone, etc. It also interpolates rotation for you as well.

                        Comment


                          #27
                          Right I think its solved. The problem was bRollToDesired defaults to false. Therefore the pawn wouldn't roll at all. So the quaternion would give you a Yaw Pitch and Roll correctly and you'd SetRotation(NewRot), but it would come out all wrong because the pawn would completel disregard the roll of the rotator.

                          This is why the base rotation would work without the quaternion.

                          So SET bRollToDesired to TRUE.

                          I would use your method Xaklse of using the controllers rotation as the facing direction but with my sidescroller it uses a fixed controller rotation as the axes which the pawn runs along.

                          So that aStrafe always makes the player run left and right, and aForward makes them climb up and down.

                          Now for the collision problem....

                          Comment


                            #28
                            mwadelin how move pawn?
                            I can turn pawn.
                            Code:
                            function TurnLeft(float DeltaTime)
                            {
                            	local Rotator NewRot;
                            
                            	NewRot = Rotation;
                            	NewRot.Yaw += DeltaTime * 4096;
                            	SetDesiredRotation(NewRot);
                            }
                            I can move pawn.
                            Code:
                            function GoForward(float DeltaTime)
                            {
                            	local Vector MoveDiff;
                            	
                            	MoveDiff = Vect(0.0,0.0,0.0);
                            	MoveDiff.X = DeltaTime * 64;
                            	Move(MoveDiff);
                            }
                            Pawn turned but dont change axes. Again move same axes. I use Pawn.Move function. What another method. Dou you know?
                            How can we solve?

                            Comment


                              #29
                              Hey mwadelin, Im currently working on something that will require something similar to this. But if its not too much to ask would you be able to post up a tutorial or something about how to implement the phys_spider on the pawn to get the walking on the ceiling?

                              Thanks heaps if that's possible.

                              Comment


                                #30
                                @TechElv: Have a look at the PlayerMove() function in PlayerController or UDKController cant remember which. Also yours may not be working because you're using a vector with 0,0,0 so basically a vector of size 0. If it has no magnetude you can multiply it by any number under the sun, you won't be able to move.

                                @DrAbacus: I will eventually try and get a tutorial put together but at the minute its not 100% working as you might notice on some of the videos that the pawn ends up in the wall on surfaces that aren't parallel to the regular floor normal. This is a collision problem I'm working on. Ill get you started on the right track though.

                                My custom player controller extends UDKPlayerController. In which I have overridden the PlayerWalking state wity my own. I then used the BeginState event to set the physics.

                                Code:
                                state PlayerWalking
                                {
                                	event BeginState(Name PrevState)
                                	{	
                                		// Make sure physics are set to spider
                                		Pawn.SetPhysics(PHYS_Spider);
                                	}
                                }
                                Also within that state if you've going to do a side-on scroller like I plan to, you need to write your own PlayerMove() function. My PLayerMove funciton uses the Controllers rotation to get the axes which the player will move along.

                                Code:
                                	function PlayerMove( float DeltaTime )
                                	{
                                		local vector            NewAccel;
                                		local eDoubleClickDir   DoubleClickMove;
                                		local bool              bSaveJump;
                                		local vector			AxisX, AxisY, AxisZ; /** Unit vectors representing the controllers local axes */
                                
                                		// Calculate the axis the player is to run along
                                		GetAxes(Rotation,AxisX,AxisY,AxisZ);
                                
                                		// Mupltipy the axis directions by the input values
                                		NewAccel = PlayerInput.aForward*AxisZ + PlayerInput.aStrafe*AxisY;
                                		// normalise and multiply by the acceleration rate of the pawn
                                		NewAccel = Pawn.AccelRate * Normal(NewAccel);
                                
                                		DoubleClickMove = PlayerInput.CheckForDoubleClickMove( DeltaTime/WorldInfo.TimeDilation );
                                
                                		bDoubleJump = false;
                                
                                		// Jumping code
                                		if( bPressedJump && Pawn.CannotJumpNow() )
                                		{
                                			bSaveJump = true;
                                			bPressedJump = false;
                                		}
                                		else
                                		{
                                			bSaveJump = false;
                                		}
                                
                                		// Move the pawn as normal
                                		ProcessMove(DeltaTime, NewAccel, DoubleClickMove, Rotation);
                                
                                		// Updates pawns rotation
                                		UpdateRotation( DeltaTime );
                                
                                		bPressedJump = bSaveJump;
                                	}
                                Take note that my Controller (currently) does not rotate with player input at all. This is so that it always runs along left and right in the same direction at all times.

                                This should get you started but beware that it will probably struggle to climb on slopes, this is because the controller doesnt rotate at the minute but I will sort this eventually.

                                Also to make the pawn jump and fall back to the surface it jumped from your going to need to change your pawn's physics when it jumps from PHYS_Spider to PHYS_Flying and implement your own gravity. In your own pawn you can override the DoJump function to make the initial jump work properly and to set it ready to fall.

                                Code:
                                function bool DoJump( bool bUpdating )
                                {
                                	if (bJumpCapable && !bIsCrouched && !bWantsToCrouch && (Physics == PHYS_Walking || Physics == PHYS_Ladder || Physics == PHYS_Spider))
                                	{
                                		if ( Physics == PHYS_Spider )
                                			Velocity += JumpZ * Floor; // THIS WAS EDITED
                                
                                               SetPhysics(PHYS_Falling);
                                
                                		return true;
                                	}
                                	return false;
                                }
                                Note these two parts:

                                This was originally Velocity = ........
                                This meant that any momentum the pawn already had from running is lost and replaced with just the jump. Now its made so you can run and jump.
                                Code:
                                Velocity += JumpZ * Floor;
                                This bit normally is SetPhysics(PHYS_Falling) but the falling physics state is hardcoded in C++ to fall in the world Z axis only and theres no way of changing this. So I changed it to go to a custom state I made for my pawn.
                                Code:
                                GotoState('PawnFalling');
                                This is the custom pawn falling state
                                Code:
                                state PawnFalling
                                {
                                	event BeginState(Name PrevName)
                                	{
                                		// If no destination pawn falls back to the same floor
                                		if(FallDirection == vect(0,0,0))
                                			FallDirection = -Floor;
                                
                                		// Direct hit wall enabled just for the custom falling
                                		bDirectHitWall = true;
                                
                                		// flying instead of Falling as flying allows for custom gravity
                                		SetPhysics(PHYS_Flying);
                                	}
                                
                                	event Tick(float DeltaTime)
                                	{	
                                		// continue normal updates
                                		super.Tick(DeltaTime);
                                
                                		// Apply Gravitational Force
                                		ApplyGravity(DeltaTime);
                                	}
                                
                                	/** Adds gravity to the velocity based on floor normal pawn was last on */
                                	function ApplyGravity(float DeltaTime)
                                	{
                                		local Vector Gravity;
                                
                                		Gravity =
                                			FallDirection * WorldInfo.WorldGravityZ * CustomGravityScaling * DeltaTime;
                                
                                		// Add force to velocity
                                		Velocity += Gravity;
                                	}
                                
                                	// called when the pawn lands or hits another surface
                                	event HitWall(Vector HitNormal,Actor Wall, PrimitiveComponent WallComp)
                                	{
                                		// switch pawn back to standard state
                                		GotoState('');
                                	}
                                
                                	event EndState(Name NextState)
                                	{
                                		FallDirection = vect(0,0,0); // CLEAR DESTINATION FLOOR
                                		bDirectHitWall = false; 
                                		SetPhysics(PHYS_Spider); // "Glue" back to surface
                                	}
                                }
                                The FallDirection is simply a vector var I added to the pawn, which if set makes the pawn fall in that direction, this is essentially our direction of gravity. When used with jumping though you leave the FallDirection at 0,0,0 and the pawn will auto fall back to the floor it jumped from.

                                I havn't put everything I've done up yet as I'm just writting this as I go but I may do a proper tut if/when I get everything working.

                                Hope this helps

                                Comment

                                Working...
                                X