Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by Mellowlink · Oct 02, 2015 at 11:49 AM · scripting problem2d animation2d-gameplayattacking

Issue with attacking and animation in a 2D game

So I'm working on a basic platformer with attack mechanics similar to Wonderboy, and I'm having trouble performing a basic melee attack.

The way I have it set up is with an abstract behaviour class that all my behaviours extend, an input state class to detect how long buttons have been held down etc, and a player manager to manage animation states.

My issue is that I want the animation to play once when the attack button is pressed, and I want attack to be disabled as longa s the button is held down so the player can't simply hold down the attack button and keep on attacking. However just when I thought I got this working, the player actually cuts out of the 6-frames sword swing animation after the first or second frame. I'll paste the code from those three classes below and I really hope you guys can help me out.

My Attack class:

 using UnityEngine;
 using System.Collections;
 
 public class Attack : AbstractBehaviour {
 
     public bool attacking = false;
 
 
     private Duck duckState;
     private Animator anim;
 
     protected override void Awake()
     {
         base.Awake();
 
         duckState = GetComponent<Duck> ();
         anim = GetComponent<Animator> ();
     }
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     protected virtual void Update () {
 
         var canAttack = inputState.GetButtonValue(inputButtons[0]);
         //var holdTime = inputState.GetButtonHoldTime(inputButtons[0]);
         
         if (canAttack)
         {
             OnAttack(true);
         }
         else
         {
             OnAttack(false);
         }
     }
 
     protected virtual void OnAttack(bool value)
     {
         attacking = value;
 
         if (!duckState.ducking)
         {
             ToggleScripts(!attacking);
         }
         
     }
 }

My Player Manager:

 using UnityEngine;
 using System.Collections;
 
 public class PlayerManager : MonoBehaviour {
 
     private InputState inputState;
     private Walk walkBehaviour;
     private Animator animator;
     private CollisionState collisionState;
     private Duck duckBehaviour;
     private Attack attackBehaviour;
 
     void Awake()
     {
         inputState = GetComponent<InputState> ();
         walkBehaviour = GetComponent<Walk> ();
         animator = GetComponent<Animator> ();
         collisionState = GetComponent<CollisionState> ();
         duckBehaviour = GetComponent<Duck> ();
         attackBehaviour = GetComponent<Attack> ();
     }
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () {
         if (collisionState.standing)
         {
             ChangeAnimationState(0);
         }
 
         if (inputState.absVelX > 0)
         {
             ChangeAnimationState(1);
         }
 
         if(inputState.absVelY > 0)
         {
             ChangeAnimationState(2);
         }
         if (duckBehaviour.ducking)
         {
             ChangeAnimationState(3);
         }
         if (attackBehaviour.attacking)
         {
             if (!duckBehaviour.ducking)
             {
                 ChangeAnimationState(4);
             }
             else
             {
                 ChangeAnimationState(5);
             }
         }
     }
 
     void ChangeAnimationState(int value)
     {
         animator.SetInteger("AnimState", value);
     }
 }

My Input State manager:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class ButtonState
 {
     public bool value;
     public float holdTime = 0f;
 }
 
 public enum Directions
 {
     Right = 1,
     Left = -1
 }
 
 public class InputState : MonoBehaviour {
 
     public Directions direction = Directions.Right;
     public float absVelX = 0f;
     public float absVelY = 0f;
 
     private Rigidbody2D body2d;
     private Dictionary<Buttons, ButtonState> buttonStates = new Dictionary<Buttons, ButtonState>();
 
     void Awake()
     {
         body2d = GetComponent<Rigidbody2D> ();
     }
 
     void FixedUpdate()
     {
         absVelX = Mathf.Abs(body2d.velocity.x);
         absVelY = Mathf.Abs(body2d.velocity.y);
     }
 
     public void SetButtonValue(Buttons key, bool value)
     {
         if (!buttonStates.ContainsKey(key))
             buttonStates.Add(key, new ButtonState());
 
         var state = buttonStates[key];
 
         if (state.value && !value)
         {
             Debug.Log("Button " + key + " released after " + state.holdTime);
             state.holdTime = 0f;
         }else if (state.value && value)
         {
             state.holdTime += Time.deltaTime;
             Debug.Log("Button " + key + " down for" + state.holdTime);
         }
 
 
         state.value = value;
     }
 
     public bool GetButtonValue(Buttons key)
     {
         if (buttonStates.ContainsKey(key))
             return buttonStates [key].value;
         else
             return false;
     }
 
     public float GetButtonHoldTime(Buttons key)
     {
         if (buttonStates.ContainsKey(key))
             return buttonStates[key].holdTime;
         else
             return 0;
     }
 
 }

I really hope you guys can help, I've been tackling this issue for the past six hours and haven't worked it out completely. I just want the animation to play once through the entire clip of 6 frames, preferably without using that reference I put in to the animator because I'm sure there's a better way to do it, as I'd rather have it depend on the AnimState I've set in the animation controller because I'm going to have different sprites for different equipment on my main character and I'd rather it be dependent on a variable like that to keep things simple.

EDIT: I'll also include this class since my behaviours extend it.

AbstractBehaviour:

 using UnityEngine;
 using System.Collections;
 
 public abstract class AbstractBehaviour : MonoBehaviour {
 
     public Buttons[] inputButtons;
     public MonoBehaviour[] disableScripts;
 
     protected InputState inputState;
     protected Rigidbody2D body2d;
     protected CollisionState collisionState;
 
     protected virtual void Awake()
     {
         inputState = GetComponent<InputState> ();
         body2d = GetComponent<Rigidbody2D> ();
         collisionState = GetComponent<CollisionState> ();
     }
     
     protected virtual void ToggleScripts (bool value)
     {
         foreach (var scripts in disableScripts)
         {
             scripts.enabled = value;
         }
     }
 
 }

Comment
Add comment
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

1 Reply

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

Answer by Mellowlink · Oct 03, 2015 at 08:14 PM

Alright so I actually figured this out the next day, and I know it's not very complicated but I'll leave the solution here in case of the off-chance that someone else has this problem.

I ended up adding an EndAttack() method in my attack class which gets called during the last frame of my attack animation. All it does is set the "attacking" variable to false. I wanted to avoid using animation events if I could but since it's working 100% of the time even on fast speed I guess I'll use it unless any further problem arise.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Having some stuck issues on the 2D infinite runner 0 Answers

Different attacks using same keybindings? 2 Answers

Hit/React Animation 2 Answers

Equivelant "set" method for "getInstantiatedObject"? 0 Answers

Switch Players during play 2 Answers


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