How to make a menu with this effect in unity3d? - scroll

Sorry, I'll try to explain better.
I want to make a sliding menu where you can select a character. I want the character that is at the center increases in size to know that this is the current character. The effect can be seen in the game of Crossy Road when you want to select a character.
Sorry but I can't upload a imagen because i am new in the forum

I think I might be able to help you without needing too much borrowed code. There are two possibilities here:
You have a perspective camera so the "selected" item can just be closer to the camera.
You have an orthographic camera so you will have to scale things.
For perspective:
List<GameObject> characters; //contains all character.
int selectedIndex = 0; //index to the selected character.
float spacing = 10; //space between chars
void Update()
{
if(Input.GetKeyDown("RightArrow"))
{
selectIndex++;
ApplyChanges();
}
if(Input.GetKeyDown("LeftArrow"))
{
selectIndex--;
ApplyChanges();
}
}
void ApllyChanges()
{
// Make sure the selected index is within range and then space the characters.
selectedIndex = selectedIndex % character.Count();
SpaceCharacters();
}
void SpaceCharacters()
{
for(int i = 0; i < characters.Count(); ++i)
{
// characters on the left will have a negative spacing and so will be placed to the left and vice versa for characters on the right.
int offset = i - selectedIndex;
characters[i].transform.position = new Vector3(offset * spacing, 0, 0);
}
// Move the selected character closer.
characters[selectedIndex].transform.position = new Vector3(0,0,spacing);
}
For orthographic camera you will need to set the select characters transform.scale to a larger vector.
This won't animate anything or look cool. This code will just snap your characters into position.

The solution I adopted was to attach objects to the transparent buttons in a scrool rect, so as to manage 3d objects with the convenient of scrool rect interface.
Here you can find the official documentation for use scrool rect: http://docs.unity3d.com/Manual/script-ScrollRect.html
Maybe my assets can serve you ;)
https://www.assetstore.unity3d.com/en/#!/content/60233

Related

How to animate component repositioning on recomposition in Jetpack Compose?

I have two squares. The green one is constrained to the top, and the blue one is constrained between the green one and the bottom of the screen. When clicking on the blue square, the green square doubles in size. Since the size of the green square increases, the blue square moves downwards because of its constraints.
How do I animate the position change of the blue square? Do I have to manually calculate and animate the offset? This feels very hacky. I feel like this should be doable declaratively, since the new position is automatically calculated by the updated constraints.
Edit: Basically, I'm looking for android:animateLayoutChanges, but for Compose.
Here is my code:
#Composable
fun AnimationTest() {
ConstraintLayout(
modifier = Modifier.fillMaxSize()
) {
val (block1, block2) = createRefs()
var blockSize by remember { mutableStateOf(20.dp) }
Surface(
color = Color.Green,
modifier = Modifier
.size(blockSize)
.constrainAs(block1) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
) {}
Surface(
color = Color.Blue,
modifier = Modifier
.size(50.dp)
.constrainAs(block2) {
top.linkTo(block1.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
}
.clickable {
blockSize *= 2
}
) {}
}
}
Try wrapping it inside the AnimatedContent composable. Though it is ConstraintLayout so I don't think it would work, but it just might. Give it a try and let me know. Otherwise, it is a very simple scenario, and can be easily achieved with the Layout composable, inside which you can use lerp() to achieve the animation

Unity3D: How do I improve my Idle animation (Y-axis)

Okay, I am almost finished with my 2d rpg click to move game. If you look at this video you will be able to see that when I click forward my player, once it gets to it's position, face the wrong direction rather than facing straight towards the players. To make myself more clearer, this is an image of the sprite sheet I am currently using, as you can see it has 8 directions. When you click here (in the game), my player would walk down and face this direction or this direction, rather than facing this direction (the normal/preferred position). This also happens when I click here (in the game) my player would walk up and face this direction or face this direction, rather than facing this direction. How can I make sure that my player face the right direction once it reached it's destination. Again this is only occurring within the Y-axis, so walking along the X-axis is fine.
private Animator anim;
public float speed = 15f;
private Vector3 target;
private bool touched;
private bool playerMovementRef;
void Start () {
target = transform.position;
anim = GetComponent<Animator> ();
}
void Update () {
if (Input.GetMouseButtonDown (0)) {
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = 10; // distance from the camera
target = Camera.main.ScreenToWorldPoint (mousePosition);
target.z = transform.position.z;
var movementDirection = (target - transform.position).normalized;
Vector3 animDirection = Vector3.zero;
if (movementDirection.sqrMagnitude > 0)
{
// Use >= to default to horizontal on both being equal
if (movementDirection.x > movementDirection.y)
animDirection.x = 1;
else
animDirection.y = 1;
anim.SetBool ("walking", true);
anim.SetFloat ("SpeedX", movementDirection.x);
anim.SetFloat ("SpeedY", movementDirection.y);
if (movementDirection.x < 0) {
anim.SetFloat ("LastMoveX", -1f);
} else if (movementDirection.x > 0) {
anim.SetFloat ("LastMoveX", 1f);
} else {
anim.SetFloat ("LastMoveX", 0f);
}
if (movementDirection.y > 0) {
anim.SetFloat ("LastMoveY", 1f);
} else if (movementDirection.y < 0) {
anim.SetFloat ("LastMoveY", -1f);
} else {
anim.SetFloat ("LastMoveY", 0f);
}
}
} else {
if (Mathf.Approximately (transform.position.x, target.x) && Mathf.Approximately (transform.position.y, target.y)) {
touched = false;
anim.SetBool ("walking", false);
} else {
transform.position = Vector3.MoveTowards (transform.position, target, speed * Time.deltaTime);
}
}
}
}
I'm just starting out with Unity, but hope I can help.
From the video you've posted I've noticed that the sprite is only 'wrong' when the oldPosition and newPosition click differs in the X component, e.g. when you would click straight down it would show the desired behavior and sprite.
Have you tried printing out the x and y values that your code is using to calculate which sprite it's setting?
At first I thought that maybe it's because the values you set in the Blend Tree were at -1, 1 etc, and due to normalizing you sometimes wound up with 0.9 for a certain value.
Can you maybe try debugging it with the animator window open, like you did at the end? Writing down the values and comparing them between Desired and Undesired behavior might tell you something more.
Sorry I don't have a concrete solution to your problem, but I hope this helps.
Edit for clarification:
Basically, what I'm recommending is to:
1) Print out the values you are getting when the behavior happens, an example of how to print these things out is by using LogFormat, for example:
Debug.LogFormat("X: {0}, Y: {1}", xPosition, yPosition);
Now, you will get the values printed out when it finishes moving.
2) Write down the values for when the moving finishes with the 'Wrong' sprite, and keep clicking to move until the 'Right' sprite shows up. Write down the values again.
3) Compare each values, and find the differences. Now deduce why the differences are as they are, using the values in conjunction with your blend trees.
4) Once you know why, go back through your code/blend trees and rewrite/fix it to work as you intended it to.

How do I correctly get control bound coordinates relitive to the control for mouse comparison?

I am presently learning C# and have chosen as a project to write a simple colour picker control ; however things have changed substantially since I last looked at writing code and I have struck this problem.
I am using the Mousedown event in my control to get the mouse coordinates as a Point - this is working fine and returns exactly what I would expect - the mouse coordinates relative to my control; however when I try and do a check against the control location I am returned a value as a Point showing the position of my control relative to the form which in certain cases the mouse coordinates will be outside the bounds of because their values will be less than the relative start position of the control I.E I click at pixel 1,1 in the control - the mouse position is 1,1 but because the control is located at 9,9 relative to the form the location of the mouse is less than the bounds of the control - I have absolutely no idea how to fix this, I have been attempting to sort it out with PointToClient and PointToScreen to no avail as they seem to come up with outlandish values can someone please help me out it's driving me insane.
I've managed to sort this out myself so thought I'd post the answer and it can hopefully help someone else. I was having problems getting Point values that were relative to the same pixel origin : this sorted it.
private void ColourPicker_MouseDown(object sender, MouseEventArgs e)
{ // Probably being paranoid but I am worried about scaling issues, this.Location
// would return the same result as this mess but may not handle
// scaling <I haven't checked>
Point ControlCoord = this.PointToClient(this.PointToScreen(this.Location));
int ControlXStartPosition = ControlCoord.X;
int ControlYStartPosition = ControlCoord.Y;
int ControlXCalculatedWidth = ((RectangleColumnsCount + 1) * WidthPerBlock ) + ControlXStartPosition;
int ControlYCalculatedHeight = ((RectangleRowsCount + 1) * HeightPerBlock) + ControlYStartPosition;
// Ensure that the mouse coordinates are comparible to the control coordinates for boundry checks.
Point ControlRelitiveMouseCoord = this.ParentForm.PointToClient(this.PointToScreen(e.Location));
int ControlRelitiveMouseXcoord = ControlRelitiveMouseCoord.X;
int ControlRelitiveMouseYcoord = ControlRelitiveMouseCoord.Y;
// Zero Relitive coordinates are used for caluculating the selected block location
int ZeroRelitiveXMouseCoord = e.X;
int ZeroRelitiveYMouseCoord = e.Y;
// Ensure we are in the CALCULATED boundries of the control as the control maybe bigger than the painted area on
// the design time form and we don't want to use unpaited area in our calculations.
if((ControlRelitiveMouseXcoord > ControlXStartPosition) && (ControlRelitiveMouseXcoord < ControlXCalculatedWidth))
{
if((ControlRelitiveMouseYcoord > ControlYStartPosition) && (ControlRelitiveMouseYcoord < ControlYCalculatedHeight))
{
SetEvaluatedColourFromPosition(ZeroRelitiveXMouseCoord, ZeroRelitiveYMouseCoord);
}
}
}

Get the Absolute Origin of an Object when DragStartedEvent fired

I've an app which like the image shown below (sorry I used an iPhone like mock-ups)
The app has an image as background (displayed using Canvas which takes the whole visual screen size), then another shape (the red rectangle in this case) will shown above the background which can be dragged and pinch zoomed.
Now the question is:
How can I get the coordinates (origins from top-left corner of the screen, i.e. top-left of the canvas) of the top-left corner of the rectangle?
UPDATE
According to #Will's suggestion, I currently move the rectangle in this case via DragDelta using TranslateTransform inside it, like:
rectTransform.X += e.HorizonalChange;
rectTransform.Y += e.VerticalChange;
The rectangle is defined within code, not in XAML:
rect.Stroke = new SolidColorBrush(Colors.Green);
rect.StrokeThickness = 10;
rect.Fill = new SolidColorBrush(Colors.Transparent);
rect.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
rect.VerticalAlignment = System.Windows.VerticalAlignment.Center;
rect.Width = 200;
rect.Height = 200;
canvas.Children.Add(rect);
and the canvas is defined within XAML.
What I've tried:
Initially I was trying to get the start point when the Drag event begins, but by using the DragStarted(object sender, DragStartedGestureEventArgs e), I am only able to output the coords of the point which was touched, but not the point of top-left corner of this rectangle.
And it's similar to the DragCompleted event which will return me the point the gesture ends.
So is there any chance I can get the origin coords of the red rectangle?
I spent nearly an afternoon on Google as well as MSDN and then finally come to find this on SO:
How to get the position of an element in a StackPanel?
which enlightened me using the similar method. In that case, they managed to get the absolute coordinates of an UI Element. Similarily, in my case, I intend to know the absolute origin(coordinates) of the red rectangle to the background canvas.
I use:
GeneralTransform gt = canvas.TransformToVisual(rect);
Point currentPos = gt.Transform(new Point(0, 0));
Then the currentPos is the current position of rectangle (its an absolute position, relative to the canvas).
And Here's the reference of TransformToVisual in MSDN
There's only one thing to pay attention to: the value of X and Y are negative.
Not 100% sure of the syntax here, but in WPF (which should be analogous) I'd handle it by
private double _startX, startY, _endX, _endY;
private void DragStarted(object sender, DragStartedGestureEventArgs e)
{
var rect = sender as UIElement; // I'm assuming the sender is your Rectangle
this._startX = Canvas.GetLeft(rect);
this._startY = Canvas.GetTop(rect);
}
private void DragCompleted(object sender, DragCompletedGestureOrWhateverLolEventArgs e)
{
var rect = sender as UIElement; // I'm assuming the sender is your Rectangle
this._endX = Canvas.GetLeft(rect);
this._endY = Canvas.GetTop(rect);
}
What you say? Not type safe? Yeah, well, okay. How about give your rectangle an x:Name and then use that in these methods?
<Rectangle x:Name="rect" SkipOtherPropertiesLol="true" />
and
this._startX = Canvas.GetLeft(rect); //etc
Attached properties are a little confusing at first, but they are very powerful and easy to use once you understand their fairy magic.

When I am trying to align fields vertically, they aren't behaving what I expected?(Blackberry JDE4.5.0 eclipse)

I am using Eclipse & JDE 4.5.0 plug-in. How to align fields vertically. Can we align fields like LEFT_BOTTOM,RIGHT_BOTTOM, LEFT_VCENTER, RIGHT_VCENTER, CENTER(vertically & horizontally), BOTTOM_CENTER, etc...?
BlackBerry UI field managers are notoriously annoying when dealing with field alignment. Managers seem to ignore all style flags (like HCENTER, VCENTER, etc) so the only way you'll be able to do this is to override the sublayout method of your manager and do it yourself.
Here's a little snippet to show you what I mean. This particular code actually does horizontal centering, not vertical centering, but once you get the idea you can implement any styles you need.
VerticalFieldManager mainmanager = new VerticalFieldManager(Field.USE_ALL_WIDTH | Field.USE_ALL_HEIGHT)
{
protected void sublayout( int width, int height ) {
super.sublayout( width, height );
width = getWidth();
height = getHeight();
for (int i = 0;i < this.getFieldCount() - 1; i++)
{
Field field = this.getField(i);
//this positions the item in the middle of the manager
int x = (int)((width - field.getWidth()) * 0.50);
setPositionChild(field, x, field.getTop());
}
}
Please note that the USE_ALL_WIDTH and USE_ALL_HEIGHT style flags are important. If you want to do things like vertical centering, bottom-right aligning, etc. you will need to write the positioning code yourself. For bottom-right alignment for example you could set the x position to the width of the manager minus the width of the field, and the y position to the height of the manager minus the height of the field.
If you want to be able to use one custom manager class to handle multiple different styles (like bottom right, bottom left) you can add some logic in sublayout to check the field's style flag and then position the field appropriately.
Hopefully this all makes sense and helps you. :)
HorizontalFieldManager only accepts Vertical Alignment Styles and VerticalFieldManager only accept Horizontal Alignment. That's it.
Annoying ++

Resources