I don’t know if I’m too late for replying this. I’ve also met this problem.
Conclusion first:
a) canvasScaler.scaleFactor is always 1 because I have never set its value (its default value is 1).
b) I have never set its value because my canvasScaler is working in “Scale With Screen Size” mode instead of “Constant Pixel Size” mode.
c) And CanvasScaler doesn’t update the value of scaleFactor in “Scale With Screen Size” mode.
d) Just manually calculate scale factor in the same algorithm can solve this.
I did try to get canvas.scaleFactor and it’s always 1. But I found this: UGUI世界坐标转屏幕坐标_ugui 将场景坐标转换成屏幕坐标-CSDN博客
This article is written in Chinese, but you don’t need to fully understand that. Just look at the code. Some variables are even not been used, and the most important line is too long for me, so I made a little modification:
public static Vector2 WordToScenePoint (Vector3 wordPosition)
{
CanvasScaler canvasScaler = GameObject.Find ("Canvas").gameObject.GetComponent<CanvasScaler> ();
float referenceWidth = canvasScaler.referenceResolution.x;
float referenceHeight = canvasScaler.referenceResolution.y;
float match = canvasScaler.matchWidthOrHeight;
float offect = (Screen.width / referenceWidth) * (1 - match) + (Screen.height / referenceHeight) * match;
Vector2 a = RectTransformUtility.WorldToScreenPoint (Camera.main, wordPosition);
return new Vector2 (a.x / offect, a.y / offect);
}
The most interesting part is defenitely this offect. It is similar to what we really want: canvas.scaleFactor.
Finally I found the reference source of CanvasScaler on 2017.3 (https://bitbucket.org/Unity-Technologies/ui/src/a3f89d5f7d145e4b6fa11cf9f2de768fea2c500f/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs?at=2017.3&fileviewer=file-view-default)
Line 166 to 178: (some is deleted for convinence)
case ScreenMatchMode.MatchWidthOrHeight:
{
// We take the log of the relative width and height before taking the average.
// Then we transform it back in the original space.
// the reason to transform in and out of logarithmic space is to have better behavior.
// If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5.
// In normal space the average would be (0.5 + 2) / 2 = 1.25
// In logarithmic space the average is (-1 + 1) / 2 = 0
float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase);
float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase);
float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight);
scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage);
break;
}
The result is named as “scaleFactor” and looks exactly what we want. But it’s not been kept inside of canvasScaler because there is another float named scaleFactor on Line 163. My math is not that good to fully explain that, but I believe that the calculation of offect is a short version of these when matchWidthOrHeight is 0.5.
The algorithm for offect is working fine in my project. (2018.1.7f1). It should work on 2018.2, I suppose.