Question for Unity 2.5d RPG Lectures

,

Im not sure if anyone else has had this issue.

I tried to use a custom sprite that has 8 direction animations. so i implemented four triggers, walkup, walkdown, walkleft and walkright.

The idea being that I would check the movement value and be able to check which way the player is moving, to play the appropriate animation.

The up anim works great, so does the down anim. However, when trying to walk upleft/right or down left/right the animator can not seem to use the triggers properly. Here is my code, im wondering if anyone might be able to help?

if (movement != Vector3.zero)
{
anim.SetBool(IS_WALK_PARAM, true);
WalkAnimSet(x, z);
}
else
{
anim.SetBool(IS_WALK_PARAM, false);
}

private void WalkAnimSet(float x, float z)
{

 anim.ResetTrigger(IS_WALK_L_PARAM);
 anim.ResetTrigger(IS_WALK_D_PARAM);
 anim.ResetTrigger(IS_WALK_U_PARAM);
 anim.ResetTrigger(IS_WALK_R_PARAM);

if (z != 0)
{
if (z < -0.001)
{
anim.ResetTrigger(IS_WALK_U_PARAM);
anim.SetTrigger(IS_WALK_D_PARAM);
}
else if (z > 0)
{
anim.ResetTrigger(IS_WALK_D_PARAM);
anim.SetTrigger(IS_WALK_U_PARAM);
}
}

if (x != 0)
{
if (x < -0.001)
{
anim.ResetTrigger(IS_WALK_R_PARAM);
anim.SetTrigger(IS_WALK_L_PARAM);
}
else if (x > 0)
{
anim.ResetTrigger(IS_WALK_L_PARAM);
anim.SetTrigger(IS_WALK_R_PARAM);
}
}

In this case, I think you’ll find a 2D Blend Tree will work far better for your purposes.
Put the sprite for each movement direction in the appropriate corners for their direction…

Left/Up = -1,1
Up = 0,1
Right/Up = 1,1
Left = -1,0
Idle = 0,0
Right = 1,0
Left/Down = -1,-1
Down = 0,-1
Right/Down = 1,-1

The graph should look now have dots representing the animations in a 3x3 pattern evenly spaced with idle being at the center.

Then your parameters (float) will be Right and Up
Simply pass Right the X value and Up the Z value you've fed to WalkAnimSet to right and Up with SetFloat.  If there is no movement, the idle will be selected automatically.

so you would feed the float value of x into the float trigger"right" and the float value of y(z) into the float trigger up?

What is the “blend” float trigger used for?
{4F30A73B-87EF-4B03-B9C1-5F0DC795B6B0}

yeah unfortunately that doesnt seem to be doing it either. I just get a static sprite with no animation.

private void WalkAnimSet(float x, float z)
{

    anim.SetFloat("Right", x);
    anim.SetFloat("Up", z);
}

 void Update()
 {
     
     float x = playerControls.Player.Move.ReadValue<Vector2>().x;     
     float z = playerControls.Player.Move.ReadValue<Vector2>().y;
     movement = new Vector3(x, 0, z).normalized;

     WalkAnimSet(x, z);
     
 }

The blend was created automagically when you first create the Blend Tree… it can be deleted.

Start with the positions… you’re getting the x and y from your playercontrols, and when you build the movement vector, you’re normalizing the Vector. This is correct for the physical movement, but you’re feeding the original x and z values (not normalized) to WalkAnimSet, and ultimately to the Animator.

What we’re going to want in the Animator is for those diagonal directions to be whole numbers… i.e. WalkUpLeft == -1,1, walkupRight = 1,1 etc. This will line up with the input.

I’m not sure that’s your immediate problem, however. Make sure that the default state is the state holding this blend tree, or it may never run.

You can see an example setup in this YouTube video… in this case, he’s only using the cardinal directions (Up, Down, Left, and Right), but the principles are the same.

i seem to be misunderstanding something fundamental here. From what I can see, logic wise. my update process checks the current frame’s x and y movement values, it then normalises this into a vector 3 which it then uses to calculate (in fixed update) where my player object needs to move.
before fixed update is called, I am sending those values to my animator to set the animators float triggers (Up and right)
I have tried both normalised (movement = new Vector3(x, 0, z).normalized;) values
and raw ( float x = playerControls.Player.Move.ReadValue().x;) to calculate this, and still no difference. the sprite shows the first frame of the animation its supposed to, and stays like that till i change direction or stop moving.

So im still no solved. |I’ve checked the you tube video he mentioned he uses the OnMove function, which, for whatever reason, is not implemented in the course?

It might be easier if I take a closer look at the project to see if I can tell what’s going on. Andrew’s code definitely wasn’t set up to handle 8 way animations, but this method has worked for me before.

Zip up your project and upload it to https://gdev.tv/projectupload and I’ll take a look. Be sure to remove the Library folder and any build folders to conserve space.

ok will do. thank you Brian. Im sure its something simple i missed

I made a couple of small changes to get this up and running…

First, there is already an idle animation at position 0,0 in the Blend Tree, so rather than switching states let’s just let the Blend Tree handle it… With that, I deleted the IsMoving boolean value.

Next, I made a slight change to the code to assign the values in PlayerController:

    private void WalkAnimSet(float x, float y)
    {
        if (Mathf.Approximately(x, 0)) x = 0; else x = Mathf.Sign(x);
        if (Mathf.Approximately(y,0)) y = 0; else y = Mathf.Sign(y);


        anim.SetFloat("Right", x);
        anim.SetFloat("Up", y);

        //Debug.Log($" XAXIS {movement.x},\n ZAXIS {movement.z}"); 
        //if (z != 0)
        //{
        //    if (z < -0.001)
        //    {
        //        anim.ResetTrigger(IS_WALK_U_PARAM);
        //        anim.SetTrigger(IS_WALK_D_PARAM);
        //    }
        //    else if (z > 0)
        //    {
        //        anim.ResetTrigger(IS_WALK_D_PARAM);
        //        anim.SetTrigger(IS_WALK_U_PARAM);
        //    }
        //}

        //if (x != 0)
        //{
        //    if (x < -0.001)
        //    {
        //        anim.ResetTrigger(IS_WALK_R_PARAM);
        //        anim.SetTrigger(IS_WALK_L_PARAM);
        //    }
        //    else if (x > 0)
        //    {
        //        anim.ResetTrigger(IS_WALK_L_PARAM);
        //        anim.SetTrigger(IS_WALK_R_PARAM);
        //    }
        //}

    }

Mathf.Approximately filters out 0 results, and Mathf.Sign returns a 1 or -1, so depending on the value for each, it will be set to exactly -1, 0, or 1, which is where our landing point is for the various sprites.

Give it a go and let me know how it went.

well… i think i found the problem and it does seem to be one of the simplest things i missed. These were all set to 0.01 before. I think that mixed with your much more efficient solution for computing movement triggers has fixed it.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms