Legacy:UScriptAnimPawn - Unreal Wiki

# Legacy:UScriptAnimPawn

### From Unreal Wiki, The Unreal Engine Documentation Site

### UScript Controlled Animation Pawn

For those interested in creating pawns whose animations are controlled through UScript instead of native code, the following code will provide a base from which you can edit. It is simply the native animation source code rewritten in UScript (c++ source available in the 3186 uscript source). The following code behaves almost exactly the same as the native code (slight difference in rotation yaw, will edit once tracked down). It would probably be beneficial to performance to place the call to UpdateMovementAnimation function in the AnimEnd event as it was back in original UT. -Meowcat

    class UScriptAnimPawn extends SomeOtherPawnClass;// SomeOtherPawnClass will typically be xPawn

    // added to get around the const values normally set by the native code
    var bool bFootTurning;
    var bool bFootStill;
    var int  iFootRot;
    var int  iTurnDir;
    var int SmoothViewPitch, SmoothViewYaw;// These two are only needed if this code is for UT2003, UT2004 pawn code already has them

    simulated function Tick(float DeltaTime)
    {
          if(!bPhysicsAnimUpdate) UpdateMovementAnimation(DeltaTime);//added to allow switching between native and scripted animation
          super.tick(deltatime);
    }

    // Epic C++ animation code converted to uscript

    simulated function UpdateMovementAnimation( FLOAT DeltaSeconds )
    {
        if ( Level.NetMode == NM_DedicatedServer )
                    return;
        if( bPlayedDeath )
            return;

        if (Level.TimeSeconds - LastRenderTime > 1.0)
        {
            iFootRot = Rotation.Yaw;
            bFootTurning = false;
            bFootStill = false;
            return;
        }

        BaseEyeHeight = Default.BaseEyeHeight;

        if ( bIsIdle && Physics != OldPhysics )
        {
            bWaitForAnim = false;
        }

        if ( !bWaitForAnim )
        {
            if ( Physics == PHYS_Swimming )
                {
                BaseEyeHeight *= 0.7f;
                UpdateSwimming();
                }
            else if ( Physics == PHYS_Falling || Physics == PHYS_Flying )
            {
                BaseEyeHeight *= 0.7f;
                UpdateInAir();
            }
            else if ( Physics == PHYS_Walking || Physics == PHYS_Ladder )
            {
                UpdateOnGround();
            }
        }
            else if ( !IsAnimating(0) )
                    bWaitForAnim = false;

        if ( Physics != PHYS_Walking )
            bIsIdle = false;

        OldPhysics = Physics;// OldPhysics is not const and can be changed in UScript
        //OldVelocity = Velocity;// is a const, may be used in the ModifyVelocity function!!

        if (bDoTorsoTwist)
            UpdateTwistLook( DeltaSeconds );
    }

    simulated function UpdateSwimming()
    {
        if ( (Velocity.X*Velocity.X + Velocity.Y*Velocity.Y) < 2500.0f )
            PlayAnim(IdleSwimAnim, 1.0f, 0.1f, 0);
        else
                PlayAnim(SwimAnims[Get4WayDirection()], 1.0f, 0.1f, 0);
            //PlayAnim(0, SwimAnims[Get4WayDirection()], 1.0f, 0.1f, true);// native anim call
    }

    simulated function UpdateInAir()
    {
       local Name NewAnim;
       local  bool bUp, bDodge;
       local  float DodgeSpeedThresh;
       local int Dir;
       local  float XYVelocitySquared;

        XYVelocitySquared = (Velocity.X*Velocity.X)+(Velocity.Y*Velocity.Y);

        bDodge = false;
        if ( OldPhysics == PHYS_Walking )
        {
            DodgeSpeedThresh = ((GroundSpeed*DodgeSpeedFactor) + GroundSpeed) * 0.5f;
            if ( XYVelocitySquared > DodgeSpeedThresh*DodgeSpeedThresh )
            {
                bDodge = true;
            }
        }

        bUp = (Velocity.Z >= 0.0f);

        if (XYVelocitySquared >= 20000.0f)
        {
            Dir = Get4WayDirection();

            if (bDodge)
            {
                NewAnim = DodgeAnims[Dir];
                bWaitForAnim = true;
            }
            else if (bUp)
            {
                NewAnim = TakeoffAnims[Dir];
            }
            else
            {
                NewAnim = AirAnims[Dir];
            }
        }
        else
        {
            if (bUp)
            {
                NewAnim = TakeoffStillAnim;
            }
            else

            {
                NewAnim = AirStillAnim;
            }
        }

            if ( NewAnim != GetAnimSequence() )
        {
        // have not quite added this yet.  Will edit later -meowcat
        //if ( PhysicsVolume->Gravity.Z > 0.8f * (Cast<APhysicsVolume>(PhysicsVolume->GetClass()->GetDefaultActor()))->Gravity.Z )
            //    PlayAnim(0, NewAnim, 0.5f, 0.2f, false); // native anim call
                    //else
                    LoopAnim(NewAnim, 1.0f, 0.1f, 0);
                //PlayAnim(0, NewAnim, 1.0f, 0.1f, false); // native anim call
        }
    }

    simulated function UpdateOnGround()
    {
        // just landed
        if ( OldPhysics == PHYS_Falling || OldPhysics == PHYS_Flying )
        {
            PlayLand();
        }
        // standing still
        else if ( Vsize(Velocity*Velocity) < 2500.0f  )  /*&& Acceleration.SizeSquared() < 0.01f*/
        {
            if (!bIsIdle || bFootTurning || bIsCrouched != bWasCrouched)
            {
                IdleTime = Level.TimeSeconds;
                PlayIdle();
            }
            PlayIdle();// added this playIdle to force the code to update whatever animation was playing, otherwise the turning anim could potentially continue to loop
            bWasCrouched = bIsCrouched;
            bIsIdle = true;
        }
        // running
        else
        {
            if ( bIsIdle  )
                bWaitForAnim = false;

            PlayRunning();
            bIsIdle = false;
        }
    }

    simulated function PlayIdle()
    {
        if (bFootTurning)
        {
            if (iTurnDir == 1)
            {
                if (bIsCrouched)
                    LoopAnim(CrouchTurnRightAnim, 1.0f, 0.1f, 0);
                else
                        LoopAnim(TurnRightAnim, 1.0f, 0.1f, 0);
            }
            else
            {
                if (bIsCrouched)
                        LoopAnim(CrouchTurnLeftAnim, 1.0f, 0.1f, 0);
                else
                        LoopAnim(TurnLeftAnim, 1.0f, 0.1f, 0);
            }
        }
        else
        {
            if (bIsCrouched)
            {
                LoopAnim(IdleCrouchAnim, 1.0f, 0.1f, 0);
            }
            else
            {
                if (PlayerController(controller)!=none &&  PlayerController(controller).bIsTyping )
                        PlayAnim(IdleRestAnim, 1.0f, 0.2f, 0);
                else if ( (Level.TimeSeconds - IdleTime < 5.0f) && IdleWeaponAnim != '')
                {
                    LoopAnim(IdleWeaponAnim, 1.0f, 0.25f, 0);
                }
                else
                {
                        LoopAnim(IdleRestAnim, 1.0f, 0.25f, 0);
                }
            }
        }
    }

    simulated function PlayRunning()
    {
        local Name NewAnim;
        local int NewAnimDir;
        local float AnimSpeed;

        NewAnimDir = Get4WayDirection();

        AnimSpeed = 1.1f * Default.GroundSpeed;
        if (bIsCrouched)
        {
            NewAnim = CrouchAnims[NewAnimDir];
            AnimSpeed *= CrouchedPct;
        }
        else if (bIsWalking)
        {
            NewAnim = WalkAnims[NewAnimDir];
            AnimSpeed *= WalkingPct;
        }
        else
        {
            NewAnim = MovementAnims[NewAnimDir];
        }
        LoopAnim(NewAnim, (Vsize(Velocity)) / AnimSpeed, 0.1f, 0);
        //PlayAnim(0, NewAnim, Velocity.Size() / AnimSpeed, 0.1f, true); // native anim call
    }

    simulated function PlayLand()
    {
        if (!bIsCrouched)
        {
            PlayAnim(LandAnims[Get4WayDirection()], 1.0f, 0.1f, 0);
            bWaitForAnim = true;
        }
    }

    simulated function UpdateTwistLook( float DeltaTime )
    {
        local int look, Update, UpdateB, PitchDiff, t, YawDiff;

        if ( !bDoTorsoTwist || (Level.TimeSeconds - LastRenderTime > 0.5f) )
        {
                    SmoothViewPitch = ViewPitch;
                    SmoothViewYaw = Rotation.Yaw;
            iFootRot = Rotation.Yaw;
            bFootTurning = false;
            bFootStill = false;
        }
        else
        {
                    YawDiff = (Rotation.Yaw - SmoothViewYaw) & 65535;
                    if ( YawDiff != 0 )
                    {
                            if ( YawDiff > 32768 )
                                    YawDiff -= 65536;

                            Update = int(YawDiff * 15.f * DeltaTime);
                            if ( Update == 0 ){
                                    //Update = (YawDiff > 0) ? 1 : -1;
                                    if (YawDiff>0) Update=1;
                                    else Update= -1;
                            }
                            SmoothViewYaw = (SmoothViewYaw + Update) & 65535;
                    }
                    t = (SmoothViewYaw - iFootRot) & 65535;
            if (t > 32768)
                            t -= 65536;

            if (((Velocity.X * Velocity.X) + (Velocity.Y * Velocity.Y)) < 1000 && Physics == PHYS_Walking)
            {
                if (!bFootStill)
                {
                    bFootStill = true;
                                    SmoothViewYaw = Rotation.Yaw;
                    iFootRot = Rotation.Yaw;
                                    t = 0;
                }
            }
            else
            {
                if (bFootStill)
                {
                    bFootStill = false;
                    bFootTurning = true;
                }
            }

            if (bFootTurning)
            {
               if (t > 12000)
                {
                    iFootRot = SmoothViewYaw - 12000;
                    t = 12000;
                }
                else if (t > 2048)
                {
                    iFootRot += 16384*DeltaTime;
                }
                else if (t < -12000)
                {
                    iFootRot = SmoothViewYaw + 12000;
                    t = -12000;
                }
                else if (t < -2048)
                {
                    iFootRot -= 16384*DeltaTime;
                }
                else
                {
                    if (!bFootStill)
                        t = 0;
                    bFootTurning = false;
                }
                iFootRot = iFootRot & 65535;
            }
            else if (bFootStill)
            {
                if (t > 10923)
                {
                    iTurnDir = 1;
                    bFootTurning = true;
                }
                else if (t < -10923)
                {
                    iTurnDir = -1;
                    bFootTurning = true;
                }
            }
            else
            {
                t = 0;
            }
                    PitchDiff = (256*ViewPitch - SmoothViewPitch) & 65535;
                    if ( PitchDiff != 0 )
                    {
                            if ( PitchDiff > 32768 )
                                    PitchDiff -= 65536;

                            UpdateB = int(PitchDiff * 5.f * DeltaTime);
                            if ( UpdateB == 0 ){
                                    //Update = (PitchDiff > 0) ? 1 : -1;
                                    if (PitchDiff>0) UpdateB=1;
                                    else UpdateB= -1;
                            }
                            SmoothViewPitch = (SmoothViewPitch + UpdateB) & 65535;
                    }
                    look = SmoothViewPitch;
            if (look > 32768)
                            look -= 65536;
            //call this native function to actually update the pawn's torso twist
            SetTwistLook(t, look);
            //td_SetTwistLook(t, look);// or call an edited version of the settwistlook so that you can alter how the rotation is applied
        }
    }

    simulated function td_SetTwistLook( int twist, int look)
    {
        local rotator r;
        if (!bDoTorsoTwist)
            return;

            r.Yaw=-twist + SmoothViewYaw - Rotation.Yaw;
        SetBoneRotation(RootBone, r, 0, 1.0f);

        r.Yaw = -twist / 3;
        r.Pitch = 0;
        r.Roll = look / 4;
        SetBoneDirection(HeadBone, r, Vect(0.0f,0.0f,0.0f), 1.0f, 0);
        SetBoneDirection(SpineBone1, r, Vect(0.0f,0.0f,0.0f), 1.0f, 0);
        SetBoneDirection(SpineBone2, r, Vect(0.0f,0.0f,0.0f), 1.0f, 0);
    }

    defaultproperties
    {
        bDoTorsoTwist=true
        bPhysicsAnimUpdate=false
    }

##### Views

- Legacy
- Discussion
- Current revision

##### Search