I'm trying to design a UI in FXML and by partly using Scene Builder. I use an Anchorpane to place all the content in the scene. However, when I resize the window to a greater size, the buttons move from the center to the left. I want to make sure they stay in the center of the page. How to do this?
Thanks.
The easy way is to make use of StackPane or BorderPane. In case of BorderPane, you can keep the button or container containing the button at center position using Pos.CENTER.
If AnchorPane is really needed, you can make use of width and height property change listeners to adjust button position during resizing.
private AnchorPane anchorPane;
private Button button;
anchorPane.widthProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
button.setLayoutX(newValue.doubleValue()/2 - (button.widthProperty().getValue() / 2));
});
anchorPane.heightProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
button.setLayoutY(newValue.doubleValue()/2 - (button.heightProperty().getValue() / 2));
});
Related
I’m really just a beginner & I have no idea how to use the animation in Unity properly. I’m working on a 2D platformer game. I managed to make the animation work, but the point is that my character should looks different from each side (so I can’t just flip the sprite). What’s the simplest way to for example, when pressing right he will use animation 1 and when pressing left he will use animation 2? Thanks in advance & sorry about my stupidity;)
Did you try using Animator Controller.
[RequireComponent(typeof(Animator))]
public class PlayerAnimation: MonoBehaviour
{
[SerializeField]private Animator _animator;
private const string DirectionParam = "Direction";
private void Update()
{
//On Right button clicked
if (Input.GetKeyDown(KeyCode.RightArrow))
{
//Play Right animation
_animator.SetInteger(DirectionParam, 1);
}else if (Input.GetKeyDown(KeyCode.RightArrow))
{
_animator.SetInteger(DirectionParam, -1);
}
else
{
_animator.SetInteger(DirectionParam, 0);
}
}
}
Drag this script on you player. This will also Add unity Animator Component on your game object.
Create Animator Object and place it on the animator component.
open Animator Editor from Window>Animation>Animator
Then create an int parameter in Animation Controller Window and name it "Direction".
Create two animation clips one for left move animation and another for right move animation
Drag these clips to the animator Window. Right click and create two transition and add condition with Direction parameter. You should create 3 animation clips and set that to idle and transition to idle when the direction value is 0.
Enjoy!
How would I aim rotate a Unity UI Element's RectTransform so that the Element points at another UI Element on a World Space Canvas?
In the image below there's a Slider (But it could be any UI Element) that I would like to rotate so that it always faces the Button as I drag the Button around the Canvas.
Example
Thanks for any help you can provide.
Place a script on the element you want to rotate that contains something like this:
//References for the pivot position of the UI elements
public RectTransform targetAnchor;
RectTransform selfAnchor;
//Set the rotating elements RectTransform
void Start() {
selfAnchor = GetComponent<RectTransform>();
}
//Update the UI elements rotation
void Update() {
float targetRotation = Mathf.Atan((targetAnchor.y - selfAnchor.y)/(targetAnchor.x - selfAnchor.x));
selfAnchor.rotation = Quaternion.Euler(0,0, targetRotation);
}
I can't test this at the moment but if you're still having issues I can update it when I get home.
I have a 3d-object (cube), which I want to use as a button. I've written the code in order to detect, if the cube was pressed but it doesn't look like it was pressed, since it lacks the "clicking animation". How can I create a clicking animation on my 3d-object ?
A good idea is to play an aninimation which skrinks the cube a bit and releases it immediately afterwards. The handler code you want to execute on a click might block the game loop, e.g. when you load a level. Then it might be useful to load the level aysnchronously to be able to see the animation. Or you execute the handler code after the animation. Or you play the scale down animation on the press event and the scale up animation on the release event.
Technically you can use the build in animation editor, the Update() method, start a coroutine or use the assets iTween or HOTween.
http://docs.unity3d.com/ScriptReference/Transform-localScale.html
Let me know if you like the idea or questions arise.
Unity makes it easier now to do this using Unity Canvas UI. Instead of real 3d buttons, you could place a canvas UI in world space at the location where you want the buttons. Add a UI Panel to the canvas then add a UI Button.
Now, you have out of the box several clicking effects. The default it color tint, but you can choose sprite swap, or animation.
If you do want animation, when you select button animation it will create an animator for you. Click on your UI button Game Object in the scene hierarchy and open the animation window. You can choose Pressed animation from the drop down, and press RECORD button, then edit your buttons scale, say make it 0.75 for x,y,z. Now when you click on the button it will animate a cool scale down for you.
Sorry, I know that is a lot of information dumped! But you will find it pretty great once you start working with it in world space.
You can scale it down a tiny bit once click happen. For example:
void OnMouseDown() {
this.transform.localScale += new Vector3(0.05f, 0.05f, 0.05f);
}
Then after click scale it back to the original size.
Perhaps look into iTween (free on Unity Asset store).
Its very easy to use and you can produce some nice looking animations.
you can scale it when pressed or just change the color a little bit. On mouse up, rescale or recolor it.
void OnMouseDown()
{
transform.localScale -= new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color += new Color(40,40,40);
}
void OnMouseUp()
{
transform.localScale += new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color -= new Color(40,40,40);
}
You can implement your button using new Event system of unity. Here are the functions you can implement :
public class ExampleClass : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
//it is the function when you hover your mouse to the object
//You can change the color of your object to make your users
//understand that it is not just a cube but also a clickable item
}
public void OnPointerExit(PointerEventData eventData)
{
//You can revert your color back to its original
}
public void OnPointerDown (PointerEventData eventData)
{
//You can play with local scale as suggested by other answers here
}
public void OnPointerUp (PointerEventData eventData)
{
// Revert back the changes you made at onPointerDown
}
public void OnPointerClick (PointerEventData eventData)
{
//Use here for operations when your button is clicked
}
}
I have the following class which adds an image to a button and then adds the button to a panel
private PushButton button;
private AbsolutePanel panel = new AbsolutePanel();
private Image image = new Image("images/rectangle_blue.png");
public ExpandingRectangularButton(String text)
{
String width = "120px";
String height = "160px";
image.setWidth(width);
image.setHeight(height);
button = new PushButton(image);
panel.add(button, 0, 0);
panel.setWidth(width);
panel.setHeight(height);
initWidget( panel );
}
When I display an instance of ExpandingRectangularButton the button is truncated on the bottom. However if I take the panel out of the equation as follows
private PushButton button;
private Image image = new Image("images/rectangle_blue.png");
public ExpandingRectangularButton(String text)
{
String width = "120px";
String height = "160px";
image.setWidth(width);
image.setHeight(height);
button = new PushButton(image);
initWidget( button );
}
and just use the image and the button ( ie I call init() on the button ) then the image will display with no truncation. As I don't set the height of the button I assume it grows dynamically to accomodate it's child widget. Why does this not happen when I put the button onto the panel?
Quoting the Javadoc:
An absolute panel positions all of its children absolutely, allowing them to overlap.
Note that this panel will not automatically resize itself to allow enough room for its absolutely-positioned children. It must be explicitly sized in order to make room for them.
You can:
explicitly set the AbsolutePanel size;
remove the overflow: hidden property from it (workaround);
use panel.add(button, -1, -1) to position the button statically;
change the AbsolutePanel with one that naturally adapt its size (like almost any other Panel).
I'd prefer the last, but your use case is not clear.
I have two canvas's in a Grid, full scene "images" that I want to transition, I wonder how I would go about transitioning between these two Canvas controls.
Programatically I add the first canvas to the grid, then I add the second canvas to the grid, and remove the first, what I really want to do is transition between them.
Any suggestions on how I might achieve this programatically?
Thanks.
Edit: I have implemented this method, but am having problems, anyone able to tell me if I'm using it wrong?
private void doTransitionIn(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeIn;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
private void doTransitionOut(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeOut;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
And here is how I use it:
SceneGrid.Children.Add(nextCanvas);
doTransitionIn(nextCanvas);
doTransitionOut(currentCanvas);
SceneGrid.Children.Remove(currentCanvas);
The problem with this is that the animation only seems to start from part way down the screen, as in, i only see it slide the last 20 or so pixels, it doesn't slide all the way.
Depending on what you mean by "transition" I'd look at creating a StoryBoard to animate the hiding/showing of each canvas.
I would recommend using the TransitioningContentControl which is part of the Silverlight Toolkit. To use this control, make your first Canvas the Content of this control. To transition, simply change the Content to your next Canvas and the TransitioningContentControl does the rest!
There are a number of blog posts that provide tutorials for this control:
http://blogs.academicclub.org/uidev/2010/06/12/transitioning-content-in-silverlight/