I'm making a Neural Network modeling program, and I've already made a tiled Image for my background grid.
I'm trying to change Image Pixels per Unit Multiplier via code, which doesnt work (Editing it via editor in runtime works just fine)
Here's my code for Zoom In/Out:
float desiredSize = this.GetComponent<Camera>().orthographicSize;
desiredSize -= Input.mouseScrollDelta.y * 3;
//Clamp between min and max
desiredSize = Mathf.Clamp(desiredSize, minSize, maxSize);
//Smoothly interpolates to desired size
this.GetComponent<Camera>().orthographicSize = Mathf.Lerp(this.GetComponent<Camera>().orthographicSize, desiredSize, 5f * Time.deltaTime);
//Change pixels per unit multiplier to half of camera's size (with only 1 decimal char)
gridImage.pixelsPerUnitMultiplier = Mathf.Round( (this.GetComponent<Camera>().orthographicSize / 2) * 10f) / 10f;
It changes the value of pixels per unit just as intended, but it doesnt seems to have any effect on the Image itself.
Interesting that this property is nowhere documented. I didn't even find it in the source codes of the ImageEditor
nor the GraphcisEditor
yet so now I'm really interested in what is actually responsible for displaying this field ^^
What I found however is that after doing changes to the size settings the editors call EditorUtility.SetDirty(graphic);
. Ofcourse this is not available in a build but it made me look for - I think - the correct solution:
After changing the property you have to call SetVerticesDirty
gridImage.SetVerticesDirty();
or simply SetAllDirty
gridImage.SetAllDirty();
I'm not sure about efficiency though .. you probably should call this only if the value actually changed.
Also avoid all those repeated GetComponent
calls! Do it once in Awake
and then re-use the reference.
Finally currently your Lerp
is useless! Since you get the current size and calculate the desired size on that one there will be no smooth scaling at all. Rather use a global field in the class and update that one:
// would even be better if you can already reference this in the Inspector
[SerializeField] private Camera _camera;
public Image gridImage;
public float minSize;
public float maxSize;
private float desiredSize;
private void Awake()
{
if (!_camera) _camera = GetComponent<Camera>();
// initialize the desired size with the current one
desiredSize = Mathf.Clamp(_camera.orthographicSize, minSize, maxSize);
// do it once on game start
UpdateImage(desiredSize);
}
// Update is called once per frame
private void Update()
{
var currentSize = _camera.orthographicSize;
desiredSize -= Input.mouseScrollDelta.y * 3;
//Clamp between min and max
desiredSize = Mathf.Clamp(desiredSize, minSize, maxSize);
// is the scaling already done?
// -> Skip unnecessary changes/updates
if (Mathf.Approximately(desiredSize, currentSize)) return;
//Smoothly interpolates to desired size
_camera.orthographicSize = Mathf.Lerp(currentSize, desiredSize, 5f * Time.deltaTime);
UpdateImage(_camera.orthographicSize);
}
private void UpdateImage(float size)
{
//Change pixels per unit multiplier to half of camera's size (with only 1 decimal char)
gridImage.pixelsPerUnitMultiplier = Mathf.Round(size / 2 * 10f) / 10f;
gridImage.SetVerticesDirty();
}
Fixed Version:
This slight jitter at the end of the "animation" comes from your rounding when assigning the pixelsPerUnitMultiplier
you might want to consider removing this round and simply apply
gridImage.pixelsPerUnitMultiplier = size / 2f
I've got tru all the documentation and find nothing as well, but your answer solved it for me ^^ Thanks, youre the best