Okay this may be really simple, but every attempt I make the console throws up various errors. If i have if(GUI.Button(new Rect(x, y, Screen.width, z), "play")) { How would I go about changing the size of the text. I have a custom GuiSkin used on the text, but I'm unsure how to change the font size of the text without using the inspector - I am using unity. What I am trying to do is change the font size depending on the screen resolution.
If you have create your GUiSkin object, first you can using inspector to change GuiSkin.Button.FontSize. Then apply this setting in you button.
public GUISkin yourGuiSkinObject;
void OnGUI()
{
if(GUI.Button(new Rect(0, 0, 100, 20), "Test", yourGuiSkinObject.button))
{
//Do something.
}
}
Second you can using script to change fontSize. And change the size depend on the screen's height.
public GUISkin yourGuiSkinObject;
void Start()
{
int scale = Screen.height / 20;
yourGuiSkinObject.button.fontsize = scale;
}
void OnGui()
{
if(GUI.Button(new Rect(0, 0, 100, 20), "Test", yourGuiSkinObject.button))
{
}
}
Related
I am trying to develop a little tool for the Unity editor using IMGUI and GL, and I came up with a problem.
I have the following code:
public class TestWindow : EditorWindow
{
[MenuItem("TEST/Test")]
static void Open()
{
var window = GetWindow<Test>();
window.Show();
}
void OnGUI()
{
DrawSquare(new Rect(10, 10, 20, 20), Color.red);
DrawSquare(new Rect(10, 40, 20, 20), Color.magenta);
GUIStyle style = new GUIStyle("label");
style.normal.background = Texture2D.whiteTexture;
style.normal.textColor = Color.black;
style.alignment = TextAnchor.MiddleCenter;
GUI.Label(new Rect(40, 10, 80, 50), "Hello World", style);
DrawSquare(new Rect(130, 10, 20, 20), Color.blue);
DrawSquare(new Rect(130, 40, 20, 20), Color.cyan);
}
private static void DrawSquare(Rect rect, Color color)
{
GL.PushMatrix();
GL.Begin(GL.QUADS);
GL.Color(color);
GL.Vertex3(rect.xMin, rect.yMin, 0);
GL.Vertex3(rect.xMax, rect.yMin, 0);
GL.Vertex3(rect.xMax, rect.yMax, 0);
GL.Vertex3(rect.xMin, rect.yMax, 0);
GL.End();
GL.PopMatrix();
}
}
The problem that I am having is that it seems like GUI.Label is blocking the remaining GL calls from being drawn in the editor window. If you run this code, you will see the red and magenta squares, followed by the label, but the blue and cyan squares are not drawn. If you comment/remove the label, then they are. I tried without the style as well and made no difference.
I managed to find out that any GUI call that will draw content into the window will block the other two squares from being drawn. For example, drawing a GUI.Label with empty string text, will still draw the blue and cyan squares.
I saw the C# reference source code from Unity, and I notice that there is a check for empty string before calling some native code, so I assume that the issue comes all the way from C++.
If anyone knows how could I prevent this (maybe there is some GL or C# method that I can use to prevent this) I would appreciate it.
P.S: Worst case scenario I can handle the code to draw all GL stuff first, and then any GUI calls, but I still would like to be able to mix them freely if there is a way.
I'm having this problem with sprites in my Unity3D project. Basiclly I can't change sprite in SpriteRenderer component during runtime. During my research I've only seen solutions that require you to have the sprite pre-loaded, but I can't because it's generated based on the users input image.
So what happens is the user can change the background of the "game" by inputing his own photo from his computer. I get the photo in and everything and I generate a sprite from it, but when I change the base sprite with his sprite, nothing happens. The base sprite is still showing. If I put the background sprite on a panel's Image in canvas, then everything works great, but if I do the same with SpriteRenderer then nothing happens. Here is my code:
public class UploadImage : MonoBehaviour
{
public GameObject background;
public Sprite sp;
[DllImport("__Internal")]
private static extern void ImageUploaderCaptureClick();
public void setTexture(Texture2D texture)
{
sp = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(texture.width / 2, texture.height / 2));
background.GetComponent<SpriteRenderer>().sprite = sp;
}
IEnumerator LoadTexture(string url)
{
WWW image = new WWW(url);
yield return image;
Texture2D texture = new Texture2D(1, 1);
image.LoadImageIntoTexture(texture);
Debug.Log("Loaded image size: " + texture.width + "x" + texture.height);
setTexture(texture);
}
void FileSelected(string url)
{
StartCoroutine(LoadTexture(url));
}
public void OnButtonPointerDown()
{
#if UNITY_EDITOR
string path = UnityEditor.EditorUtility.OpenFilePanel("Open image", "", "jpg,png,bmp");
if (!System.String.IsNullOrEmpty(path))
FileSelected("file:///" + path);
#else
ImageUploaderCaptureClick ();
#endif
}
}
I can't have the background on an image in canvas because other game objects lose transparency and if I set the alpha on image too low, then when game objects move, it leaves everything blurry.
Thanks for your help
I think you are setting the sprites pivot wrong when generating the sprite. Your sprite should even be displayed at the moment but its far away from where you expect it to be.
Change your code to something like this:
sp = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
This question is asked before but since it doesn't work and my lack of reputation point(I tried to comment at question but I couldn't) I had to ask this question again.
This is the link of the quustion asked before;
How to zoom at a point in picturebox
I used the code which is shown in the link but when I run it the point or shape disappear.
here is my code;
public partial class Form1 : Form
{
private Matrix transform = new Matrix();
private double m_dZoomscale = 1.0;
public static double s_dScrollValue = .1;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Transform = transform;
Pen mypen = new Pen(Color.Red,5);
Rectangle rect = new Rectangle(10, 10, 30, 30);
e.Graphics.DrawRectangle(mypen, rect);
}
protected override void OnMouseWheel(MouseEventArgs mea)
{
pictureBox1.Focus();
if (pictureBox1.Focused == true && mea.Delta != 0)
{
ZoomScroll(mea.Location, mea.Delta > 0);
}
}
private void ZoomScroll(Point location, bool zoomIn)
{
transform.Translate(-location.X, -location.Y);
if (zoomIn)
transform.Scale((float)s_dScrollValue, (float)s_dScrollValue);
else
transform.Scale((float)-s_dScrollValue, (float)-s_dScrollValue);
transform.Translate(location.X, location.Y);
pictureBox1.Invalidate();
}
The answer you are referencing cannot possibly work. I have no idea why it was accepted, nor up-voted. Except that at some time in the past, I apparently up-voted it as well. I don't know what I was thinking.
Anyway, that code has some problems:
It uses the mouse coordinates passed in directly, rather than converting them to the coordinate system for the PictureBox control. The coordinates passed to the OnMouseWheel() method are relative to the Form itself, so only if the PictureBox top-left coincides with the Form's upper-left corner would that work.
More problematically, the code is completely misusing the Matrix.Scale() method, passing a value that seems intended to be a delta for the scale, when in fact the Scale() method accepts a factor for the scale. This has two implications:
Passing a negative value is wrong, because negative values flip the coordinate system, rather than reducing the scale, and
Passing an increment value is wrong, because the value passed will be multiplied with the current scaling to get the new scaling.
Also problematic is that the code applies the matrix transformations in the wrong order, because the default order is "prepend", not "append" (I find the latter more natural to work with, but I assume there's some reason known to those who specialize in matrix math that explains why the default is the former).
There is also the relatively minor issue that, even ignoring the above, allowing the user to adjust the scale factor arbitrarily will eventually lead to an out-of-range value. It would be better for the code to limit the scale to something reasonable.
Here is a version of your code, modified so that it addresses all of these issues:
private Matrix transform = new Matrix();
private float m_dZoomscale = 1.0f;
public const float s_dScrollValue = 0.1f;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Transform = transform;
Pen mypen = new Pen(Color.Red, 5);
Rectangle rect = new Rectangle(10, 10, 30, 30);
e.Graphics.DrawRectangle(mypen, rect);
}
protected override void OnMouseWheel(MouseEventArgs mea)
{
pictureBox1.Focus();
if (pictureBox1.Focused == true && mea.Delta != 0)
{
// Map the Form-centric mouse location to the PictureBox client coordinate system
Point pictureBoxPoint = pictureBox1.PointToClient(this.PointToScreen(mea.Location));
ZoomScroll(pictureBoxPoint, mea.Delta > 0);
}
}
private void ZoomScroll(Point location, bool zoomIn)
{
// Figure out what the new scale will be. Ensure the scale factor remains between
// 1% and 1000%
float newScale = Math.Min(Math.Max(m_dZoomscale + (zoomIn ? s_dScrollValue : -s_dScrollValue), 0.1f), 10);
if (newScale != m_dZoomscale)
{
float adjust = newScale / m_dZoomscale;
m_dZoomscale = newScale;
// Translate mouse point to origin
transform.Translate(-location.X, -location.Y, MatrixOrder.Append);
// Scale view
transform.Scale(adjust, adjust, MatrixOrder.Append);
// Translate origin back to original mouse point.
transform.Translate(location.X, location.Y, MatrixOrder.Append);
pictureBox1.Invalidate();
}
}
With this code, you will find that no matter where you place the mouse before adjusting the mouse wheel, the rendered image will scale while keeping the point under the mouse fixed in place.
Note:
I took a look at some of the similar questions on Stack Overflow, and there are a few that might also be useful to you. Some of the answers overcomplicate things, in my opinion, but all should work. See:
Zoom To Point Not Working As Expected
Zoom in on a fixed point using matrices
Zooming graphics without scrolling
I want to ask a question. How could I make a chat background similar like this link?
Link
With the auto text (the text will automatically typed one by one words per time).
The thing is, I already done the chat background similar to the image above, but with the transparent background, when I tried to fill the transparent background with the text in it, the text did not show.
Here is the image when it is on transparent background:
And here is the code that I have been using for this one (auto text):
using UnityEngine;
using System.Collections;
public class AutoText : MonoBehaviour
{
public float letterPause = 0.5f; // Define and set the pause for each letters
public AudioClip sound = null; // For the sound
public GUISkin customLabel = null; // For the label
public static string message = "Help...! Help...!" + "\n" + "Somebody...! Please Help Me...!"; // The message
private void Start()
{
StartCoroutine(TypedText());
}
private void OnGUI()
{
GUI.Label(new Rect((Screen.width / 2) - 250, (Screen.height / 2) - 200, 500, 500), message, customLabel.customStyles[0]);
}
IEnumerator TypedText()
{
// Loop through the message
foreach (char letter in message.ToCharArray())
{
// Set the gui text to be same with message
guiText.text += letter;
// If sound available
if (sound)
{
// Play it on each words
audio.PlayOneShot(sound);
// Go back to the if statement
yield return 0;
}
// Each letters will be shown for how many seconds delay
yield return new WaitForSeconds(letterPause);
}
}
}
For the text itself, I create a gui text and the gui skinin the unity editor and put the script on it, like the below image:
And also, when I tried to set the chat background to not be transparent, the text is on behind the chat background (so the text not been shown)
Thank you very much sir for answering this question and interest with it
Can't you just try and draw the Texture behind the Text :)?
Start by adding the texture as a variable in the script
public Texture2D Background;
Then change your OnGUI into
private void OnGUI()
{
GUI.DrawTexture(new Rect((Screen.width / 2) - 250, (Screen.height / 2) - 200, 500, 500), Background);
GUI.Label(new Rect((Screen.width / 2) - 250, (Screen.height / 2) - 200, 500, 500), message, customLabel.customStyles[0]);
}
Don't forget to assign the background texture in the editor first; Also on the imported texture. Set the Transparency to be from the alpha channel.
Without testing this I can ALMOST guarantee that it will work :-)
I've got drawing sprites to work with OpenTK in my 2d game engine now. Only problem I'm having is that custom drawn objects with opengl (anything but sprites really) show up as the background color. Example:
I'm Drawing a 2.4f width black line here. There's also a quad and a point in the example, but they do not overlap anything that's actually visible. The line overlaps the magenta sprite, but the color is just wrong. My question is: Am I missing an OpenGL feature, or doing something horrible wrong?
These are the samples of my project concerning drawing: (you can also find the project on https://github.com/Villermen/HatlessEngine if there's questions about the code)
Initialization:
Window = new GameWindow(windowSize.Width, windowSize.Height);
//OpenGL initialization
GL.Enable(EnableCap.PointSmooth);
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
GL.Enable(EnableCap.LineSmooth);
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.ClearColor(Color.Gray);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
GL.ClearDepth(1d);
GL.DepthRange(1d, 0d); //does not seem right, but it works (see it as duct-tape)
Every draw cycle:
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
//reset depth and color to be consistent over multiple frames
DrawX.Depth = 0;
DrawX.DefaultColor = Color.Black;
foreach(View view in Resources.Views)
{
CurrentDrawArea = view.Area;
GL.Viewport((int)view.Viewport.Left * Window.Width, (int)view.Viewport.Top * Window.Height, (int)view.Viewport.Right * Window.Width, (int)view.Viewport.Bottom * Window.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(view.Area.Left, view.Area.Right, view.Area.Bottom, view.Area.Top, -1f, 1f);
GL.MatrixMode(MatrixMode.Modelview);
//drawing
foreach (LogicalObject obj in Resources.Objects)
{
//set view's coords for clipping?
obj.Draw();
}
}
GL.Flush();
Window.Context.SwapBuffers();
DrawX.Line:
public static void Line(PointF pos1, PointF pos2, Color color, float width = 1)
{
RectangleF lineRectangle = new RectangleF(pos1.X, pos1.Y, pos2.X - pos1.X, pos2.Y - pos1.Y);
if (lineRectangle.IntersectsWith(Game.CurrentDrawArea))
{
GL.LineWidth(width);
GL.Color3(color);
GL.Begin(PrimitiveType.Lines);
GL.Vertex3(pos1.X, pos1.Y, GLDepth);
GL.Vertex3(pos2.X, pos2.Y, GLDepth);
GL.End();
}
}
Edit: If I disable the blendcap before and enable it after drawing the line it does show up with the right color, but I must have it blended.
I forgot to unbind the texture in the texture-drawing method...
GL.BindTexture(TextureTarget.Texture2D, 0);