Search Unity

Getpixel outputting color from a different location

Discussion in 'Scripting' started by alterix97, Feb 20, 2020.

  1. alterix97

    alterix97

    Joined:
    Oct 7, 2019
    Posts:
    42
    So I have a map, with alot of colored regions on it, and some gameobjects on top of these colored regions. I'm trying to implement some code that gets the location under the objects and assigns it to a variable, and I have all of these objects as children of another object. I have this code

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using System;
    4.  
    5. public class NodeNeighborAssigner : MonoBehaviour
    6. {
    7.     private Node[] NodeArray;
    8.     private Transform[] TransformArray;
    9.     public Texture2D ProvinceMap;
    10.     Color32 NodeColor;
    11.     ProvinceSelection _ProvinceSelection;
    12.     void Start()
    13.     {
    14.         NodeArray = this.GetComponentsInChildren<Node>();
    15.         TransformArray = this.GetComponentsInChildren<Transform>();
    16.         for(int i =1; i < NodeArray.Length;i++){
    17.             Vector3 position = TransformArray[i].position;
    18.             int x = (int)position.x;
    19.             int y = (int)position.y;
    20.             NodeColor = ProvinceMap.GetPixel(x, y);
    21.             print (NodeColor);
    22.             //Here I use the color to get something from a json using a function in another script
    23.             int id = Convert.ToInt32(_ProvinceSelection.GetProvince(Convert.ToString(NodeColor), "Provinces"));
    24.             print (id);
    25.             NodeArray[i].provinceid = id;
    26.         }
    27.     }
    28. }
    29.  
    For some reason, when this is used for the first game object, upload_2020-2-20_16-10-11.png
    it outputs the color of the dark green to it's left. Can anyone see the issue in the code?
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    My first guess is that you may be shifting between different coordinate systems without proper conversions. Is your texture being displayed so that 1 pixel = 1 game unit? (Note: An Image component will NOT enforce that on its own.)

    You might try printing X and Y and comparing them to the texture dimensions, and/or checking several positions in your map and seeing if there's a pattern to the way that your output is wrong (e.g. does it always shift to the left? is it looking at the mirror-image position? etc.)

    It's also a bit weird that your loop counter starts at 1 (rather than 0) and that you are counting up to NodeArray.length but are actually using i as an index into TransformArray, but those are unlikely to be related to your symptom.
     
    alterix97 likes this.
  3. alterix97

    alterix97

    Joined:
    Oct 7, 2019
    Posts:
    42
    Thank's for the quick response! Ok, by my texture being 1 pixel for 1 unit do you mean upload_2020-2-20_16-33-22.png on my image's import settings? As for the weird stuff, my Node Array an Transform Array both pull for the children so it makes no difference, as for the node array starting at 1, that was a mistake I made, thanks for pointing that out. I have a doctor's appointment now so I probably can't respond for an hour or two.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    No, I'm asking about how the texture is actually rendered on the screen. For example, if you use a UI.Image component with default settings ("Simple" image type), then it will stretch the sprite to fill the available space, so if you rendered a 1000x1000 map but your game window is 1920x1080 then it will scale your image by a factor of 1.92 horizontally and 1.08 vertically. (No matter what you put in the "pixels per unit" box in the import settings.)

    Also, that assumes that 1 pixel on your screen equals 1 game unit on your Canvas--which is often not true, if you are using a Canvas Scaler.

    Basically, you either need to make sure that the size of the GameObject displaying your picture (in Unity game units, after scaling) exactly matches the size of your texture (in pixels)...or you need to do a coordinate transform where you look at how far across your map the object is in percentage terms and then find the proportional point in the texture.
     
  5. alterix97

    alterix97

    Joined:
    Oct 7, 2019
    Posts:
    42
    Ok, so I have this on a UI panel which takes up the whole screen. The canvas is set to scale with screen size and the reference screen size is identical to the texture and has a reference pixels per unit of 1, will that work?
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Not when you're using positions in global coordinates. Canvas Scalers work by applying a scale value to the Canvas, which means the local coordinates of everything inside the Canvas stay the same size, but when you convert to global coordinates everything is bigger/smaller based on the actual screen size.

    (Also, beware of changes to screen aspect ratio!)
     
  7. alterix97

    alterix97

    Joined:
    Oct 7, 2019
    Posts:
    42
    I got it to work! Thank you!