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
0
Question by user5200 · Aug 13, 2012 at 07:27 AM · c#colliderdamage

Attack combos and collision detection

Hi,

So, I'm making a action/fighting game on Unity and I have started to notice that my damage application script for the main attack was pretty inconsistent. This is either due to my bad coding or the unity colliders being inconsistent.

The main problem is that sometimes the attack animation will play while the damage application does not go through. Like I said, this happens very inconsistently. My main character has a three hit combo as his main attack string and he will miss at least 20% of the time. This can happen on first, second or third hit. I started with discrete collision detection but I have slowly moved to continuous and then continuous dynamic. It has made some difference but there are still times where it will fail.

Here is the code I have:

This is the part that tracks how many times you have hit and plays the appropriate animation.

 if (atkready && rightbox.dmgReady ||
  atkready && leftbox.dmgReady)
  { 
  if (!blocking && !gettinghit)
  {
  if (attackcounter >  3)
  {
  attackcounter = 1;
  }
  if (attackcounter == 3)
  {
  karateman.Play("attack3");
  attackcounter++;
  atktimer = true;
  atkreset = 0;
  spacebar++;
  atkready = false;
  }
  if (attackcounter == 2)
  {
  karateman.Play("attack2");
  attackcounter++;
  atktimer = true;
  atkreset = 0;
  spacebar++;
  atkready = false;
  }
  if (attackcounter == 1)
  {
  karateman.Play("attack1");
  attackcounter++;
  atktimer = true;
  atkreset = 0;
  spacebar++;
  atkready = false;
  }
  }
  }

This next part handles the attack reset. Since the animations have different lengths, the next attack animation will not be ready until a certain amount of time has passed.

 if (!atkready && attackcounter == 1)
  {
  atkCD += Time.deltaTime;
  if (atkCD >= 1.4f)
  {
  atkready = true;
  atkCD = 0;
  }
  }
  
  if (!atkready && attackcounter == 2)
  {
  atkCD += Time.deltaTime;
  if (atkCD >= 0.3f)
  {
  atkready = true;
  atkCD = 0;
  }
  }
  
  if (!atkready && attackcounter == 3)
  {
  atkCD += Time.deltaTime;
  if (atkCD >= 0.3f)
  {
  atkready = true;
  atkCD = 0;
  }
  }
  
  if (!atkready && attackcounter > 3)
  {
  atkCD += Time.deltaTime;
  if (atkCD >= 1.4f)
  {
  atkready = true;
  atkCD = 0;
  }
  }

These 2 above code snippets are only dealing with animation. Next up is where the problem is. This next code tries to mirror the attack reset code so that the damage will only apply when the animations are correct.

 //delay after THE WHOLE combo
  if (!dmgReady && playerscript.attackcounter == 1)
  {
  dmgCD += Time.deltaTime;
  if (dmgCD >= 1.4f)
  {
  dmgReady = true;
  dmgCD = 0;
  }
  }
  
  //delay after FIRST attack
  if (!dmgReady && playerscript.attackcounter == 2)
  {
  dmgCD += Time.deltaTime;
  if (dmgCD >= 0.3f)
  {
  dmgReady = true;
  dmgCD = 0;
  }
  }
  
  //delay after SECOND attack
  if (!dmgReady && playerscript.attackcounter == 3)
  {
  dmgCD += Time.deltaTime;
  if (dmgCD >= 0.3f)
  {
  dmgReady = true;
  dmgCD = 0;
  }
  }
  
  //delay after THIRD attack
  if (!dmgReady && playerscript.attackcounter > 3)
  {
  dmgCD += Time.deltaTime;
  if (dmgCD >= 1.4f)
  {
  dmgReady = true;
  dmgCD = 0;
  }
  }

Finally, this last part is inside OnTriggerStay() of the damage hitbox. If an enemy is within this box, and you press the main attack button this code will execute.

 if (Input.GetButtonDown("fight") && playerscript.state != Player.State.Explosion && !playerscript.stunned && !playerscript.blocking && !playerscript.gettinghit)
  {
 
  if (dmgReady)
  {
  if (otherObject.tag == "Enemy")
  {
  //All the dmg and effects code omitted for clarity
  dmgReady = false;
  
  
  }//end | tag: enemy

As I was saying earlier, this system works for the most part. But it is extremely frustrating when it doesn't because it will cause the main character to drop combos from the air, when it was clearly supposed to hit.

Atkready and Dmgready should be basically in sync but sometimes the animation comes out while none of the dmg script goes through. Has anyone else experienced this? Is it coming from the coding or the colliders?

Here is the link for a requested minimal pack from ScroodgeM

https://www.dropbox.com/s/i8e71znj79ryll5/Karateman.rar

Comment
Add comment · Show 10
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 ScroodgeM · Aug 13, 2012 at 07:30 PM 0
Share

fuf... too much letters...

it's hard a little to debug all your code without other parts. needs to write all stuff around to make this working. understand and debug it without executing in unity is also takes time 8)

so, use a very powerful tool Debug.Log("something"); - insert it in every point in code that works incorrect and monitor states of your variables. check what is executed and when, may be something executing twice etc.

i'm sure you'll get much more information about your issue and get a solution, or, issue becomes more specific and can be asked in few lines of text 8)

if you'd try this and still stuck, write a line here again, i'll try to penetrate your code 8)

avatar image user5200 · Aug 14, 2012 at 04:40 AM 0
Share

Hi!

Thanks for reading. I am aware of Debug.Log and I have used it as well as other various debugging methods. I even have a Devmode display that displays whatever variables I want to check on real-time in the unity GUI.

$$anonymous$$y problem is not that I don't know what's going wrong, but rather, that I don't understand why. As I said earlier, There are 2 main bools involved that should mirror each other but they do not. Today I have tried 2 more methods to try to make them execute in sync.

What you seem to be saying is that I am providing too much information and too little information at the same time! If you want more code, I am 100% willing to post it. The whole reason I am omitting stuff is to avoid the TL;DR problem.

avatar image darthbator · Aug 14, 2012 at 08:26 AM 1
Share

I'm probably a little out of my depth here especially without being able to see all of the animations but I will offer 1 small piece of advice. The formatting on the code tool here in answers is junk. If you keep heading down this rabbit hole you might want to start tossing some of that into pastebin ins$$anonymous$$d just to ease readability.

usually when I hit these points I just start putting a debug log into any "breakpoint" I might conceive in my code /shrug

$$anonymous$$inda the best novice class advice I can give here.

avatar image Mander · Aug 14, 2012 at 03:17 PM 0
Share

i would recomend you to use OnTriggerEnter() at the last part and OntriggerExit(), and use some flags

var isInRange : bool; var enemy : bool;

function onTriggerEnter() { enemy = other.gameObject.tag== "enemy"; isInRange = true; }

function onTriggerExit() { isInRange = false; }

function Update(){ if (Input.GetButtonDown("fight") && isInRange == true && enemy){ //more code } }

this will make everything more accurate. i had the same problem some days ago and used this flag and it now works perfectly

avatar image ScroodgeM · Aug 14, 2012 at 07:12 PM 0
Share

share a $$anonymous$$imal pack to reproduce issue, i'll check it.

Show more comments

1 Reply

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

Answer by ScroodgeM · Aug 20, 2012 at 09:31 PM

leftrightbox.cs:

...
void OnTriggerStay (Collider otherObject)
{
	#region...
	if (Input.GetButton("fight")...
...

don't use GetButtonDown in any place except Update() function. GetButtonDown hits once a frame and you can't be sure that OnTriggerStay hits at this frame.

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 user5200 · Aug 21, 2012 at 12:52 AM 0
Share

Brilliant! Thanks so much. This works perfectly. I have been using GetButtonDown so much that I hadn't even thought that the problem might be there.

avatar image user5200 · Aug 29, 2012 at 04:23 AM 0
Share

Hey Scroodge,

I don't know if you're still around, but, after implementing your fix, I discovered something bad. I suppose I'm a noob for not noticing in the first place, but when GetButton is used ins$$anonymous$$d of GetButtonDown, the user is able to hold down the button and continuously do damage. This seems obvious in hindsight but I was just so happy that it worked, I didn't have a care.

Is there a way to keep this system but disable this exploit? If I find a good way myself, I will post it. Any help would be appreciated.

avatar image ScroodgeM · Aug 29, 2012 at 09:21 PM 1
Share
  • make a bool variable

    private bool buttonPressed;
  • check button pressed in Update()

    void Update()
    {
        buttonPressed = buttonPressed | Input.GetButtonDown("fight");
    }
  • use this in apply action method

    void OnTriggerStay (Collider otherObject)
    {
    #region...
    if (buttonPressed...
  • don't forget to reset it after use

    ...
    buttonPressed = false;
avatar image user5200 · Aug 30, 2012 at 03:16 AM 0
Share

Thanks again, Scroodge! You're a lifesaver :D

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

15 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 avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Zombie Damage Parts Problem 0 Answers

Distribute terrain in zones 3 Answers

Raycast isn't working as expected 1 Answer

How to check if two objects collide without a collider 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