Sounds like a silly problem, but whenever I drag an oval to the table, an error pops out: "Cannot create component of type 'Shape' in container of type 'TableLayoutPanel'. Is there a way I can work around this?
The Shape classes require a container, an instance of the ShapeContainer class, pretty invisible when you use the designer to drop shapes on a form. Technically you can find it back from the control selector combobox at the top of the Properties window, the default name is "shapeContainer1" and has no properties at all. The surface of this container class is used to draw the shapes.
All of this is done completely automatically with a custom designer, it ensures that the ShapeContainer instance is created when you drag a shape from the toolbox onto the form. Problem is, this designer isn't quite smart enough to deal with the TableLayoutPanel class. What it should do is create a ShapeContainer that can be embedded in a cell of the TLP, it doesn't. Instead it just gives up and displays the message box. Or to put it another way, you are seeing the Microsoft programmer having given up on making this work. It is not very simple to do correctly, pretty hard to get rid of those otherwise invisible containers again.
Only workaround you have is to write the code yourself. You do so in the constructor of the form. A simple example that puts a LineShape in the upper/left table cell:
public Form1() {
InitializeComponent();
var line = new Microsoft.VisualBasic.PowerPacks.LineShape() {
X1 = 0, Y1 = 0, X2 = 50, Y2 = 20
};
var container = new Microsoft.VisualBasic.PowerPacks.ShapeContainer();
container.Shapes.Add(line);
container.Size = new System.Drawing.Size(50, 20);
tableLayoutPanel1.Controls.Add(container, 0, 0);
}
I know this is an old thread... but for the sake of someone who might be looking into an easier option in the future this is the solution I found:
Insert a Panel inside of your TablePanelLayout where you want to place a shape and VisualStudio should allow you to place the shape inside the newly created panel.
Good luck.
Related
Anyone who knows how to add User Inteface on top of Rajawali Surface View?
I check the rajawali documentation but it doesn't work
The following approach worked for me: Create your UI elements that you want to add to your layout, I used a ConstraintLayout as a container. Do not create the SurfaceView by xml, but instead programmatically. Create it in a way that it will overlap all other UI elements and that it uses all available space. By this, the UI elements are still visible even though technically they should be hidden by the SurfaceView which is in front.
Below is my code how I setup the SurfaceView. Note that constraintLayout is the name of the container layout that has other buttons in it as well.
surfaceView = new SurfaceView(getContext());
surfaceView.setFrameRate(30.0);
surfaceView.setRenderMode(ISurface.RENDERMODE_WHEN_DIRTY);
surfaceView.setSurfaceRenderer(YOUR_RENDERER);
surfaceView.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, ConstraintLayout.LayoutParams.MATCH_CONSTRAINT));
surfaceView.setId(View.generateViewId());
constraintLayout.addView(surfaceView, 0);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(surfaceView.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT);
constraintSet.connect(surfaceView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT);
constraintSet.connect(surfaceView.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
constraintSet.connect(surfaceView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
constraintSet.applyTo(constraintLayout);
I have been working on figuring out what is going on with my game's UI for at least two days now, and no progress.
Note that this is a mobile game, but I was asked to build for Windows for visualization and presentation purpose.
So the problem is that when I run my game on the Unity Editor, Android, iOS and Mac platforms the UI works just perfect, but then when I run the game on Windows the UI still works fine UNTIL I load a specific scene.
This specific scene is a loading screen (between main menu and a level) when the level finished async loading, a method called MoveObjects is called in a script in the loading screen, to move some objects that where spawned in the loading screen scene into the level scene (this is not the issue though, since I already try without this method and the problem on the UI persist).
Once the logic of this MoveObjects method is done, a start button is enabled in the loading screen, for the player to click and start playing (I did try moving the start button to the level scene, since maybe it not been a child of the currently active scene could be the issue, but the problem still persist). Is at this point that the UI is partially broken, what I mean with this is, that I can see buttons (and some other UI elements like a scrollbar) changing color/state when the mouse moves over them, but I cannot click on them anymore (the button wont even change to the pressed state).
Also note that I tried creating a development build to see if there was any errors in the console, and I notice that this problem is also affecting the old UI system, so I was not able to interact with the development console anymore.
Also also, note that if I grab and drag the scrollbar before this issue appear, and I keep holding down on the scrollbar until this happens, the mouse gets stuck on the scrollbar, meaning that I cannot interact with the UI anymore, but the scrollbar will still move with the mouse.
I already check that this things are not the source of the problem:
Missing EventSystem, GraphicRaycaster or InputModule.
Another UI element blocking the rest of the UI.
Canvas is Screen Space - Overlay so there is no need for a camera reference.
I only have one EventSystem.
Time.timeScale is 1.
I am not sure what else I could try, so if anyone has any suggestions, I would appreciate it. Thanks.
P.S: I am sorry to say that I cannot share any code or visual material or examples due to the confidentiality.
A major source for a non-working UI for me has always been another (invisible) UI object blocking the raycast (a transparent Image, or a large Text object with raycast on).
Here's a snippet I put together based on info found elsewhere, I often use it to track objects that are masking the raycast in complex UI situations. Place the component on a text object, make sure it's at least few lines tall, as the results will be displayed one under another.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(Text))]
public class DebugShowUnderCursor : MonoBehaviour
{
Text text;
EventSystem eventSystem;
List<RaycastResult> list;
void Start()
{
eventSystem = EventSystem.current;
text = GetComponent<Text>();
text.raycastTarget=false;
}
public List<RaycastResult> RaycastMouse(){
PointerEventData pointerData = new PointerEventData (EventSystem.current) { pointerId = -1, };
pointerData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results);
return results;
}
void Update()
{
list= RaycastMouse();
string objects="";
foreach ( RaycastResult result in list)
objects+=result.gameObject.name+"\n";
text.text = objects;
}
}
I'm trying to make an augmented reality application with vuforia and unity.
whenever it recognize the image target, it must tell a story by showing text , and it should enable the user to press next and back to go on reading the different parts of this story, I'm totally new to unity and don't know how to handle with UI throughout scripting, I need some help on how to accomplish the part of "going forward and backward on showing the story by hitting Next and Back buttons", and all these parts of story should be related to the same image target in the same scene.
I appreciate it if you help me with an example code.
You should create some script that attach on trackable object, maybe something like this.
public class DataBook {
string[] dataBook;
string idText;
bool isActive;
}
Then you must create another script to set that trackable object is active or not, this link can help you to get that.
https://developer.vuforia.com/forum/faq/unity-how-do-i-get-list-active-trackables
Then after you get the active trackable object, you can set the dialog from the book by create another controller script for button, example
public void Next() {
DataBook[] books = FindObjectsOfType<DataBook>(); // if the object more than one, it will be more easy if it only the one
foreach (var book in books)
{
if (book.isActive) {
book.idText += 1;
textUI.text = book.dataBook[idText]; //textUI assign to object text on canvas
}
}
}
you can learn about unity UI Button on this :
https://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button
Good luck
I have the following problem, and I'd appreciate greatly if someone could help.
I've been trying create a roll-a-ball game in Unity, similar as the one presented in one of the tutorials on their official website, but with one difference: I'd like to add GUI text that would show the score. Every time the ball hits (and destroys) one of the rotating cubes, the score should increase by 1, and the text should show the current score.
I've watched the following tutorial:
http://unity3d.com/learn/tutorials/projects/space-shooter/counting-points
I have created the UI text, called ScoreText, and, on the other hand, I have written the script that makes an instance of GUIText class, called guitext, show the current score. However, I cannot connect my particular GUI text (ScoreText) with the script, i.e. I cannot tell the script to use that particular GUI text to show score. In the video, at 16:35, they just drag the GUI text to the instance of the GUIText class from the script (in my case, guitext), in order to tell the script it's that particular text that should show the score. But when I try to drag it, I simply can't do it. I have no idea why.
I don't know if this could cause the problem: under "Create" in the free version of Unity, I could not find anything called "GUI text" but instead I created a UI text. I know it's the same thing, but... In the script, I define an instance of GUIText class - guitext - so maybe, when I try to add my UI text to it, it won't work because my text really doesn't belong to the GUIText class?
Since you are using Unity 4.6 which has a new GUI system and not the Legacy UI which was present when the tutorial which you mentioned was made. There are two options - either you create an empty gameobject and add add a GUIText component to it. You can add the GUIText to empty gameobject by selecting it in the Hierarchy which should display the objects properties in the Inspector panel.
In the Inspector, you should see an Add Component button, click on it and search for GUIText. Add it and that should solve your problem.
Oh yea, the second option is to migrate to Unity 4.6 new GUI, which should take time unless you are pretty good with unity.
If you want to learn Unity 4.6 GUI, you can refer these links
Unity Official
Unity 4.6 tutorials by TheGameContriver
I am only posting on this because many come to this one and get lost. Here is how to make this work in Unity5.3 at the time of this response.
This is in C#
Simply use the GameController game object to attach the script to. Second create a UI text. Toy only call it score or scoretext for your own referral otherwise the name itself does not matter.
using UnityEngine;
using UnityEngine.UI;///needed to reference the new UI setup in this script type
using System.Collections;/// <summary>
/// allows collections of related information.
/// </summary>
public class GameController : MonoBehaviour {
public GameObject targets;
public Vector3 spawnValues;
public int hazardCount;
public float spawnWait;
public float startWait;
public float waveWait;
public Text Text; /// <summary>
/// change this because you dont actually use the words UI or GUI. Thats just for the reference and not clarified by instructors.
/// </summary>
private int score;
void Start()
{
score = 0;
UpdateScore();
StartCoroutine(SpawnWaves());
}
IEnumerator SpawnWaves()///this depends on the above using System.Collections
{
yield return new WaitForSeconds(startWait);
while (true)
{
for (int i = 0; i < hazardCount; i++)
{
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(targets, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnWait);
}
yield return new WaitForSeconds(waveWait);
}
}
public void AddScore(int newScoreValue)
{
score += newScoreValue;
UpdateScore();
}
void UpdateScore()
{
Text.text = "Score: " + score;
}
}
Confirmed. In the GameController.cs file, change the declaration of public GUIText scoreText to public Text scoreText, and then it will let you drag it on the Game Controller as the video shows.
Update your Unity tutorials, peoples! Just spent an hour trying to figure this out!
One more thing...check the Z position. My UI looked perfect head on in the scene view, but my text never showed in the game...then I rotated the scene view and found my text was way behind the camera. Seems when you add something to the UI, the z value is somewhat random.
I have a flash game where I have a picture designed to be the textbox for a prompt and textbox inside with the relevant text but the textbox is being hidden by the image. Anyone know how to make is so that the textbox is guaranteed to be on top or whatever I need to do to keep this from happening?
The other answer using setChildIndex will definitely work, however, I think a different design approach is really what you should be doing to remove the headache altogether.
For example in a game I might have different layers such as :
backgroundLayer
gameLayer
interfaceLayer
Those 3 Sprite layers would get added to the stage in that order. I would then add display objects to the appropriate layers. So anything I added to the backgroundLayer or gameLayer would ALWAYS be 'behind' my user interface on the interfaceLayer.
That allows you to not have to worry about the layering constantly. The answer with setChildIndex will fix the problem for that moment, but should something else be added to the container it will overlap your textbox, which is something I don't assume you want.
here's an example :
var backgroundLayer:Sprite = new Sprite;
var gameLayer:Sprite = new Sprite;
var interfaceLayer:Sprite = new Sprite;
addChild(backgroundLayer);
addChild(gameLayer);
addChild(interfaceLayer);
now, whatever you add to interfaceLayer, will ALWAYS be on top of objects you add to gameLayer or backgroundLayer.
So in the case of your text box, just add it to your interfaceLayer and any other objects you want behind it, you add to the gameLayer or backgroundLayer.
The order of adding display objects to display object containers effect their z-order, in other words the front to back order. The last added display object becomes the frontmost. So the child index of the children of a display object container is important for drawing of overlapped children.
If you put picture and text on the same DisplayObjectContainer such as a MovieClip:
Lets say your DisplayObjectContainer is mc.
And your textbox is txt
Please try this:
mc.setChildIndex(txt, mc.numChildren-1);