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 Saiura · Jun 10, 2014 at 12:32 PM · animationtimerstucktimer-script

Problem with "stun"-timer after player is being hit

In the 2,5D sidescroller I currently develop, I am trying to stun the player for a very brief moment of time once they get hit by an enemy (that also serves to play the "hit"-animation").

I started off by a simple collision script, reducing the players HP by 30 on each hit (player begins with currently 110). That worked just fine so far, each time the enemy touches the player, he loses 30 hp, but only once per touch.

Then I added an extra bit of code to my Update method in order to get the stun-timer in:

     if (IsHit)
         {
             DamageTaken();
             Hittimer = Time.time + Hitdown;    
 
             if (Hittimer >= Time.time)
             {
                 GetComponent<CharacterController>().enabled = false;
                 Hitanim = true;
             }
 
             if (Hittimer <= Time.time)
             {
                 IsHit = false;
                 GetComponent<CharacterController>().enabled = true;
                 Hitanim = false;
             }
         }

Hittimer isn't initialized before that if-statement, Hitdown is set to 0.2f. Hitanim is given to my Animation-script to handle the hit-animation. IsHit is initialized with false. My enemy-script detects collision and sets IsHit to true once collision occures (simple OnTriggerEnter script).

My problem now is, I seem to have an error in the sub-IFs that I can't find. The "stun" is permanent, as is the boolean for Hitanim. Though the boolean for IsHit instantly resets to false. The damage is done only once too, so I am quite sure that the issue is somewhere in those if-statements

I'd be glad for any help on it, or better methods to get my "stun" done, preferably in C#.

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 iwaldrop · Jun 10, 2014 at 09:08 PM 0
Share

You should cache a reference to the character controller in Awake. It won't fix your problem, but it's an optimization you should always make. Alternatively, make the character controller a public member variable and link it up in the inspector.

1 Reply

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

Answer by PouletFrit · Jun 10, 2014 at 02:21 PM

You could use a Coroutine. A Coroutine is a function that can extend it's execution on a certain laps of time; in other word you can wait a certain amount of time before resuming it.

You can declare a Coroutine like this:

 IEnumerator WaitForStunToEnd() {
     // Wait a frame
     yield return null;

     // Wait 0.2 seconds
     yield return new WaitForSeconds(0.2f);
 }

To start a Coroutine use:

 StartCoroutine(WaitForStunToEnd());

So In your case you just need set the damage taken, disable the character controller in your OnTriggerEnter AND start the coroutine.

In the coroutine, yield return new WaitForSeconds() for the time you need, then reenable the character controller.

Also if you don't want your player to be hit while stun keep using your hit boolean and just set it to true in your OnTriggerEnter and set it back to false in your coroutine.

Comment
Add comment · Show 8 · 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 Saiura · Jun 11, 2014 at 08:48 AM 0
Share

thanks for the help, the stun works just fine so far, though it seems, even though having the coroutine reenable the character controller and setting IsHit to false, the controller seems to be set to true again way later than the IsHit. I just tried running into an enemy, got stunned but before I could move again I was even hit twice.

This is my coroutine:

     IEnumerator WaitForStunToEnd() {
     
             yield return new WaitForSeconds(0.5f);
             GetComponent<CharacterController> ().enabled = true;
             Hitanim = false;
             IsHit = false;
         }
 

I even go as far in my Enemy-script to only set IsHit back to true when the players character controller is also enabled during collision, also the Update methode of the Player is supposed to only trigger when that's the case. Unless of course an IF like the following doesn't quite work (though it does do the damage)

     if (IsHit && GetComponent<CharacterController>().enabled == true)
         {
             DamageTaken();
         }
avatar image PouletFrit · Jun 11, 2014 at 11:32 AM 0
Share

You dont need any of that code in your update anymore. You would either A) Have a timer in your update incremeting it with Time.deltaTime or B) use a coroutine and use yield return, but you shouldn't mix both.

In the OnCollisionEnter function of your enemy script ins$$anonymous$$d of just setting IsHit to true start a function of your player script that will handle everything from there.

something along these lines (not sure how you do it, but not really important since it seems to work)

 OnCollisionEnter(Collision collision) {
     if (collision.gameObject.tag == "Player") {
         collision.gameObject.GetComponent<PlayerScript>().PlayerHit();
     }
 }

and then in your player script:

 public float stunTime = 0.2f;
 
 private bool isStun;
 
 // Let's cache the controller, just like iwaldrop suggested, it's a good idea
 private CharacterController controller;
 
 void Awake() {
     controller = GetComponent<CharacterController>();
 }
 
 public void PlayerHit() {
     // If we are already stun, quit; we don't want to be hit again when we are stun
     if (isStun) {
         return;
     }
 
     DamageTaken();
     isStun = true;
     controller.enabled = false;
 
     StartCoroutine(WaitForStunToEnd());
 }
 
 private IEnumerator WaitForStunToEnd() {
     yield return new WaitForSeconds(stunTime);
     isStun = false;
     controller.enabled = true;
 }
avatar image Saiura · Jun 11, 2014 at 12:56 PM 0
Share

I'm starting to feel stupid... I have it all set up as in your code, just set the stunTime to 1.0f for testing and ins$$anonymous$$d of the collision script I have:

 void OnTriggerEnter(Collider collision) 
     {
         if (collision.gameObject.tag == "Player") {
             collision.gameObject.GetComponent<Player>().PlayerHit();
         }
     }

So basicly the same, just as Trigger ins$$anonymous$$d of Collision The stun seems to last just fine, though I seem to get damage each "tick" as long as I am at the enemy.

avatar image PouletFrit · Jun 11, 2014 at 04:09 PM 0
Share

First of all, dont feel stupid... We all need to learn and I'm be wrong and misguiding you...

Try adding

 Debug.Log("PlayerHit [isStun=" + isStun + "]");

at the start of the PlayerHit() function. And maybe a

 Debug.Log("PlayerHit passed the isStun check");

right after the

 if (isStun) {
     return;
 }

just to check if the condition is working.

and then another

 Debug.Log("WaitForStunToEnd Done");

at the end of the coroutine

and try to check what's happening...

avatar image Saiura · Jun 12, 2014 at 08:02 AM 0
Share

Alright, just tried out the debugging.

what I got is:

 PlayerHit [isStun=False]
 PlayerHit passed the isStun check

(posted those two directly under the if-statement, if I have them inside of it they don't come up at all)

then a ton of:

 CharacterController.$$anonymous$$ove called on inactive controller
 UnityEngine.CharacterController:$$anonymous$$ove(Vector3)

and a

 WaitForStunToEnd Done

at the very end. I haven't noticed the Warning about the CharacterController until now, but considering I keep pressing/holding movement keys while stunned, that part is understandable.

Show more comments

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

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

Related Questions

Countdown timer? 1 Answer

How do i know if a animation is finished or not ? 2 Answers

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

SimpelTimerScript 1 Answer

How do I implement a timer into this script that will record the total time the player has played. 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