Game Development Community

Adding a new state

by Sean T. Boyette · in Torque X Platformer Kit · 06/20/2007 (8:38 pm) · 6 replies

What would be the quickest way to add say a
AttackState to that plays a different animation?

#1
06/22/2007 (2:02 pm)
There's actually an ActionState on ActorAnimationManager for just that purpose. We saw the potential need for different activated action animations and added it.

It functions very similar to DamageState in that it will play through until the end and then return to IdleState to kinda reset itself (transitions from idle should be kinda universal anyway.. if you're using the transition system, that is).

Death and Damage will interrupt the action animation, so if you want your attack logic to be based on an animation frame, you might want to switch that around to have the attack go off even if you take damage.

By default, ActionState is registered with the string "action". When activated, the animation in the actor's ActionAnim property will be played. You can swap out the ActionAnim safely even as it's playing (though to go from one action to another, you would have to switch to Idle or something, and then back to Action.

As with DamageAnim (also transitions and the like), animations that cycle will break the state. Because it waits until the animation is finished to transition, any animation that cycles will cause you to get stuck in the state.
#2
06/23/2007 (9:44 pm)
Thomas,

Here is what I did - I think I am almost there.
In short - I want to
create a state : StandingFarLP and have that state play when I press "X" on the xb controller, and then return to idle.

Added to PlayerController.cs
in ProcessTick
if (move.Buttons[1].Pushed)
                {
                    foreach (StreetFighterActorComponent SFActor in Movers)
                        SFActor.StandingFarLP();
                }

Created a StreetFighterActorComponen to add just one state called StandingFarLP:
using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.T2D;
using GarageGames.Torque.XNA;
using GarageGames.Torque.PlatformerFramework;

namespace StreetFighterX
{
    class StreetFighterActorComponent : ActorComponent
    {
        #region Public properties, operators, constants, and enums
        public T2DAnimationData StandingFarLPAnim
        {
            get { return _StandingFarLPAnim; }
            set { _StandingFarLPAnim = value; }
        }
        #endregion
        #region Public methods
        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);

            StreetFighterActorComponent obj2 = obj as StreetFighterActorComponent;

            obj2.StandingFarLPAnim = StandingFarLPAnim;
        }
        // move method for gliding
        // (interface for controller)
        public virtual void StandingFarLP()
        {
            _StandingFarLP = true;
        }
        #endregion
        #region Private, protected, internal methods
        protected override void _createAnimationManager()
        {
            // create and assign animation manager
            _animationManager = new StreetFighterActorAnimationManager(this);

        }
        protected override void _initAnimationManager()
        {
        }
        #endregion
        #region Private, protected, internal fields
            protected bool _StandingFarLP;
            protected T2DAnimationData _StandingFarLPAnim;
        #endregion

        // derived animation manager with states modified to play glide animations
        public class StreetFighterActorAnimationManager : ActorAnimationManager
            {
                //======================================================
                #region Constructors

                public StreetFighterActorAnimationManager(StreetFighterActorComponent actorComponent)
                    : base(actorComponent)
                {
                    _actorComponent = actorComponent;
                }

                #endregion

                //======================================================
                #region Private, protected, internal methods

                protected override void _registerAnimStates()
                {
                    // register base states
                    base._registerAnimStates();

                    // register all our states
                    FSM.Instance.RegisterState<StandingFarLPState>(this, "StandingFarLP");

                    // set the initial state
                    //_currentState = FSM.Instance.GetState(this, "idle");
                }

                #endregion

                //======================================================
                #region Private, protected, internal fields

                private StreetFighterActorComponent _actorComponent;

                #endregion

                //======================================================
                #region Actor animation states
                public class StandingFarLPState : AnimationState
                {
                    public override void Enter(IFSMObject obj)
                    {
                        base.Enter(obj);

                        StreetFighterActorAnimationManager actorAnimMgr = obj as StreetFighterActorAnimationManager;

                        if (actorAnimMgr._actorComponent == null)
                            return;

                        actorAnimMgr._actorComponent._useAnimationManagerSoundEvents = false;
                    }

                    public override void Exit(IFSMObject obj)
                    {
                        base.Exit(obj);

                        StreetFighterActorAnimationManager actorAnimMgr = obj as StreetFighterActorAnimationManager;

                        if (actorAnimMgr._actorComponent == null)
                            return;

                        actorAnimMgr._actorComponent._useAnimationManagerSoundEvents = true;
                    }
                }
                #endregion
            }
    }
}
#3
06/24/2007 (5:43 pm)
You actually don't need an animation state for each action, you can just use the base ActorAnimationManger and change the action animation. The glide for the dragon was done in a seperate state because it is a looping state that needed smooth transitions to multiple different states. The bool flag is there because it needed to be turned on and off. In the case of activated actions, you normally wouldn't want a transition because it could lead to a sense of feedback lag on the player's input.

You can get away with just setting the action animation using the default ActorAnimationManager like so:
public virtual void StandingFarLP()
        {
            // set the current action animation
            ActionAnim = _standingFarLPAnimationData;

            // switch to the "action" state
            FSM.Instance.SetState(_animationManager, "action");

            // perform any specific game logic for this move
            [...]
        }

If you decide that you do want to make seperate states for different moves, you'll want to look at FSM.cs. It's got some tips on implementing states. Basically what you were missing is the Execute method for the state that switches it back to Idle and the call to the FSM manager to set the animation manager in that specific state.

It's much simpler to just use the action state.
#4
06/24/2007 (8:57 pm)
Thomas - Perfect!

Thanks!

I an running into waiting for an animations to end issue. (is this addressed via the animation manager?)
// The X Button
                if (move.Buttons[1].Pushed)
                {
                    if (!_xButton)
                    {
                        foreach (StreetFighterActorComponent SFActor in Movers)
                        {
                            if (crouching == true)
                            {
                                //SFActor.CrouchLP();
                            }
                            else if (jumping == true)
                            {
                                //SFActor.JumpLP();
                            }
                            else if (!crouching && !jumping)
                            {
                                SFActor.StandingFarLP();
                            }
                        }
                        _xButton = true;
                    }
                }
                else if (_xButton)
                {
                    _xButton = false;
                }
#5
06/25/2007 (9:08 am)
Yes, if I'm understanding the issue. Correct me if I'm wrong, but the problem is that you need the action animation to end early in certain circumstances, right?

Assuming you're using ActionState:
By default it only skips out before it's done if the actor is damaged or dies. You can change this by creating a derived ActionState class. You would only need to override the "Execute" method to modify the state change conditions. Check out FallState or JumpState on DragonActorComponent in the demo for an example of how to do this.

Post back if you have any more questions.

EDIT: You'd also need to register your derived state with the same string name as the original action state in your _registerAnimStates method.
#6
08/17/2010 (2:29 am)
Hello guys.

Thomas or Sean, can you put some example of this for us please?

We are looking for a attack state but we still can't implement this.

Thanks in advance.

Regards.