Search Unity

Couple of question on Unity 4.3 2d features

Discussion in '2D' started by framusrock, Nov 15, 2013.

  1. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    Hey guys,

    I'm trying my first steps with Unity's new 2d environment at the moment (coming from cocos2d). I'd love to have my game work on iOS / Android My question is: How can I position sprites pixel perfect / depending on screen size. E.g. have the menu button on the top left on the screen.

    I'm parsing levels from XML files. In those files the positions of each sprite are determined. How can I dynamically create sprites when reading in the XML?
     
  2. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    If I'm not mistaken, I think you may be "doing it wrong", or over thinking it.

    In my experience, each level in unity is a scene, and you just set the sprites in Unity. No need for an XML sheet explaining to the app where sprites go -- unity does all that stuff for you.
     
  3. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    You will always have pixel perfect no matter what the screen size is. If you want to dynamically create sprites, you'll need to write a script that places them at various x,y coordinates in Unity's world space. Pay close attention to the sprite sheets you're pulling sprites from, there is a parameter for Pixels to Units (world units) that by default is set to 100, which means every 100 pixel units is equal to 1 unit in unity.
     
  4. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    @unitylover you guessed my head scratching point ;)

    I'm a bit more into it today by trying out more stuff. I found the "2dToolkit" thing in the store to look promising but haven't bought it yet.
    I haven't done it yet but I guess I'll create a script that loads the XML and creates all needed graphics from prefabs.
    Anyway some more questions about this stuff :

    1) So I'm trying it just with basic Unity Free for now. Correct me if wrong: If I just leave that ratio at 100 it's gonna be exaclty the size as it is as a graphic?

    2) That 2dToolkit somehow promises to automatically be able to select the right Sprites (SD vs. HD) version or better to say iPad vs. iPad retina. How would you do that with basic Unity?

    3) How would you do touch begin / touch moved / touch end detection for a set of sprites? I've seen solution that work with raycasts from the camera but I think there must be something easier in 2d ;)

    Thank you so far! Cool community here even if I'm new :)
     
  5. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    I find that an orthographic camera size of 5 and a pixel to world ratio of 100 gives pixel perfect every time.

    You can detect the DPI of the device using the Screen class. The docs are detailed here: http://docs.unity3d.com/Documentation/ScriptReference/Screen.html

    Touch detection can be done any number of ways but I generally look for touch events in the update function. More information can be found here: http://docs.unity3d.com/Documentation/ScriptReference/Input.GetTouch.html
     
  6. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    Camera size is based on the height of the ortho camera view if you're after 1:1 pixel perfect rendering.

    Attach this to your camera and in the Inpector set pixelsPerUnit to the same value you're using as your sprites' Pixels To Units properties.

    Code (csharp):
    1.     public float pixelsPerUnit;
    2.     public int zoom = 1;
    3.  
    4.     void Start () {
    5.         Camera.main.orthographicSize = Screen.height / 2f / pixelsPerUnit / zoom;
    6.     }
    You'll also want to create a clean Sprite Material, and enable Pixel snap.

    Note that 1 Unit = 1 Meter in physics, so if you want nicer results off the bat base your import sizes around that.

    2D Toolkit is well worth the money if you want to get up and running without worrying about this lot; it has a good-to-go camera, decent font and tile mapping support and supports the new 2D physics and sorting layers out of the box with the latest update.
     
    Last edited: Nov 17, 2013
  7. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    Thank you guys!

    @Pix10 What do you mean by "height" of the camera view? Like the the screen rect height?
    Could you explain what that Script is supposed to do? I see the math but not the reason.

    How do I enable PixelSnap? I went to edit --> Snap Settings und there X Y Z are set to 1 (Snap All Axes). Is that correct?

    What do you mean by that? That Box2D operates best with meters < 10 ? With import size you mean UnitsToPixel ratio?

    I'm still wondering how one can automatically switch out the resource graphics depending on the screen size. E.g. Having double size images on iPad retina.
     
  8. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    Yep, screen.height

    It's setting the camera's orthogonal size - that is, how large a single world unit is in the view*. Rather than attempt a maths lesson (and my math isn't so great), it's worth googling "pixel perfect camera unity"....there's a huge amount of info on the topic.

    *Example: You can test this by setting camera's Size to 1, and putting a default Cube in the scene. Cubes are 1 unit in size, and take up half the camera's view (in the vertical).

    It's not a system setting, it's a sprite material setting. Select a (Unity) sprite, check out the material (which is a new type for Sprites).


    No not at all, but physics properties work more predictably if you use close-to-real-world values. Don't worry about it too much.

    That's a whole other topic - Here we just store two versions of each set, mostly for quality reasons rather than anything else...again though, 3rd party tools such as 2D Toolkit will make life easier.
     
    Last edited: Nov 17, 2013
  9. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    Thanks, I understood!

    Here comes today's problem: I manged to load XML and create a level from it (with prefabs). Everything works and I just enabled a basic sprite dragging for testing. That works fine in Unity itself. As soon as I deploy to iPad it crashes on the Splashscreen with exc_bad_access. I found out it could be a null reference.

    I have the suspicion that my XML file didn't make it to the iOS build but I'm not sure...The crash occurs to a line when I try to access the loaded dictionary. I've put the XML files into a folder called "Resources". Do I have to do something special to make that work?
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    There is no Resources folder in a build. I assume you're using System.IO commands; you should use a TextAsset file instead.

    --Eric
     
  11. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    Sorry, you're right of course. I've set up a Singleton and I'm loading Assets with that path:

    Code (csharp):
    1. string plistPath = Application.dataPath + "/Resources/LevelsXML/easy.plist";
    That works fine in Unity itself but I guess Unity won't copy the Assets over when building for iOS since it thinks those are unused.
    I'm loading these from a Singleton since I want them to be available throughout the project.

    I guess I can't set the right file as an asset in the inspector using

    Code (csharp):
    1. public TextAsset textAsset;
    since my class is a singleton and won't appear in the hiearchy view.
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You could use Resources.Load.

    --Eric
     
  13. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
    I had another hour of fun with Resources.Load and still no luck, so I'm asking again here ;)

    Code (csharp):
    1.  
    2.         TextAsset newTextAsset = (TextAsset) Resources.Load ("myLevel"); // is a txt file
    3.         XmlDocument xml = new XmlDocument();
    4.         xml.XmlResolver = null; //Disable schema/DTD validation, it's not implemented for Unity.
    5.         xml.LoadXml(newTextAsset.text);
    6.  
    This works perfectly in the Unity preview thing (pressing the play button). But on device all I load is null. So I guess the files are simply missing.
     
  14. framusrock

    framusrock

    Joined:
    Nov 15, 2013
    Posts:
    15
  15. Gonjes

    Gonjes

    Joined:
    Jul 10, 2013
    Posts:
    14
    every 100 pixel units is equal to 1 unit in unity

    @unitylover: can you tell me what it means?
    i don't understand what is pixel in units and what is unit in unity.
    ex: 1 use resolution 1024 x 768 then i make a cube but when i used unity lower than 4.3 1 pixel in unity same to 1 pixel from the resolution i set.
    but when i used unity 4.3 q move position 1 pixel in unity then @game screen it moved alot then when i move the cube object to 29.5 it was like the position is 1024 pixel from left to right at game screen..
    what i want to know is how can i count how much pixel in unity is same to 1 pixel to screen resolution that show on game screen.

    thanks
     
  16. dukester

    dukester

    Joined:
    Nov 7, 2012
    Posts:
    14
    @Gonjes:
    I may be wrong, but I think Unity's coordinates were never about pixels.
    A "unit" in Unity is what you set in the Transform's Position fields (X,Y,Z). Unit roughly means one amount of something.
    Position is about units of length. In some places in the world it's the meters, in others it's feet. In Unity it could be whatever you want, just as long as you're consistent throughout your project. For example, a human figure in your game might be 1.8288 units high if you decide you want to work with meters, or it could be 6.00 units high if you decided to work in feet as units. Unity doesn't care. And it doesn't have anything to do with pixels.
    For your "ex:1", it would only be true if you used Orthographic camera and set its orthographicSize to 384.
    This "orthographicSize" property is what you want to adjust to get 1 to 1 ratio of Unity units to pixels on screen.
    So, set the type of camera to "Orthographic", and set its size to half your screen height. For 1024x768, the size would be 384. For 800x600 the size would be 300 etc.
    You may ask how does Unity know about the other (horizontal) size if you only set (half of) its vertical size. Well, it takes that from the current resolution it's running on (during runtime).
    Plus, there's a parameter of the orthographic camera that you can't see in the inspector called "aspect". You can access it from script. Aspect is width divided by height.
    If you set your project's default resolution to 1024x768 and your camera's orthographic size to 384, then when you run your game on a 16:10 monitor, you will have black bars on the left and right sides. If you want Unity to stretch your game content to fill the whole screen, you need to put something like this in your Start() method:
    Code (csharp):
    1. Camera.main.orthographicSize = 1024/768;
    This will stretch your graphics in the horizontal direction, but according to my knowledge most players prefer it this way as opposed to having black bars on the sides.
    Hope this helps.
     
    Last edited: Nov 24, 2013
  17. iansnyder

    iansnyder

    Joined:
    Dec 22, 2012
    Posts:
    27
    @Pix10 thanks for all the info!
     
  18. Shnayke

    Shnayke

    Joined:
    Mar 29, 2013
    Posts:
    11
    I'll be extremely interested to see if you get projectiles driven by Rigidbody2Ds working in your scenario. I came across this problem -and this thread here that indicates that if you want to use Rigidbody2D.velocity, you pretty much should stick with the default 100 pixels to 1 unit ratio that Unity imports your sprites at.