Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Asy1umrat · Oct 02, 2012 at 03:56 PM · animation2dmovementcontroller

Help with Top-Down Controls using 2D Toolkit

I am attempting to make a top-down game using the 2D Toolkit.

I am looking for a controls that "I press LEFT. While he is walk it is not possible to press any other key." After the button is released, it should play the "animation" for idle in each direction (1 frame each). While the player is walking they should not be able to interrupt the current walk animation.

Forward Walk: 4 frames/4 Frame rate, Up Walk: 4 frames/4 Frame rate, Left Walk: 2 Frames/8 Frame rate, Right Walk: 2 Frames/8 Frame rate

also, as you hold the movement button, the animation should loop, which at the moment it fails to do, only showing the first and last frames when press/holding and releasing, respectively.

At the moment I am attempting to get my controller working properly, playing different walking animations based on which direction the character is moving. Problems include if multiple buttons are pressed the incorrect animation will play. I have been attempting to rebuild from scratch:

using UnityEngine; using System.Collections;

 public class Animation_Controler : MonoBehaviour 
 {
     tk2dAnimatedSprite anim;
     float speed = 0.25f;
     int lastButtonPress = 2;
 
     // Use this for initialization
     void Start () 
     {
         anim = GetComponent<tk2dAnimatedSprite>();
     }
 
 
     // Update is called once per frame
     void Update () 
     {
         //Moving Animations
         if (Input.GetKey(KeyCode.UpArrow))
         {
             transform.Translate(0,0,speed * Time.deltaTime,Space.World);
             if (Input.GetKeyDown(KeyCode.UpArrow))
             {
                 anim.Play("Walk_Up");
             }
             lastButtonPress = 0;
         }
         
         else if (Input.GetKey(KeyCode.LeftArrow))
         {
             transform.Translate(-speed * Time.deltaTime,0,0,Space.World);
             if (Input.GetKeyDown(KeyCode.LeftArrow))
             {
                 anim.Play("Walk_Left");
             }
             lastButtonPress = 1;
         }
         
         else if (Input.GetKey(KeyCode.DownArrow))
         {
             transform.Translate(0,0,-speed * Time.deltaTime,Space.World);
             if (Input.GetKeyDown(KeyCode.DownArrow))
             {
                 anim.Play("Walk_Forward");
             }
             lastButtonPress = 2;
         }
         
         else if (Input.GetKey(KeyCode.RightArrow))
         {
             transform.Translate(speed * Time.deltaTime,0,0,Space.World);
             if (Input.GetKeyDown(KeyCode.RightArrow))
             {
                 anim.Play("Walk_Right");
             }
             lastButtonPress = 3;
         }
         
         
         
         //Idle Animations
         else if (lastButtonPress == 0)
         {
             anim.Play("Up_Idle");
         }
         
         else if (lastButtonPress == 1)
         {
             anim.Play("Left_Idle");
         }
         
         else if (lastButtonPress == 2)
         {
             anim.Play("Forward_Idle");
         }
         
         else if (lastButtonPress == 3)
         {
             anim.Play("Right_Idle");
         }
     }
 }

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlucardJay · Oct 02, 2012 at 04:23 PM 0
Share

Split the steps up. First deter$$anonymous$$e the direction of movement from the key presses. Then when you know the direction, apply the correct animation.

code converted to answer

$$anonymous$$ake sure you also read the answer by Fattie, and think about how you can organize scripts. (nestled ifs and input after if input - ouch).

Also consider animation.CrossFade : http://docs.unity3d.com/Documentation/ScriptReference/Animation.CrossFade.html

Asy1umrat : The cases look interesting as well. Would that solve my issue of multiple button presses?

$$anonymous$$e : yes, I do believe splitting up the steps will resolve your input and animation issues. The switch-case is a fantastic alternative to an endless thread of nestled if statements.

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Fattie · Oct 02, 2012 at 04:18 PM

Never, EVER use "else if".

Maybe this is what you want. You can write this many different ways, I have tried to do it so it is as explanatory as possible.

 enum FACING {up, right, down, left }
 private var playingOneAnimationLoop:boolean
 private var weNeedAnIdle:boolean
 private var facing:FACING;
 
 Update()
   {
 
   // if you only get to here, one of the walk animations
   // is actually playing at this instant
   
   if ( playingOneAnimationLoop ) return;
 
   // if you get to here, we have either JUST finished an
   // animation this split-second, or, we're just doing nothing

   // if we have JUST finished an anaimtion, it's possible
   // the user wants ANOTHER animation, if a key is down
 
   if (Input.GetKey(KeyCode.UpArrow)) { dpUP(); return; }
   if (Input.GetKey(KeyCode.RightArrow)) { doRight(); return; }
   if (Input.GetKey(KeyCode.DownArrow)) { doDown(); return; }
   if (Input.GetKey(KeyCode.LeftArrow)) { doLeft(); return; }
 
   // if you get to here, you have JUST finished the play loop
   // this split-second AND nobody is pressing any damned keys
   // (or, we're just doing nothing and sitting around)
 
   // if weNeedAnIdle is true it means we have JUST finished
   // an animation.  we'll simply ONCE (one time) play the
   // correct standing anime.  ie "set it to" the right image
   if ( weNeedAnIdle ) changeToIdle();
   }
 
 function doUp()
   {
   alreadyBusy = true;
   anim.Play("Walk_Up");
   Invoke( "oneLoopIsFnished", 1.00 );
   // NOTE use the CORRECT time for each animation
   // you may want to tweak them in each case
   // for the feel you want, jerky, smooth whatever
   facing = FACING.up;
   weNeedAnIdle = true;
   }
 
 function doRight .. similar
 function doDown .. similar
 function doLeft .. similar
 
 function oneLoopIsFinished()
   {
   playingOneAnimationLoop = false;
   }
 
 function changeToIdle()
   {
   if ( facing == FACING.up ) anim.Play("Up_Idle");
   if ( facing == FACING.right ) anim.Play("Right_Idle");
   .. etc ..
   weNeedAnIdle = false;
   }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Asy1umrat · Oct 03, 2012 at 06:08 AM 1
Share

That is fantastic, thank you. I see where I was getting confused with my own logic, as well. That cleared up so much. Thank you.

avatar image Fattie · Oct 03, 2012 at 11:52 AM 0
Share

fantastic! do me a favour and "thumb up" the answer as I get more points, points, POINTS! :-)

do not hesitate to start a new question if there is any further problem

avatar image Asy1umrat · Oct 03, 2012 at 06:02 PM 0
Share

Done! Your outline helped so much, thank you, again! It works wonderfully.

I am, though, currently getting an issue where the player will move, but only the first frame will play. I was able to solve this animation problem by putting a playingOneAnimationLoop = true; line in the doUp, etc, functions. The result being that now holding down a button plays the full animation, but the character only translates a few pixels at a time.

I'm sure I'm just misunderstanding something simple.

avatar image Fattie · Oct 03, 2012 at 07:49 PM 0
Share

i reckon a new question would be in order for that, show all code you are using etc!

avatar image
1

Answer by AlucardJay · Oct 03, 2012 at 03:16 AM

Here is the switch-case from my comment, tested and working with an example web player build at the bottom. I also included the change from Input.GetKey to Input.GetAxis :

 #pragma strict
 
 private var speed : float = 0.5;
 private var moveDir : int = 0;
 private var lastDir : int = 0;
 
 function Update() 
 {
         
     if ( Input.GetAxis("Vertical") > 0 ) // Input.GetKey(KeyCode.UpArrow)
     {
         moveDir = 0;
         lastDir = 0;
     }
     else if ( Input.GetAxis("Horizontal") < 0 ) // Input.GetKey(KeyCode.LeftArrow)
     {
         moveDir = 1;
         lastDir = 1;
     }
     else if ( Input.GetAxis("Vertical") < 0 ) // Input.GetKey(KeyCode.DownArrow)
     {
         moveDir = 2;
         lastDir = 2;
     }
     else if ( Input.GetAxis("Horizontal") > 0 ) // Input.GetKey(KeyCode.RightArrow)
     {
         moveDir = 3;
         lastDir = 3;
     }
     else
     {
         moveDir = -1;
     }
     
     
     switch( moveDir )
     {
         case 0 :
             // move up
             transform.Translate( 0, 0, speed * Time.deltaTime, Space.World );
             animation.CrossFade("TPC_Dude Running");
         break;
     
         case 1 :
             // move left
             transform.Translate( -speed * Time.deltaTime, 0, 0, Space.World );
             animation.CrossFade("TPC_Dude Strafing");
         break;
     
         case 2 :
             // move down
             transform.Translate( 0, 0, -speed * Time.deltaTime, Space.World );
             animation.CrossFade("TPC_Dude Walking Backward");
         break;
     
         case 3 :
             // move right
             transform.Translate( speed * Time.deltaTime, 0, 0, Space.World );
             animation.CrossFade("TPC_Dude Strafing");
         break;
     
         default : // case -1 :
             // play correct idle animation
             switch( lastDir )
             {
                 case 0 :
                     // idle up
                     animation.CrossFade("TPC_Dude Idle");
                 break;
     
                 case 1 :
                     // idle left
                     animation.CrossFade("TPC_Dude Idle");
                 break;
     
                 case 2 :
                     // idle down
                     animation.CrossFade("TPC_Dude Idle");
                 break;
     
                 case 3 :
                     // idle right
                     animation.CrossFade("TPC_Dude Idle");
                 break;
     
             }
         break;
     }
     
     //Debug.Log( " moveDir " + moveDir + " : lastDir " + lastDir );
 }

Here is a web build to demonstrate : http://www.alucardj.net16.net/unityanswers/CrossAnim.html

This is a direct copy of the script in my build, so you'll have to change the animation names (and they're old animations! but all I had on hand right now, enough for the example)

=]

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Xepherys · Oct 23, 2013 at 08:56 PM

Couldn't you just use a SWITCH/CASE clause directly from Input.GetAxis? ELSE IF statements make my skin crawl. :)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Sprite staying on idle animation 1 Answer

Unity2D Space shooter rotation resetting when analogue stick input has ended 1 Answer

How to tell when and in which direction the player is moving? (2d) 1 Answer

SpriteManager 2 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges