• 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
Question by irokoispliskin · Jan 06, 2015 at 12:37 PM · androidiostimerpenelope

Stopping Penelope's CountDown Timer

Hello everybody,

So I am using Penelope Unity Scripts for my game as I am not a programmer. The timer in the ScoreKeeper Script works fine but would like it to stop and win/end(and play character animation) the game when all the collectibles have been collected and deposited in the DepositArea(An on trigger cube without mesh renderer). Else, I have to wait for timer to finish to end the game which is not ideal. Hope someone can help.

Many thanks

 var carrying : int;
 var carryLimit : int;
 var deposited : int;
 var winScore : int;                                // How many orbs must be deposited to win
 
 var gameLength : int;                            // Length in seconds
 
 var guiMessage : GameObject;                    // Prefab for one-shot messages
 
 
 // GUIText objects that must be assigned in editor
 var carryingGui : GUIText;                        
 var depositedGui : GUIText;
 var timerGui : GUIText;
 
 
 // Sound fx and voices for different events
 var collectSounds : AudioClip[];
 var winSound : AudioClip;
 var loseSound : AudioClip;
 var pickupSound : AudioClip;
 var depositSound : AudioClip;
 
 private var timeSinceLastPlay : float;            // Last time we played a voice for pickup
 private var timeLeft : float;
 
 public function Start()
 {
     timeLeft = gameLength;
     timeSinceLastPlay = Time.time;
     UpdateCarryingGui();
     UpdateDepositedGui();
     CheckTime();
 }
 
 function UpdateCarryingGui()
 {
      carryingGui.text = "   X " + carrying + " of " + carryLimit;    
 }
 
 function UpdateDepositedGui()
 {
      depositedGui.text = " : " + deposited + " of " + winScore;    
 }
 
 function UpdateTimerGui()
 {
     timerGui.text = "   " + TimeRemaining();        
 }
 
 private function CheckTime()
 {
     // Rather than using Update(), use a co-routine that controls the timer.
     // We only need to check the timer once every second, not multiple times
     // per second.
     while ( timeLeft > 0 )
     {
         UpdateTimerGui();        
         yield WaitForSeconds(1);
         timeLeft -= 1;
     }
     UpdateTimerGui();
     EndGame();
 }    
 
 // This is a utility function to a play one shot audio at a specific position
 // and at a specific volume
 function PlayAudioClip( clip : AudioClip, position : Vector3, volume : float )
 {
     var go = new GameObject( "One shot audio" );
     go.transform.position = position;
     var source : AudioSource = go.AddComponent( AudioSource );
     source.rolloffMode = AudioRolloffMode.Logarithmic;
     source.clip = clip;
     source.volume = volume;
     source.Play();
     Destroy( go, clip.length );
     return source;
 }
 
 private function EndGame()
 {
     var animationController : AnimationController = GetComponent( AnimationController );
     var prefab : GameObject = Instantiate(guiMessage);
     var endMessage : GUIText = prefab.GetComponent( GUIText );
     
 
     if(deposited >= winScore)
     {
         //Player wins
         endMessage.text = "You win!";
         PlayAudioClip( winSound, Vector3.zero, 1.0 );
         animationController.animationTarget.Play( "WIN" );
     }
     else
     {
         //Player loses
         endMessage.text = "Ran out of time!";
         PlayAudioClip( loseSound, Vector3.zero, 1.0 );        
         animationController.animationTarget.Play( "LOSE" );        
     }
     
     // Alert other components on this GameObject that the game has ended
     SendMessage( "OnEndGame" );
     
     while( true )
     {
         // Wait for a touch before reloading the intro level
         yield WaitForFixedUpdate();
         if ( Input.touchCount > 0 && Input.GetTouch( 0 ).phase == TouchPhase.Began )
             break;
     }
     
     Application.LoadLevel( 0 );
 }
 
 public function Pickup( pickup : ParticlePickup )
 {
     if ( carrying < carryLimit )
     {
          carrying++;
         UpdateCarryingGui();         
         
         // We don't want a voice played for every pickup as this would be annoying.
         // Only allow a voice to play with a random percentage of chance and only
         // after a minimum time has passed.
         var minTimeBetweenPlays = 5;
         if ( Random.value < 0.1 && Time.time > ( minTimeBetweenPlays + timeSinceLastPlay ) )
         {
             PlayAudioClip( collectSounds[ Random.Range( 0, collectSounds.length ) ], Vector3.zero, 0.25 );
             timeSinceLastPlay = Time.time;
         }
         
          pickup.Collected();    
         PlayAudioClip( pickupSound, pickup.transform.position, 1.0 );
     }
     else
     {
         var warning : GameObject = Instantiate( guiMessage );
         warning.guiText.text = "You can't carry any more";
         Destroy(warning, 2);
     }
     
     // Show the player where to deposit the orbs
      if ( carrying >= carryLimit )
         pickup.emitter.SendMessage( "ActivateDepository" );         
 }
 
 public function Deposit()
 {
     deposited += carrying;
     carrying = 0;
     UpdateCarryingGui();
      UpdateDepositedGui();
     PlayAudioClip( depositSound, transform.position, 1.0 );     
 }
 
 public function TimeRemaining() : String
 {
     var remaining : int = timeLeft;
     var val : String;
     if(remaining > 59) // Insert # of minutes
      val+= remaining / 60 + ".";
     
     if(remaining >= 0) // Add # of seconds
     {
         var seconds : String = (remaining % 60).ToString();
         if(seconds.length  < 2)
             val += "0" + seconds; // insert leading 0
         else
             val += seconds;
     }
         
     return val;
 }








Comment
StrikeMasterz

People who like this

1 Show 6
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 StrikeMasterz · Jan 06, 2015 at 12:44 PM 0
Share

Right now, looking at the script, it should do what you are asking for. Look at the EndGame() function. If a certain amount of stuff is deposited, it says you win and an animation plays out. What is the issue?

avatar image irokoispliskin · Jan 06, 2015 at 12:57 PM 0
Share

Hi, thank you for the prompt response. Yes it works fine but I would like the timer to stop when the WinScore(the required number of items collected) has been achieved.

Currently what happens is that: I collect all the items then have to wait for timer(here denoted by gamelength or timeLeft) to finish to win the game.

I would like to modify the script to end the timer or make the timer = 0 when all the items have been collected and deposited in the Deposit Area.

avatar image StrikeMasterz · Jan 06, 2015 at 01:09 PM 0
Share

Do you see the section on line 88?

if (deposited >= winScore)

Underneath, simply set timeleft to be 0

if(deposited >= winScore) { timeleft=0; }

avatar image irokoispliskin · Jan 06, 2015 at 01:35 PM 0
Share

Thanks! Keep getting this error: Assets/Scripts/ScoreKeeper.js(109,9): BCE0044: expecting EOF, found 'else'. Do you think an Ontrigger script with the deposit area collider would work instead?

avatar image StrikeMasterz · Jan 06, 2015 at 02:00 PM 0
Share

Can you give the whole script now? After my edit?

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by StrikeMasterz · Jan 07, 2015 at 12:31 AM

Your issue here is that there is nothing in your code that checks if you are picking up the game objects and increasing your score. Here is a way to fix that:


Step Zero: Notes

I need to sleep right now, and as such I won't be able to proofread this answer. There could be spelling mistakes, which you need to be mindful of, ESPECIALLY if they are in code

I use C# more than Javascript, so if there is any syntax wrong, please point it out :)

If there are still any errors/issues, please tell EXACTLY what is going wrong, AS WELL AS any errors that come from the unity engine

Step One: Editor

Add two game object cubes, one named DepositArea and one named ScoreBlock. Put them a fair distance apart. Set the tag for the DepositArea to be Deposit, while the tag for the score block to be ScoreBlock.

Check online if you are not sure how to tag objects

Then, set both of their colliders to be OnTrigger. Again, check if the internet if unsure how.

Step One.Five: Setting up some variables

In the beginning of the script, we assigned some variables, but never gave them a value. It would be best if we did. This is to just remove any possible errors

 //This is how many you are carrying. In beginning, you are carrying none, so set this to 0
 var carrying : int = 0;
 // This is how many you can carry at one time. Set this to what you like (here, 10)
 var carryLimit : int = 10;
 //This is how many you have deposited.In beginning, you have deposited none, so set this to 0
 var deposited : int = 0;
 // This is how many you need to win. Set this to what you like (here, 5)
 var winScore : int = 5;

Step Two: Increase Carrying Score by Code

Now we need to actually track the amount of blocks you are carrying. Put a new function inside the script, and set it to public:

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         // Something;
     }

This function will execute everytime you hit an object that is marked OnTrigger. Now, check if that object has the tag ScoreBlock, so we know we are hitting a Score Block

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  // Something;
             }
     }

Now, we are checking if the object we are collided is a Score Block, by checking if it has the tag Score Block. If it does, let us increase how many you are carrying.

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  carrying++;
             }
     }

This will simply take how many you are carrying (In this case, 0) and add a 1 to it. Now, lets work on the Deposit Area!

Step Three: Increase Score when deposited by Code

Now, what we want to do is to do the exact same thing as before, but instead of looking if we hit a ScoreBlock, lets check if we are hitting a DepositBlock. We do both in an if statement inside the function OnTriggerEnter

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  carrying++;
             }
         if (objectCollided.transform.tag == "Deposit")
             {
                  // Something;
             }
     }

Now, instead of increasing the carrying number, lets increase how many we have deposited by how many carrying we have

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  carrying++;
             }
         if (objectCollided.transform.tag == "Deposit")
             {
                  deposited += carrying;
             }
     }

What did does is increase deposited by our current carrying score. It is the same thing as writing deposited = deposited + carrying, its just more concise. Now, we also need to reset the carrying score, so we can't just cheat and keep tapping the Deposit area with how much we previously carried

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  carrying++;
             }
         if (objectCollided.transform.tag == "Deposit")
             {
                  deposited += carrying;
                  carrying = 0;
             }
     }

Step Four: Done!

That is all we should need to do. Everytime you hit an object with the tag ScoreBlock, it will increase carrying by one. Whenever you hit the Deposit object, it will increase the deposit score with ScoreBlock, AS well as reset it to 0.

If there are any more problems, just say so :)

Step Five: Edited Code

MAKE SURE TO READ THE TEXT BEFOREHAND, INCREDIBLY IMPORTANT

 var carrying : int; = 0
 var carryLimit : int; = 10
 var deposited : int; = 0
 var winScore : int; = 5                            // How many orbs must be deposited to win
  
 var gameLength : int;                            // Length in seconds
  
 var guiMessage : GameObject;                    // Prefab for one-shot messages
  
  
 // GUIText objects that must be assigned in editor
 var carryingGui : GUIText;                        
 var depositedGui : GUIText;
 var timerGui : GUIText;
  
  
 // Sound fx and voices for different events
 var collectSounds : AudioClip[];
 var winSound : AudioClip;
 var loseSound : AudioClip;
 var pickupSound : AudioClip;
 var depositSound : AudioClip;
  
 private var timeSinceLastPlay : float;            // Last time we played a voice for pickup
 private var timeLeft : float;
  
 public function Start()
 {
     timeLeft = gameLength;
     timeSinceLastPlay = Time.time;
     UpdateCarryingGui();
     UpdateDepositedGui();
     CheckTime();
 }
  
 function UpdateCarryingGui()
 {
      carryingGui.text = "   X " + carrying + " of " + carryLimit;    
 }
 
 function UpdateDepositedGui()
 {
      depositedGui.text = " : " + deposited + " of " + winScore;    
 }
 
 function UpdateTimerGui()
 {
     timerGui.text = "   " + TimeRemaining();        
 }
 
 private function CheckTime()
 {
     // Rather than using Update(), use a co-routine that controls the timer.
     // We only need to check the timer once every second, not multiple times
     // per second.
     while ( timeLeft > 0 )
     {
         UpdateTimerGui();        
         yield WaitForSeconds(1);
         timeLeft -= 1;
     }
     UpdateTimerGui();
     EndGame();
 }    
 
 // This is a utility function to a play one shot audio at a specific position
 // and at a specific volume
 function PlayAudioClip( clip : AudioClip, position : Vector3, volume : float )
 {
     var go = new GameObject( "One shot audio" );
     go.transform.position = position;
     var source : AudioSource = go.AddComponent( AudioSource );
     source.rolloffMode = AudioRolloffMode.Logarithmic;
     source.clip = clip;
     source.volume = volume;
     source.Play();
     Destroy( go, clip.length );
     return source;
 }
 
 private function EndGame()
 {
     var animationController : AnimationController = GetComponent( AnimationController );
     var prefab : GameObject = Instantiate(guiMessage);
     var endMessage : GUIText = prefab.GetComponent( GUIText );
     
 
     if(deposited >= winScore)
     {
         //Player wins
         timeleft=0;
         endMessage.text = "You win!";
         PlayAudioClip( winSound, Vector3.zero, 1.0 );
         animationController.animationTarget.Play( "WIN" );
     }
     else
     {
         //Player loses
         endMessage.text = "Ran out of time!";
         PlayAudioClip( loseSound, Vector3.zero, 1.0 );        
         animationController.animationTarget.Play( "LOSE" );        
     }
     
     // Alert other components on this GameObject that the game has ended
     SendMessage( "OnEndGame" );
     
     while( true )
     {
         // Wait for a touch before reloading the intro level
         yield WaitForFixedUpdate();
         if ( Input.touchCount > 0 && Input.GetTouch( 0 ).phase == TouchPhase.Began )
             break;
     }
     
     Application.LoadLevel( 0 );
 }
 
 public function Pickup( pickup : ParticlePickup )
 {
     if ( carrying < carryLimit )
     {
         carrying++;
         UpdateCarryingGui();         
         
         // We don't want a voice played for every pickup as this would be annoying.
         // Only allow a voice to play with a random percentage of chance and only
         // after a minimum time has passed.
         var minTimeBetweenPlays = 5;
         if ( Random.value < 0.1 && Time.time > ( minTimeBetweenPlays + timeSinceLastPlay ) )
         {
             PlayAudioClip( collectSounds[ Random.Range( 0, collectSounds.length ) ], Vector3.zero, 0.25 );
             timeSinceLastPlay = Time.time;
          }
          
         pickup.Collected();    
         PlayAudioClip( pickupSound, pickup.transform.position, 1.0 );
     }
     else
     {
         var warning : GameObject = Instantiate( guiMessage );
         warning.guiText.text = "You can't carry any more";
         Destroy(warning, 2);
     }
     
     // Show the player where to deposit the orbs
      if ( carrying >= carryLimit )
         pickup.emitter.SendMessage( "ActivateDepository" );         
 }
 
 public function Deposit()
 {
     deposited += carrying;
     carrying = 0;
     UpdateCarryingGui();
     UpdateDepositedGui();
     PlayAudioClip( depositSound, transform.position, 1.0 );     
  }
  
 public function TimeRemaining() : String
 {
     var remaining : int = timeLeft;
     var val : String;
     if(remaining > 59) // Insert # of minutes
      val+= remaining / 60 + ".";
     
     if(remaining >= 0) // Add # of seconds
     {
         var seconds : String = (remaining % 60).ToString();
         if(seconds.length  < 2)
             val += "0" + seconds; // insert leading 0
         else
             val += seconds;
     }
         
     return val;
 }

 public function OnTriggerEnter (objectCollided: Collider) 
     {
         if (objectCollided.transform.tag == "ScoreBlock")
             {
                  carrying++;
             }
         if (objectCollided.transform.tag == "Deposit")
             {
                  deposited += carrying;
                  carrying = 0;
             }
     }





Comment

People who like this

0 Show 14 · 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 irokoispliskin · Jan 07, 2015 at 05:53 AM 0
Share

Thanks! The game plays but the timer keeps going and doesn't stop when all the coins have been collected :(

I have added this too but still doesn't work:

 if(deposited >= winScore && timeLeft >= 0)
     {
         //Player wins
         timeLeft=0;
avatar image StrikeMasterz · Jan 07, 2015 at 08:55 AM 0
Share

Does the timer go negative?

avatar image irokoispliskin · Jan 07, 2015 at 12:26 PM 0
Share

Nope, it goes to zero and i win/lose the game fine but I am not able to win the game by collecting the required items before the timer finishes the countdown, even with your codes :( Might have to find a way around somehow...

avatar image StrikeMasterz · Jan 08, 2015 at 12:19 AM 0
Share

Ah, I see. The problem is that you can't actually win the game right? From collecting the items?

avatar image irokoispliskin · Jan 08, 2015 at 08:27 AM 0
Share

Yes, i can't win the game from collecting the items. I have to wait for the timer to finish to win. I would ideally like to win the game upon depositing the collected items in the deposit area before the timer reaches zero. I am all ears though, please let me know what's best to do. Thank you so much for your help!

Show more comments
avatar image

Answer by Graham-Dunnett · Jan 06, 2015 at 12:57 PM

Add after line 114:

 if (deposited >= winScore)
     timeleft = 0;

Now, when orbs are deposit and Deposit() gets called you'll artificially change the time. The function CheckTime() checks the time every second, so next time it runs it'll think the time has ended, so it'll call EndGame(). The first thing EndGame() does is to check the number of deposited orbs, so the player will see they have won.

Comment

People who like this

0 Show 1 · 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 irokoispliskin · Jan 06, 2015 at 01:30 PM 0
Share

Hello! Thank you so much for your reply, but it doesn't seem to be working. Do you think an OnTrigger script with the DepositArea collider would work better? Just don't know how to write it down.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Countdown Timer 1 Answer

Is there a limit to how many 2048 texture pages we can use for iOS and android? 0 Answers

How to load a level after 30 seconds? 3 Answers

Google Sign In On Android and IOS 0 Answers

Send HTML email to native email client 3 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