Jump to content

Unity UI Creation Tutorial


Recommended Posts

1 hour ago, stupid_chris said:

Other than that, is there any particular reason it seems to be recommended to anchor in the top left? Just as a convenience or does KSP handle it's Canvas in a specific way that makes this more convenient?

There's no particular reason to use a top-left anchor. If you set the anchor and pivot center to top-left (pivot x = 0, y = 1) then I suppose it's a little easier to position elements; x pixels to the right of the parent's left side, and -y pixels down from the top.

If you have a completely static UI, no option to resize the window, no dynamically changing elements or window size, then you can set the anchors to whatever you want. Top-left (or bottom-left) does make some sense for the top level of the UI window, since it makes it a little easier to position the window on screen (though you do run into potential problems with the UI loading off the screen on the right or the bottom, having some code to clamp the window position to the screen helps with this).

But for a dynamic UI there are lots of cases where you want other anchors. You might want elements that stick to different corners of your UI when you resize it. Or you want elements to expand to fill the window (using the blue anchor preset options). And there are other more complicated situations, like you want a label to be 1/3 of the way along a resizable bar, then you would need to manually set the anchors.

As I think I mentioned somewhere in the tutorial, the rect transform anchors are confusing and the best way to get a handle on them is just to fiddle around with them. This is also a situation where having your code run in the Unity editor is helpful. You could run all of the code needed to add a re-size handle to a window, then just play the scene in the editor and see how the different rect transform anchors behave, instead of having to run KSP every time you need to change something.

Link to comment
Share on other sites

  • 8 months later...
  • 2 months later...
  • 11 months later...

@DMagic First of all, thanks a lot for the amazing tutorial. I was able to go from zero to an almost complete UI for the PersistentThrust mod with only this tutorial and your mods as references(alright, not only, but these were by far the biggest sources).

But I have now encountered an issue with TextMeshPro: after including the code to replace the Text components, I can't find a way to make the text alignment option persist. Every text field is reset to upper left alignment when converted to TMP. There's also a different issue, which is that TMP font size doesn't correspond to Text font size; specifically, TMP text is always smaller. This is a minor issue compared to alignment completely breaking, so I can ignore it for the moment.

I have double-checked the code you have posted here, and even copy-pasted the TMProFromText code from BasicOrbit (since I know for certain that it works), but to no avail. The code is all available on github, but I'll post the TMProFromText method code here anyway, since I guess that's where the error lies. If you have any idea why this is happening, please let me know since I really can't find any error.

Spoiler

private void TMProFromText(TextHandler handler)
{
	if (handler == null)
		return;

	//The TextHandler element should be attached only to objects with a Unity Text element
	//Note that the "[RequireComponent(typeof(Text))]" attribute cannot be attached to TextHandler since Unity will not allow the Text element to be removed
	Text text = handler.GetComponent<Text>();

	if (text == null)
		return;

	//Cache all of the relevent information from the Text element
	string t = text.text;
	Color c = text.color;
	int i = text.fontSize;
	bool r = text.raycastTarget;
	FontStyles sty = TMPProUtil.FontStyle(text.fontStyle);
	TextAlignmentOptions align = TMPProUtil.TextAlignment(text.alignment);
	float spacing = text.lineSpacing;
	GameObject obj = text.gameObject;

	//The existing Text element must by destroyed since Unity will not allow two UI elements to be placed on the same GameObject
	DestroyImmediate(text);

	PTTextMeshProHolder tmp = obj.AddComponent<PTTextMeshProHolder>();

	//Populate the TextMeshPro fields with the cached data from the old Text element
	tmp.text = t;
	tmp.color = c;
	tmp.fontSize = i;
	tmp.raycastTarget = r;
	tmp.alignment = align;
	tmp.fontStyle = sty;
	tmp.lineSpacing = spacing;

	//Load the TMP Font from disk
	tmp.font = UISkinManager.TMPFont;
	//tmp.font = Resources.Load("Fonts/Calibri SDF", typeof(TMP_FontAsset)) as TMP_FontAsset;
	tmp.fontSharedMaterial = Resources.Load("Fonts/Materials/Calibri Dropshadow", typeof(Material)) as Material;

	tmp.enableWordWrapping = true;
	tmp.isOverlay = false;
	tmp.richText = true;
}

 

 

Link to comment
Share on other sites

  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...