Search Unity

Begin Timer OncollisionEnter

Discussion in 'Scripting' started by redghost, Jul 30, 2007.

  1. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    Hi there,

    In a racing gaming I want a timer to begin a countdown when the car enters in a specific road. When the car exits this road and drives on another road I want the timer to reset and start the countdown again.

    so far...

    I created a plane (for a road) and I attached to it a guiText object as a timer (like in the marble tutorial). I created a prefab and dragged in the prefab the plane (with the attached guiText). Then I took the timer script (from the tutorial) and I changed the function Update() to function OnCollisionEnter () and I attached it onto the plane prefab.

    When I run the game and the car is moving onto this plane I got a message... "there is no 'GuiText' attached to the Plane01 object but a script is trying to access it"... but the guiText is attached to the plane...what am I doing wrong??
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    It would help to see the code you're using, as well as a picture of the Inspector when the plane is selected.
     
  3. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    The script is from the MarbleTutorial. I have changed the function Update to function OncollisionEnter().

    Code (csharp):
    1.  
    2. var startTime = 10.0;
    3. function OnCollisionEnter () {
    4.    
    5.  
    6.  // The time left for player to complete level!
    7.    
    8.  
    9.  timeLeft = startTime - Time.time;
    10.    
    11.  
    12.  // Don't let the time left go below zero.
    13.    
    14.  
    15.  timeLeft = Mathf.Max (0, timeLeft);
    16.    
    17.  
    18.  // Format the time nicely
    19.    
    20.  
    21.  guiText.text = FormatTime (timeLeft);
    22. }
    23. // Format time like this
    24. // 12[minutes]:34[seconds].5[fraction]
    25. function FormatTime (time)
    26. {  
    27.  
    28.  
    29.    
    30.  
    31.  var intTime : int = time;
    32.    
    33.  
    34.  var minutes : int = intTime / 60;
    35.    
    36.  
    37.  var seconds : int = intTime % 60;
    38.    
    39.  
    40.  var fraction : int = time * 10;
    41.    
    42.  
    43.  fraction = fraction % 10;
    44.    
    45.  
    46.  // Build string with format
    47.    
    48.  
    49.  // 12[minutes]:34[seconds].5[fraction]
    50.    
    51.  
    52.  timeText = minutes.ToString () + ":";
    53.    
    54.  
    55.  timeText = timeText + seconds.ToString ();
    56.    
    57.  
    58.  timeText += "." + fraction.ToString ();
    59.    
    60.  
    61.  return timeText;
    62. }
    63.  
    The inspectorView of the plane is in the attached pic

    Another idea is telling with a script 'if the car is grounded start the timer, when the car is not grounded reset the timer'. I'm trying to work it out at the moment.
     

    Attached Files:

  4. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Well, the first thing to note is that there is no GUIText component attached to your plane. Note that "attached" means attached directly to the object, either by dragging a script to the object or by choosing something from the Component menu while the object is selected. What you may have is a GameObject which is a child of the plane and has its own GUIText attached. This will not suffice for the script in its current state, because guiText is a reference to a component attached to the same object as the script.

    The script probably won't do what you want in its current state, however. You need an Update() function in order to display the time. Otherwise it will only change when you enter a collision. What are you resetting the timer for? Are you going for a checkpoint system where you have a certain amount of time to get through each part of the track?
     
  5. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    well, I'm trying to make something like a 'Driving On The Mix' game. I have a road wich is consisted of 3 smaller roads. Each one of the smaller roads volumes up one of the 3 tracks of the soundtrack everytime the car is driving on it.

    At the same time you can collect spheres that trigger other random sounds, which contribute to the soundtrack.

    I just need a timer so that I can "force" the player not to drive all the time on the same small road. For example, the car enters in a small road and a timer starts a 20seconds countdown. The player then must collect as many spheres as he can and then change route to the small road at the side before the timer reaches to zero. when he enters the new road then the timer resets and starts the countdown again and so on.
     
  6. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    an even simpler idea maybe will be to change the text of the guiText object everytime there is a collisionenter.

    something like that???




    Code (csharp):
    1. function OnCollisionEnter () {
    2.    
    3. GameObject.Find("Timer").GetComponent(guiText).text = "0:10.0";
    4.  
    5. }
    it doesn't work though. Probably there is an error in the script which try to change the text of the "Timer" guiText object.
     
  7. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    there was a spelling mistake:

    Code (csharp):
    1.  
    2. function OnCollisionEnter () {
    3.    
    4.    
    5. GameObject.Find("Timer").GetComponent(GUIText).text = "0:10.0";
    6. }
    7.  
    8.  
    I attached this scrip to the plane. It's correct but it only works when the timer is not running. So, I think I have to stop the timer before I change the GUItext back to 10 seconds. Or I could just set the timeLeft var of the time script back to 10 seconds. Any Ideas???
     
  8. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    For situations where you have a central timer or controller, I prefer to break it into it's own script as a controller.

    So what you do is create a timer script, with public functions for starting and stopping the timer, and whatever else you need. This "Timer Controller" is then placed on an empty GameObject in your scene.

    Now all you do is get a reference to the timer controller script (either set up a var and drag it to whatever script in the inspector, or better, find it on startup.)

    Here's some basic code to give you an idea
    Code (csharp):
    1.  
    2. //++++this is the timer controller.  It is placed on it's own GO++++
    3.  
    4. public var myGUIText;  //our GUIText
    5.  
    6. public var timer = 0.0;
    7. public var running = false;
    8.  
    9. function Update()
    10. {
    11.     if (running)
    12.     {
    13.        //update the timer and the GUI
    14.     }
    15. }
    16.  
    17. public function StartTimer()
    18. {
    19.     //start the timer
    20.     running = true;
    21. }
    22.  
    23. public function StopTimer()
    24. {
    25.     //stop the timer
    26.     running = false;
    27. }
    28.  
    29. public function ResetTimer()
    30. {
    31.     //etc
    32.     timer = 0.0;
    33. }
    34.  
    35.  
    36.  
    37. //+++++++++++++++++++++++++++++++++++++
    38.  
    39. //now our other code file which accesses the timer
    40. var timer;
    41.  
    42. function Start()
    43. {
    44.     timer = GameObject.Find("Timer Controller").GetComponent("Timer Script");
    45.  
    46.  
    47. function OnCollisionEnter()
    48. {
    49.     //start the timer
    50.     timer.StartTimer();
    51. }
    52.  
    53. function OnCollisionExit()
    54. {
    55.     //stop the timer
    56.     timer.StopTimer();
    57. }
    58.  
    Don't try to use that code as is because a: I dont code JS an I haven't defined the types of vars and such, and b: it is just meant to give you an idea of setup and design. ;-)

    HTH,
    -Jeremy
     
  9. redghost

    redghost

    Joined:
    Mar 7, 2007
    Posts:
    82
    Thanx a lot lot lot!!!!!

    I'm reposting the scripts for anyone who is interested in to see them complete.

    I created the script for the Timer and I attached it on the car.

    Timer.js :

    Code (csharp):
    1.  
    2. var seconds = 11.0;
    3. var timertext : GUIText;
    4. var running = false;
    5.  
    6. function Update () {
    7.     if (running) {
    8.     timertext.text = "change track in " + Mathf.Floor(seconds);
    9.    
    10.     seconds -= Time.deltaTime;
    11.     }
    12.  
    13.   if (seconds < 1) {
    14.         Application.LoadLevel ("Level1");
    15.     }    
    16.    
    17. }
    18.  
    19. function StartTimer() {
    20.    
    21.     running = true;
    22. }
    23.  
    24. function StopTimer () {
    25.    
    26.     running = false;
    27. }
    28.  
    29. function ResetTimer() {
    30.    
    31.     seconds = 11.0;
    32. }
    33.  
    and then a script to restart the timer everytime the car change road.

    controlTimer.js:

    Code (csharp):
    1.  
    2. var timer;
    3.  
    4. function Start(){
    5.    
    6.     timer = gameObject.Find("Car").GetComponent(Timer);
    7. }
    8.  
    9. function OnCollisionEnter(){
    10.    
    11.     timer.StartTimer();
    12.    
    13. }
    14.  
    15. function OnCollisionExit(){
    16.    
    17.     timer.ResetTimer();
    18.    
    19. }
    It seems so simple now that I see it finished!!

    But I don't think I would have ever thought braking it into 2 sub-scripts.

    Thanx again!
     
  10. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Haha, np. I am glad you got it working. Sometimes you get to close to your work and the "forest from the trees" thing kicks in. Helps to get a different perspective. The Unity IRC is awesome for this. ;-)

    -Jeremy