I want to fix OnGUI method inside in a script to a panel. Especially what I want to do is, In free aspect, when I change the size of game screen, also my text which is writen with onGUI changes depending on size of the game screen.
public HumanBodyVisualizer bodyVisualizer;
public GameObject text;
Vector2 scrollPosition = Vector2.zero;
float scrollPosition_y = 30;
private void OnGUI()
{
//Debug.Log(text.transform.position.y);
int subPartsSpacing = 0;
float spacing = 30;
float x = 7 + spacing;
float y = text.transform.position.y;
HumanBodyPart mainBodyPart = bodyVisualizer.BodyData.Body.SubParts[0];
List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
List<HumanBodyPart> allPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
scrollPosition = GUI.BeginScrollView(new Rect(7, 68, 236, 426), scrollPosition, new Rect(7, 68, 500, scrollPosition_y));
GUI.backgroundColor = Color.clear;
while (nextPartsToRender.Count > 0)
{
HumanBodyPart currentPart = nextPartsToRender[0];
nextPartsToRender.RemoveAt(0);
if(GUI.Button(new Rect(currentPart.DrawDepth * spacing + x + subPartsSpacing, y, 200, 20), currentPart.EnglishTitle))
{
HumanBodyVisualizer.ShowMode showModeFullBody = HumanBodyVisualizer.ShowMode.Invisible;
bodyVisualizer.ShowBody(showModeFullBody);
List<HumanBodyPart> AllSubPartsAndRoot = new List<HumanBodyPart>();
AllSubPartsAndRoot.Insert(0, currentPart);
allSubPartsOfClickButton(currentPart, AllSubPartsAndRoot, 1);
HumanBodyVisualizer.ShowMode showModeCurrentPart = HumanBodyVisualizer.ShowMode.LowTransparent;
//bodyVisualizer.ShowBodyPart(showModeCurrentPart, currentPart);
for (int i = 0; i < AllSubPartsAndRoot.Count; i++)
{
bodyVisualizer.ShowBodyPart(showModeCurrentPart,AllSubPartsAndRoot[i]);
}
/*
List<String> modelList = currentPart.ModelList;
for(int i = 0; i < modelList.Count; i++)
{
Debug.Log(modelList[i]);
}
*/
}
if (currentPart.SubParts.Count != 0)
{
if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing + subPartsSpacing, y, 20, 20), "+"))
{
if (!currentPart.IsExpanded)
{
currentPart.IsExpanded = true;
subPartsSpacing += 20;
}
else
currentPart.IsExpanded = false;
}
if (currentPart.IsExpanded)
{
nextPartsToRender.InsertRange(0, currentPart.SubParts);
allPartsToRender.InsertRange(allPartsToRender.Count - 1, currentPart.SubParts);
scrollPosition_y = allPartsToRender.Count * spacing ;
}
}
y += spacing;
}
// End the scroll view that we began above.
GUI.EndScrollView();
}
private void allSubPartsOfClickButton(HumanBodyPart root, List<HumanBodyPart> AllSubparts,int a)
{
AllSubparts.Insert(a, root);
a++;
for(int i = 0; i < root.SubParts.Count; i++)
{
allSubPartsOfClickButton(root.SubParts[i], AllSubparts, a);
}
}
When I run like that, even I change the size of game screen, OnGUI text(Buttons , labels and scrollview) stay constant on the screen.
I can not use Unity UI. I have to handle this problem with using onGUI.
Related
I set the points and when the points of the same color form a square, I draw a polygon. But when a new square is formed, the old one disappears.
can you tell me how to make sure that when drawing a new polygon, the old one does not disappear?
in the checkpoint() function, I check whether there is a square of points of the same color and return e coordinates for drawing.
public partial class Form1 : Form
{
private Class1 Class1 = new Class1();
private CellState currentPlayer = CellState.Red;
public const int SIZE = 11;
public const int Icon_Size = 30;
public Form1()
{
InitializeComponent();
}
//ставит точки
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
var p = new Point((int)Math.Round(1f * e.X / Icon_Size), (int)Math.Round(1f * e.Y / Icon_Size));
if (Class1[p] == CellState.Empty)
{
Class1.SetPoint(p, currentPlayer);
currentPlayer = Class1.Inverse(currentPlayer);
Invalidate();
}
}
//рисуем
private void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.ScaleTransform(Icon_Size, Icon_Size);
//рисуем сеточку
using (var pen = new Pen(Color.Gainsboro, 0.1f))
{
for (int x = 1; x < SIZE; x++)
e.Graphics.DrawLine(pen, x, 1, x, SIZE - 1);
for (int y = 1; y < SIZE; y++)
e.Graphics.DrawLine(pen, 1, y, SIZE - 1, y);
}
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//рисуем точки
using (var brush = new SolidBrush(Color.White))
for (int x = 1; x < Form1.SIZE; x++)
for (int y = 1; y < Form1.SIZE; y++)
{
var p = new Point(x, y);
var cell = Class1[p];
if (cell != CellState.Empty)
{
brush.Color = StateToColor(cell);
e.Graphics.FillEllipse(brush, x - 0.2f, y - 0.2f, 0.4f, 0.4f);
}
}
using (var PenP = new Pen(Color.Black, 0.1f))
using (var brush = new SolidBrush(Color.White))
{
Class1.CheckPoint();
int i = Class1.CheckPoint()[0];
int j = Class1.CheckPoint()[1];
int cp = Class1.CheckPoint()[2];
if (cp == 1)
{
PenP.Color = Color.Red;
brush.Color = Color.IndianRed;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
if (cp == 2)
{
PenP.Color = Color.Blue;
brush.Color = Color.RoyalBlue;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
}
}
//условие смены цвета под ход игрока
Color StateToColor(CellState state, byte alpha = 255)
{
var res = state == CellState.Blue ? Color.Blue : Color.Red;
return Color.FromArgb(alpha, res);
}
}
The thing that I want to do is that when I click the onGUI Button, Scroll view viewRect y axis increase at the same time. It means,I want to update the horizontal scroll view. However, my code is not working. How can I handle this?
private void OnGUI()
{
int subPartsSpacing = 0;
float spacing = 30;
float x = 7 + spacing;
float y = 68;
float scrollview_y = 236;
HumanBodyPart mainBodyPart = bodyVisualizer.BodyData.Body.SubParts[0];
List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
while (nextPartsToRender.Count > 0)
{
HumanBodyPart currentPart = nextPartsToRender[0];
nextPartsToRender.RemoveAt(0);
scrollPosition = GUI.BeginScrollView(new Rect(7, 68, 236, 426), scrollPosition, new Rect(7, 68, 500, scrollview_y));
GUI.Label(new Rect(currentPart.DrawDepth * spacing + x + subPartsSpacing, y, 200, 20), currentPart.EnglishTitle);
if (currentPart.SubParts.Count != 0)
{
if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing + subPartsSpacing, y, 20, 20), "+"))
{
if (!currentPart.IsExpanded)
{
currentPart.IsExpanded = true;
subPartsSpacing += 20;
}
else
currentPart.IsExpanded = false;
}
if (currentPart.IsExpanded)
{
//The wrong part I guess...
scrollview_y += 20 * currentPart.SubParts.Count;
//
nextPartsToRender.InsertRange(0, currentPart.SubParts);
}
}
y += spacing;
}
// End the scroll view that we began above.
GUI.EndScrollView();
}
GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced)
Shrinked to the esential you are doing
while (/*...*/)
{
// ...
scrollPosition = GUI.BeginScrollView(/*...*/);
// ...
}
GUI.EndScrollView();
so you get possibly multiple calls of BeginScrollView but only one call of EndScrollView after the loop.
So rather either move it into the while loop so it gets called for every BeginScrollView call
while (/*...*/)
{
// ...
scrollPosition = GUI.BeginScrollView(/*...*/);
// ...
GUI.EndScrollView();
}
or move both outside depending on your needs ofcourse
scrollPosition = GUI.BeginScrollView(/*...*/);
while (/*...*/)
{
// ...
}
GUI.EndScrollView();
I am following this tutorial: https://www.youtube.com/watch?v=LyV7cEQyZMk to generate a planet for my game. I have gotten up to 6:08
For some reason, the color of the planet won't change depending on the type like it should, it is only white.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Type
{
Water, Ice, Volcano, Snow, Grass, Forest, Desert, Rocky
}
[CreateAssetMenu()]
public class PlanetSettings : ScriptableObject
{
public float Size;
public Type type;
}
public class TerrainFace
{
Mesh mesh;
int resolution;
Vector3 localUp;
Vector3 axisA;
Vector3 axisB;
Vector3[] vertices;
int[] triangles;
PlanetSettings settings;
Vector3 CalculatePointOnPlanet(Vector3 p)
{
return p * settings.Size;
}
public TerrainFace(Mesh mesh, int resolution, Vector3 localUp, PlanetSettings settings)
{
this.mesh = mesh;
this.resolution = resolution;
this.localUp = localUp;
this.settings = settings;
axisA = new Vector3(localUp.y, localUp.z, localUp.x);
axisB = Vector3.Cross(localUp, axisA);
}
public void ConstructMesh()
{
vertices = new Vector3[resolution * resolution];
triangles = new int[(resolution - 1) * (resolution - 1) * 6];
int triIndex = 0;
for (int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
int index = x + y * resolution;
Vector2 percent = new Vector2(x, y) / (resolution - 1);
Vector3 pointOnUnitCube = localUp + (percent.x - 0.5f) * 2 * axisA + (percent.y - 0.5f) * 2 * axisB;
Vector3 pointOnUnitSphere = pointOnUnitCube.normalized;
vertices[index] = CalculatePointOnPlanet(pointOnUnitSphere);
if (x != resolution - 1 && y != resolution - 1)
{
triangles[triIndex] = index;
triangles[triIndex + 1] = index + resolution + 1;
triangles[triIndex + 2] = index + resolution;
triangles[triIndex + 3] = index;
triangles[triIndex + 4] = index + 1;
triangles[triIndex + 5] = index + resolution + 1;
triIndex += 6;
}
}
}
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
public class PlanetGenerator : MonoBehaviour
{
[Range(2, 256)]
public int Resolution = 10;
public PlanetSettings Settings;
[SerializeField, HideInInspector]
MeshFilter[] meshFilters;
TerrainFace[] terrainFaces;
Color c;
private void OnValidate()
{
GeneratePlanet();
}
void Initialize()
{
switch (Settings.type)
{
case Type.Desert:
c = new Color(244, 176, 66, 255);
break;
case Type.Forest:
c = new Color(9, 119, 22, 255);
break;
case Type.Grass:
c = new Color(21, 193, 41, 255);
break;
case Type.Ice:
c = new Color(105, 206, 239, 255);
break;
case Type.Rocky:
c = new Color(104, 65, 6, 255);
break;
case Type.Snow:
c = new Color(204, 226, 229, 255);
break;
case Type.Volcano:
c = new Color(160, 16, 16, 255);
break;
case Type.Water:
c = new Color(26, 69, 178, 255);
break;
default:
c = new Color();
break;
}
if (meshFilters == null || meshFilters.Length == 0)
meshFilters = new MeshFilter[6];
terrainFaces = new TerrainFace[6];
Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back };
for (int i = 0; i < 6; i++)
{
if (meshFilters[i] == null)
{
GameObject meshObj = new GameObject("mesh");
meshObj.transform.parent = transform;
meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
meshFilters[i] = meshObj.AddComponent<MeshFilter>();
meshFilters[i].sharedMesh = new Mesh();
}
terrainFaces[i] = new TerrainFace(meshFilters[i].sharedMesh, Resolution, directions[i], Settings);
}
}
public void GeneratePlanet()
{
Initialize();
GenerateMesh();
GenerateColor();
}
void GenerateMesh()
{
foreach (TerrainFace face in terrainFaces)
{
face.ConstructMesh();
}
}
void GenerateColor()
{
foreach (MeshFilter m in meshFilters)
{
m.GetComponent<MeshRenderer>().sharedMaterial.color = c;
}
}
}
The size part works, it's just the color that doesn't. I should see a dark red colored sphere. I have been trying different things to identify the problem, I think i have narrowed it down to sharedmaterial.color but I don't know for sure.
Well you don't have the code he talks about at around the 5 min mark where he changed the TerrainFace object and it's constructor.
I want to print 50 labels per sheet (5 columns and 10 rows). When it goes to the 11th row it should switch to the next page. I have tried e.hasMorePages in several ways, but sometimes it gets overlapped on the same page.
Here is my code:
private void MakingLabel(int curentIndex,List<BarcodesSpecs> List)
{
int ListRows = List.Count;
BarcodesSpecs barcodesSpecs = List.ElementAt(curentIndex);
BarCode_ItemCode = barcodesSpecs.ItemCodeMain;
BarCode_Description = barcodesSpecs.Description;
BarCode_SalePrice = barcodesSpecs.SalePrice;
BarCode_Size = barcodesSpecs.Size;
BarCode_Colour = barcodesSpecs.Colour;
barCode_LabelToPrint = Convert.ToInt16(barcodesSpecs.QtyToPrint);
}
int xCord = 0, yCord = 0;
int CurentIndex = 0;
int MaxCharactersInString = 26;
private void printBarcodes_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
for (CurentIndex = 0; CurentIndex < BcList.Count; CurentIndex++)
{
MakingLabel(CurentIndex, BcList);
for (int i = 0; i < barCode_LabelToPrint; i++) //// making Copies means How many Labels Of this Item Needed
{
if (xCord >= 750)
{
xCord = 0;
yCord += 115;
}
if (BarCode_Description.Length > MaxCharactersInString)
{
BarCode_Description = BarCode_Description.Substring(0, MaxCharactersInString);
}
e.Graphics.DrawString("ALPIAL SUITING", new Font("Arial", 10, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 10));
e.Graphics.DrawString("Rs" + BarCode_SalePrice + "/-", new Font("Arial", 14, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 21));
e.Graphics.DrawString("Size: " + BarCode_Size + " Colour: " + BarCode_Colour, new Font("Arial", 07, FontStyle.Regular), Brushes.Black, new Point(xCord, yCord + 42));
e.Graphics.DrawString(BarCode_Description, new Font("Arial", 07, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 52));
e.Graphics.DrawString(BarCode_ItemCode, new Font("Arial", 06, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 62));
Zen.Barcode.Code128BarcodeDraw barcode = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
e.Graphics.DrawImage(barcode.Draw(BarCode_ItemCode, 25), xCord, yCord + 72);
xCord += 160;
}
}
}
The result I am getting is in the picture, any help will be appreciated thanks!
Somewhere along the line, you will need to check if yCord is beyond the bottom of the page. If it is, you need to set HasMorePages to true and exit the PrintPage handler. It will be called again for the next page. You'll have to keep track of which labels you have already printed outside the PrintPage handler and continue from that point.
Here's a sample I did to simulate labels printing. I only drew a square to represent the label. I had to do a little math to figure out the spacing so you will likely have to adjust this for your situation.
private static void doPrintPreview()
{
var pd = new PrintDocument();
pd.PrintPage += pd_PrintPage;
var prv = new PrintPreviewDialog();
prv.Document = pd;
prv.ShowDialog();
}
//Units are in 1/100 of an inch
private static float leftMargin = 100f; //Page margins
private static float rightMargin = 750f;
private static float topMargin = 100f;
private static float bottomMargin = 1000f;
private static int numLabelsToPrint = 200; //How many we want to print
private static int numLabelsPrinted = 0; //How many we have already printed
private static float labelSizeX = 75; //Label size
private static float labelSizeY = 75f;
private static float labelGutterX = 7.14f; //Space between labels
private static float labelGutterY = 7.5f;
static void pd_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.PageUnit = GraphicsUnit.Display; //Units are 1/100 of an inch
//start at the left and top margin of the page for a new page
float xPos = leftMargin;
float yPos = topMargin;
using (var p2 = new Pen(Brushes.Red, 3.0f))
{
//While there are still labels to print
while (numLabelsPrinted < numLabelsToPrint)
{
//Draw the label (i just drew a square)
e.Graphics.DrawRectangle(Pens.Red, xPos, yPos, labelSizeX, labelSizeY);
numLabelsPrinted++;
//Set the x position for the next label
xPos += (labelSizeX + labelGutterX);
//If the label will be printed beyond the right margin
if ((xPos + labelSizeX) > rightMargin)
{
//Reset the x position back to the left margin
xPos = leftMargin;
//Set the y position for the next row of labels
yPos += (labelSizeY + labelGutterY);
//If the label will be printed beyond the bottom margin
if ((yPos + labelSizeY) > bottomMargin)
{
//Reset the y position back to the top margin
yPos = topMargin;
//If we still have labels to print
if (numLabelsPrinted < numLabelsToPrint)
{
//Tell the print engine we have more labels and then exit.
e.HasMorePages = true;
//Notice after setting HasMorePages to true, we need to exit from the method.
//The print engine will call the PrintPage method again so we can continue
//printing on the next page.
break; //you could also just use return here
}
}
}
}
}
}
I want create a control that draws a table in panel . My code is:
public class PanelZ : System.Windows.Forms.Panel
{
public static void Draw()
{
Panel p = new Panel();
p.Width = 200;
p.Height = 200;
Graphics g = p.CreateGraphics();
Pen mypen = new Pen(Brushes.Black, 1);
Font myfont = new Font("tahoma", 10);
int lines = 9;
float x = 0;
float y = 0;
float xSpace = p.Width / lines;
float yspace = p.Height / lines;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, x, p.Height);
x += xSpace;
}
x = 0f;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, p.Width, y);
y += yspace;
}
}
..but it dosen't draw a table; so what should I do?
This will work. But the numbers ought to be properties, as should the pen and then some.. Also: Properties ought to start with an uppercase letter.
public class PanelZ : System.Windows.Forms.Panel
{
public PanelZ() // a constructor
{
Width = 200;
Height = 200;
DoubleBuffered = true;
lines = 9;
}
public int lines { get; set; } // a property
protected override void OnPaint(PaintEventArgs e) // the paint event
{
base.OnPaint(e);
Graphics g = e.Graphics;
Pen mypen = new Pen(Brushes.Black, 1);
Font myfont = new Font("tahoma", 10);
float x = 0;
float y = 0;
float xSpace = Width / lines;
float yspace = Height / lines;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, x, Height);
x += xSpace;
}
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, 0, y, Width, y);
y += yspace;
}
}
}
At work in VS:
Note that this only colors pixels. There is no useful grid there, just pixels with color.. So, if you actually want to use the Font you define you will have to calculate the coodordinates and the bounding boxes.