Search Unity

FPS Tutorial

Discussion in 'Scripting' started by tholland, Jul 15, 2009.

  1. tholland

    tholland

    Joined:
    May 28, 2009
    Posts:
    129
    This is code included in the FPS Tutorial:

    Code (csharp):
    1. function UpdateGUI ()
    2. {
    3.     // Update health gui
    4.     // The health gui is rendered using a overlay texture which is scaled down based on health
    5.     // - Calculate fraction of how much health we have left (0...1)
    6.     var healthFraction = Mathf.Clamp01(hitPoints / maximumHitPoints);
    7.     // - Adjust maximum pixel inset based on it
    8.     healthGUI.pixelInset.xMax = healthGUI.pixelInset.xMin + healthGUIWidth * healthFraction;
    9.  
    10.     // Update machine gun gui
    11.     // Machine gun gui is simply drawn with a bullet counter text
    12.     if (machineGun)
    13.     {
    14.         bulletGUI.text = machineGun.GetBulletsLeft().ToString();
    15.     }
    16.    
    17.     // Update rocket gui
    18.     // We use a quicktime movie with 20 frames to display how many are left
    19.     // The alpha of the movie changes every frame thus rockets get masked out when changing the frame.
    20.     if (rocketLauncher)
    21.     {
    22.         var rocketTexture : Texture2D =  rocketGUI.texture;
    23.         rocketTexture.frame = rocketLauncher.ammoCount;
    24.     }
    This generates a compiler error 'frame' not member of Texture2D. I can see what the code is trying to do but cannot find a way around it. Can anyone help, please.
     
  2. Alec-Slayden

    Alec-Slayden

    Joined:
    Dec 16, 2008
    Posts:
    101
    While an actual frame operator would be nice, the only way I know of animating a texture2D is through manipulating its offset (after determining the proper scale). Forgive me if there turns out to be a far simpler way.

    you can use http://www.unifycommunity.com/wiki/index.php?title=Animating_Tiled_texture_-_Extended
    as an example of an animated cycle, which may be more than you need, but I'll continue here just in case.


    -----
    Assuming your rocketTexture is evenly sliced into sprites, here is what I would do:

    In the material, set the "tile x" as the inverse of the number of frames in a row;
    if the rocket texture is 4 frames across, it'd be 1/4, so set it to 0.25.
    if it's 2 across it'd be 0.5, etc.

    do the same for the "tile y", based on how many frames are in the columns. This will tell the renderer to only use a small portion of the image, equal to the frame size.

    Next, while it might seem redundant, we're going to actually need to *know* the frame size, even though the renderer has tiled it properly. If you don't know this offhand, multiply the image width by your new tile x (this will give you the width of each frame), and the image height by the tile y (for the height of each frame). The script linked above shows a way of handling that math internally, instead of doing it yourself.

    I recommend throwing these numbers into variables in your script like frameWidth and frameHeight to keep track of them simply.

    When it comes time in the script to change the frame, we'll shift the offset, effectively telling the renderer to use the next frame-sized section of the image. The first frame's index is 0.

    Here's an example (in Javascript) of what I believe would be one way to set up a frame change without animating through a cycle. You'll need to specify the frameLimit (total # of frames) in this version. This will prevent accidental input beyond the total number of frames. You'll also need to supply the row and column count.

    Code (csharp):
    1.  
    2. /////// initialized variables  /////////
    3. var frameHeight : float = ???;//set these as calculated.
    4. var frameWidth : float = ???;
    5.  
    6. var frameLimit : int = ???; // set this to your total # of frames.
    7. var columns : int = ???; // how many frames are there in a row?
    8. var rows : int = ???; // how many in a column?
    9.  
    10.  
    11. // call ChangeFrameTo(#) to change the frame number, 0 is first frame
    12.  
    13. function ChangeFrameTo(frameNumber){
    14.  
    15.      if (frameNumber < 0)
    16.           frameNumber = 0; //clamps minimum frame to first frame.
    17.  
    18.      if (frameNumber > frameLimit)
    19.          frameNumber = frameLimit; //clamps maximum frame to last frame.
    20.      
    21.      //return the offset x to 0 if the frame's in a new row.
    22.      var offset_x : int;
    23.      if (frameNumber != 0) // avoid dividing by zero...
    24.           offset_x = frameWidth * (columns % frameNumber);
    25.      else
    26.           offset_x = 0;
    27.  
    28.      // increase the offset y for additional rows    
    29.      // we take a shortcut here by rounding down a division.
    30.      // offset_y will only change when the frame number = column count,
    31.      // and since the index starts at 0,
    32.      // thats actually the start of a new row.
    33.      var offset_y : int = frameHeight * Mathf.Floor(frameNumber / columns);
    34.      
    35.      //now we combine the offsets to a vector...
    36.      var offset = Vector2(offset_x, offset_y);
    37.      
    38.      //and change the material offset directly.  
    39.      renderer.material.SetTextureOffset ("_MainTex", offset);
    40.  
    41. }
    42.  
    43.  
    I haven't actually tested this code, so I might be missing one thing or another.

    If you're more comfortable or your code requires your first frame to be index 1,
    you can throw "frameNumber--; " in at the start of the function.
    other ways could involve linking the texture2D to a variable, to grab the width etc and let the script do the calculations for you.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can use an array of textures. ".frame" is from Unity 1.x and is no longer supported.

    --Eric
     
  4. Alec-Slayden

    Alec-Slayden

    Joined:
    Dec 16, 2008
    Posts:
    101
    an array of textures...
    so simple...
    brilliant!
     
  5. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Forum tip: use the Code button, or manually use code blocks around scripts for better formatting. I've edited your post above as an example so you can see how it looks. :)
     
  6. tholland

    tholland

    Joined:
    May 28, 2009
    Posts:
    129
    Thanks A.A.Slayden and Eric5h5. I'll give both suggestions a try.