Hi,
I have found a procedure to reproduce this bug.
- First create a prefab which contains a UILabel with some text.
The UILabel uses a bitmap font which atlas also contains other sprites. - Create a GameObject under UIPanel, and attach the following component "Testbed" to it.
- Make _prefab field reference to the prefab you just created. (The one contains UILabel)
- Save the scene. Close and restart Unity. By default, Unity will load the scene opened before exit Unity.
- Hit play button.
public class Testbed : MonoBehaviour {
[SerializeField]
GameObject _prefab;
void Awake(){
GameObject go = (GameObject)GameObject.Instantiate(_prefab);
go.transform.parent = this.transform;
go.transform.localPosition = Vector3.zero;
go.transform.localScale = Vector3.one;
}
}
Testbed will instantiate the prefab with
UILabel, so you will see the text of
UILabel.
However, the display text will be garbled.
This is because of miscalculation of
mUVRect of
UIFont.
By design,
mUVRect is computed in the first call of
get method of
UIFont.uvRect property.
public Rect uvRect
{
get
{
if (mReplacement != null) return mReplacement.uvRect;
if (mAtlas != null && (mSprite == null && sprite != null))
{
//compute mUVRect
}
return mUVRect;
}
However, if mSprite is assigned and not equal to null due to some reason,
the codition
mAtlas != null && (mSprite == null && sprite != null)
will always be false, and mUVRect will be never computed.
I have used debugger to monitor UIFont.mSprite and found that
mSprite will automatically assigned to an empty UISpriteData created by the default constructor when entering play mode.
But I cannot find where UIFont.mSprite is assigned, so I guess UIFont.mSprite is assigned an empty object created by Unity debug serialization in very first stage of launching Play Mode.
To fix the problem, change the condition
mAtlas != null && (mSprite == null && sprite != null)
in
UISprite.uvRect.get to
mAtlas != null && ( !mSpriteSet && sprite != null)
.
Alvin