Search Unity

Question Animating the player ship in a vertical scrolling shooter

Discussion in '2D' started by AnjAvraam, May 10, 2020.

  1. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    I'm new to Unity and thought it might be a good idea to start a simple project so I can learn my way around the editor and get started on some basic C# scripting skills. So I decided to make a vertical scrolling shootemup.

    Rather frustratingly. sorting out the player ship's animations has me stumped. And this is after a week of scouring the internet and Unity forums for clues. I can only find instructions for platform games which don't apply to this and one forum thread that refers to buying a third party plugin to do it - surely that's excessive, and this is actually something that can be done in Unity or with C#, right?


    The goal is relatively modest:

    What I'm trying to do is animate a 2D spaceship, so when you pull to the side it appears to tilt (like a flying object not like a mouse pointer that always stays the same).

    I've already drawn the graphics (7 states of tilt including a default non-tilted state - that's 3 frames per side) but no method of animation I've come across allows for this simple sprite-swapping (that I imagine) to occur when the directions are input.


    The desired effect:
    • When the x axis is engaged (i.e. the player is holding the left or right arrow key) the 3-frame animation for tilting the ship to that side occurs, and it holds the last frame until the player lets go of that direction input - this will create the illusion that the ship is banking to that side.
    • The animation needs to pingpong back to the default position once the player stops pulling left or right (the ship levels out again when not being steered left or right - it doesn't just jolt right back to default as that would look weird).

    Un-desired effects:
    • The animation has to be able to be interrupted, i.e. be able to start reversing at whatever frame it's currently on because it will look weird if the player just momentarily taps a direction key and the whole animation plays through.
    • Also no sprite mirroring can be used (i.e. I don't want to set up the left sequence and mirror it for the right because then the highlights and shadows on the sprite graphics will flip sides very unnaturally, that's why I made 7 states alrogether).
    • I do not want the game to have analogue controls, I want it to be kinematic.
    An example of the sprite sheet I made is attached. It has the ship in its 7 positions and also has thruster (idling and flaring) and shot sprites (basic and powered-up).


    I am a Unity noob... but...

    I'm already OK with importing the sprite sheet, slicing it up, and with putting basic movement controls in via C# script and a 2D rigid body to the sprite. I can make basic frame-by-frame animation sequences in Unity but the in-build animation system I would prefer to avoid if possible.

    If anyone can help me find a solution to this I would be extremely grateful!


    Reference for type of behaviour I'm looking for:

    I'm unashamedly influenced by one of my favourite vertical scrolling shootemups of all time, Raiden, which you can check out here:
    . The player ships in Raiden have these tilting animations but they are more complex, with 5 frames per side instead of my 3.
     

    Attached Files:

  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Hi @AnjAvraam

    "I am a Unity noob... but..."

    So why not watch some official tutorials and read the docs first?

    Otherwise it will be painful guesswork.

    If you really are just starting, and don't even know all the available things, why not first learn about those?
    (like Animator state machine in this case)

    With Animator, you can setup a graph that does exactly what you described.
     
    AnjAvraam likes this.
  3. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    I did specify in the post that I've scoured all available sources for a week and found nothing that looked suitable. I should add that I've also been using a bit of trial and error involving Sprite Library and Sprite Resolver (but to no avail).

    Why don't you tell me a bit more about the method you had in mind, using a state machine?
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    There is nothing special, if you actually check out how animator works you have several options.
     
    AnjAvraam likes this.
  5. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    I have checked out how the animator works, and it seemed like overkill for my sprite to involve things like blend trees. I did say in my post if it can be done without using the in-built animator it would be better - this is because from my week of research I hit upon posts where people were saying that there's a known issue with getting the animations to cut off without playing the whole sequence (though what I read could be spurious or fixed in newer versions of Unity that have come out since then). To be clear are you saying there is a way to do it as described via Mecanim and it's still a better option than a code-based solution (in C#)? I'm genuinely trying to learn here.
     
  6. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    animator can do what you need to do quite well, for tilting left you need 4 states

    1) stable
    2) banking to side animation state
    3) fully tilted
    4)banking back to stable animation

    trigger these animations using animator.play

    animator.play also has parameters to pick in which frame you want your animation to start playing from so you can freely begin and end animations
     
    AnjAvraam and eses like this.
  7. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @AnjAvraam

    "I have checked out how the animator works, and it seemed like overkill"

    Overkill, when you only require 3-5 states? And 2-3 animation clips?

    "for my sprite to involve things like blend trees"

    Well that was my first though too. But you don't even need blend trees, if you just try to use animator first, you'll see that you have several options to create this.

    "from my week of research I hit upon posts where people were saying that there's a known issue with getting the animations to cut off without playing the whole sequence"


    If you have a link, I'm interested reading about this, but I haven't heard about such issue. However, there is an option called "has exit time" if this is ticked, then the animation clip plays until its exit moment, before transitioning to next state.

    "To be clear are you saying there is a way to do it as described via Mecanim and it's still a better option than a code-based solution (in C#)?"

    Yes - @brigas said pretty much what is needed - although, you don't even need that much; you can use reverse time of state for banking back, so you only need reverse state in that case for both left and right no clips as you use reverse time. You don't either need fully tilted state, just make the animation non-looping, and it will hold last frame.

    Alternative is to manually change sprite. When you get input, instead of raw input, use GetInput and finetune the speed to your liking. Then pick a suitable frame from an array or list based on normalized value of your input.
     
    brigas and AnjAvraam like this.
  8. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
  9. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    AnjAvraam likes this.
  10. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    Ah, great - thank you @brigas!
     
  11. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    (sorry couldn't resist, nice looking ship):

    ship.gif
     
    AnjAvraam likes this.
  12. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    @eses that looks fab! Thanks for the compliment too - my challenge is to get this working for myself tonight!
     
  13. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @AnjAvraam

    It is pretty much is done like described above, just keep an eye on those transition lengths and "has exit time". These are the usual suspects when something doesn't happen instantly. Good luck! And if you get stuck, ask again.
     
    AnjAvraam likes this.
  14. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    That's absolutely amazing @eses, I feel a lot more confident now. Cheers!
     
  15. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    Do you have an example of the syntax for animator.play @brigas? I've got my animations and transitions all set up in the animator (only Fly_left and Fly_right are relevant here) and I've tried everything I can think of in the script to call them up but it still won't work.

    If it helps, this is the part of the code that definitely works - purely the movement of the ship (no animation):

    Code (CSharp):
    1. public class Movement : MonoBehaviour {
    2.  
    3.     float maxSpeed = 5f;
    4.  
    5.     void Update() {
    6.              
    7.         Vector3 pos = transform.position;
    8.      
    9.         pos.x += Input.GetAxis("Horizontal") * maxSpeed * Time.deltaTime;
    10.      
    11.         pos.y += Input.GetAxis("Vertical") * maxSpeed * Time.deltaTime;
    12.      
    13.         transform.position = pos;
     

    Attached Files:

  16. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    Code (CSharp):
    1. public Animator anim;
    2.  
    3. ////
    4.  
    5. anim.Play("Fly_left");
    by the way with this method you dont need that transition setup, you can trigger everything with animator.play
     
    AnjAvraam likes this.
  17. AnjAvraam

    AnjAvraam

    Joined:
    Feb 7, 2018
    Posts:
    9
    Thanks @brigas, that's much appreciated!