I'm trying to make it possible to drag an object. This object can only rotate so much. (Similair to a door).
Here is the code abit edited that rotates an object which works.
I have 2 vectors for maxrotation and minrotation.
This code will be called whenever the user is dragging the interactible object. (like update but only when dragged)
if (GestureManager.Instance.IsNavigating &&
HandsManager.Instance.FocusedGameObject == gameObject)
{
//speed and navigiation of rotation
float rotationFactor;
rotationFactor = ManipulationManager.Instance.ManipulationPosition.y * RotationSensitivity;
totransform.Rotate(new Vector3(rotationFactor, 0, 0));
}
It would be great if I could use an if statement here. And I tried quite some things but it's still not working.
As stated the code paste here works. The object should be dragable but only up to a certain points.
totransform is the transform that will be rotated
Any ideas would be great and most appreciated.
Kind regards.
I think you want to look at eulerAngles. Check the values you're getting then set an if-statement before doing the rotation. This is a sample code for you to find the values you want:
if (GestureManager.Instance.IsNavigating &&
HandsManager.Instance.FocusedGameObject == gameObject)
{
//speed and navigiation of rotation
float rotationFactor = ManipulationManager.Instance.ManipulationPosition.y * RotationSensitivity;
Debug.Log(totransform.eulerAngles);
if (totransform.eulerAngles.x < 100) {
totransform.Rotate(new Vector3(rotationFactor, 0, 0));
}
}
So here is the solution that worked for me. First I declare the movement variable (not seen down below, which is 2 in this case). Then I track the distance covered and put a limit on that.
Of course there are some improvements to this code like use movement instead of 2. But because of time constraints I didn't do it.
if (GestureManager.Instance.IsNavigating &&
HandsManager.Instance.FocusedGameObject == gameObject)
{
//here we get the movement direction and set it in movement.
if (GestureManager.Instance.NavigationPosition.y > 0)
{
movement = 2;
}
else if (GestureManager.Instance.NavigationPosition.y < 0)
{
movement = -2;
}
//the first part is false if we reach higher then maxdistance and the movement is going up
//the second part is false if we reach the lower distance and the movement is going down.
if ((!(distance > maxdistance.x) || movement < 0) && ((!(distance < mindistance.x) || movement > 0)))
{
//here we add the movement to the distance so we know if it gets closer or further
distance += movement;
//here we rotate
totransform.Rotate(new Vector3(movement, 0, 0));
}
}
Related
I have written this code for my controller in Unity. The problem is that the jump in Y axis has different height than the jump for X and Y axis simultaneously.
// Update is called once per frame
void FixedUpdate()
{
Debug.Log(rigidbody.velocity);
float inputX = Input.GetAxis("Horizontal");
//Movement X
if(inputX != 0 && isGrounded)
{
animator.SetBool("isWalking", true);
rigidbody.velocity = new Vector2(inputX*speed, 0);
//Turn left & right
if(inputX > 0)
{
spriteRenderer.flipX = false;
} else if (inputX < 0)
{
spriteRenderer.flipX = true;
}
} else
{
animator.SetBool("isWalking", false);
}
//Jump
if(Input.GetAxis("Jump") > 0 && isGrounded)
{
rigidbody.AddForce(Vector2.up * jumpImpulse, ForceMode2D.Impulse);
}
}
if i understand your code right, you only gives force to X when you are in ground, so i suggest to remove isgrounded variable and use it just for jump for example in your update method
if(isGround){
if(keypress == y){
addforce in Y
}
}
actually im a bit oxided in unity but i hope to be usefull about logical
I am pretty bad myself when it comes to the jumping physics, but i found these links maybe these will help you.
Unity 2d jumping script
https://answers.unity.com/questions/710765/2d-c-jump-script-addforce-1.html
I also want to know which jump is higher. You stated that there is a height difference when you jump without moving vs when you are moving. Which of the two jumps higher? Are you actually sure that one jumps higher than the other or does it just look like one jumps higher? You can test this by placing a platform an test if you can make it.
Sorry I can't me of more help and can only speculate of what might cause the problem. I would recommend however that when you do movement that you multiply it by Time.DeltaTime. This makes the movement time based instead of frame based. This will make the movement feel smoother.
I am trying to re-create the popular SnakeVSBlock mobile game. Most of the physics are pretty straight forward but I cannot seem to re-create the snake movement. What's special about the snake movement in the game is that the previous node follows the next ones path perfectly, both in X and in Y. This is my current code which does work as a snake movement but does not follow the exact path of the next node. I'm wondering if anyone has a solution to this.
public void Move()
{
if (Input.GetMouseButton(0) && GameManager.Instance.IsGameOver() == false && Nodes.Count > 0)
{
Vector3 curPos = Input.mousePosition;
curPos.z = -1;
curPos = Camera.main.ScreenToWorldPoint(curPos);
Nodes[0].GetComponent<Rigidbody2D>().velocity = new Vector2(curPos.x - Nodes[0].position.x, 0) * 20;
if (Nodes[0].position.x > 2.56f)
{
Nodes[0].position = new Vector2(2.56f,Nodes[0].position.y);
}
else if (Nodes[0].position.x < -2.56f)
{
Nodes[0].position = new Vector2(-2.56f, Nodes[0].position.y);
}
for (int i = 1; i < Nodes.Count; i++)
{
Vector2 newPos = new Vector2(Nodes[i-1].position.x, Nodes[i].position.y);
if (GameManager.Instance.GetPoweredUp())
{
Nodes[i].position = Vector2.Lerp(Nodes[i].position, newPos, Time.deltaTime * 14);
}
else
{
Nodes[i].position = Vector2.Lerp(Nodes[i].position, newPos, Time.deltaTime * 10);
}
}
}
UPDATE: I changed the basic logic for the snake movement in my game. Instead of having the snake move upwards, the snake stays in the same position and the blocks move downwards. However I still can't obtain the smooth snake movement like in the real games. Are there any other suggestions?
If I understand what you want to do, you should approach this in the reverse order.
So, if you have the nodes 0 to n:
Start from the n-th node
Assing this node the position of the (n-1)-th node
Then for each i node, assign it the position of the i-1 node
When you moved all the nodes, move the node 0 according to the user input.
It should look like this:
public void Move()
{
int n = Nodes.Count;
if (n > 0)
{
for (int i = n - 1; i > 0; i--)
{
_curNode = Nodes[i];
_nextNode = Nodes[i - 1];
Vector3 pos = _nextNode.transform.position;
pos.z = Nodes[0].position.z;
_curNode.tranform.position = pos;
}
float horizontalInput = Input.GetAxis("Horizontal");
Nodes[0].Translate(Vector3.right * Time.deltaTime * horizontalInput * 10);
Nodes[0].Translate(Vector3.up * Time.deltaTime * 4);
if (Nodes[0].position.x > 2.90)
{
Nodes[0].position = new Vector2(2.90f, Nodes[0].position.y);
}
else if (Nodes[0].position.x < -2.90)
{
Nodes[0].position = new Vector2(-2.90f, Nodes[0].position.y);
}
}
}
Also, unless you somehow increment the two LerpTime variables, you're misusing the Lerp function, and you don't need it in this context either.
This is an awesomely clear guide on what Lerp really means and how to use it properly:
http://lunarlabs.pt/blog/post/the-art-of-lerp
The old mobile game "snake" where you collect little squares has the same sort of movement. The solution then was that the parts of the snake don't actually move, just each frame you add a bit to the head and take one off the tail.
The reason why that approach works with snake but not immediately in this snake vs blocks game is that the former is discrete, and the latter is continuous.
One way to solve this is that each body part could always be lerping towards the one above it and when it gets there, it teleports back. This would give the illusion of the snake moving forward, when actually the body parts are stuck in place, just like the old snake game.
This works on paper but I have no idea how it will perform. However, if you are really desperate you could consider giving this a try.
(Before you read, I'm very nervous about posting here since my previous question got a lot of negative responses... Please try and be nice. I am a student and can't write "Perfect" code yet)
I'm currently trying to figure out how to make a mosquito (Texture2D) swoop downwards and then come back up to it's original position.
Currently the mosquitoes simply move left and right within the screen bounds, with no Y movement.
I've stepped it through a debugger and observed it's Y coordinate. My mosquitoes are indeed swooping down and then back upwards again... However, they do it so quickly that it isn't visible to the human eye.
Therefore I need a way to smoothly swoop them down so that it's actually visible.
I am currently unable to embed images into my posts, however I have made a GIF demonstrating the effect that I want.
Here's a link to my GIF
Things I've tried:
Copied the first line of my movement code (seen below) and changed it so that it would only affect the Y coordinates.
Result: Mosquitoes were still swooping too fast to see.
Changing my mosquitoe's velocity.Y to include a Y that isn't 0, so that my movement code will also change the Y position instead of just the X position.
Result: Game was stuck in an infinite loop since my movement code is found in the Update() function, and the code never got out of the loop so that it could update the position...
Here's the movement code I have in my Update.
The mosquitoes move all the way to the right, then all the way to the left.
internal void Update(GameTime GameTime)
{
position += velocity * (float)GameTime.ElapsedGameTime.TotalSeconds;
// Reverses the direction of the mosquito if it hits the bounds
if (position.X <= gameBoundingBox.Left ||
position.X + animationSequence.CelWidth > gameBoundingBox.Right)
{
velocity.X *= -1;
}
}
And here's the actual Swoop() code that I have...
internal void Swoop(GameTime gameTime)
{
float originalYPosition = position.Y;
bool currentlySwooping = true;
while (currentlySwooping)
{
position.Y++;
if (this.BoundingBox.Bottom >= gameBoundingBox.Bottom)
{
currentlySwooping = false;
}
}
while (!currentlySwooping && position.Y > originalYPosition)
{
position.Y--;
}
}
I don't ask questions on here too often, so I'm sorry if I'm using an incorrect format or if I've given too little information.
If you need to know anything else then please let me know.
There are many ways of implementing this, but this should do it.
float originalYPosition = position.Y;
int swoopDirection = 0;
internal void Update(GameTime GameTime)
{
/* Same update code */
if (swoopDirection != 0)
{
position.Y += swoopDirection;
if (swoopDirection == 1 && this.BoundingBox.Bottom >= gameBoundingBox.Bottom)
{
swoopDirection = -1;
}
else if (swoopDirection == -1 && position.Y <= originalYPosition)
{
swoopDirection = 0;
}
}
}
internal void Swoop()
{
swoopDirection = 1;
}
Basically, we have a variable swoopDirection that changes depending on the state of the swoop (1 when going down and -1 when going up). In the update method we check that swoopDirection != 0 (we are swooping). If we are swooping we add the direction to the Y axis and check that we aren't out of bounds. If we touch the bottom we set swoopDirection to -1 so we go up. If we are at the original position swoopDirection is set to 0 and we stop swooping.
i currently have a gameobject named "block" with two long cubes next to each other with a gap between them. now when a user touches the screen and drags left or right the block also moves in that direction. now i am trying to setup a boundary so they can go up to a certain amount in the left or right direction. however how can i code this so it is the same for different screens eg iphone ipad etc.
the code i am currently using makes the block overlap each other getting rid of the gap which needs to be there. how do i go about to fix this. the code is below:
public float speed = 0.0F;
void Update() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -1f, 1f);
transform.position = boundaryVector;
}
}
For screen size problem I recommend u put some Image Ui at the background and then according to different resolution set it Using anchor property and .
Make height to width ratio 0.5,Set UI scale to screen size...all these in Inspector Only.
Get the left and right boundary values from Transform and then in block gameobj script use it as follows :
//windows specific code
float x=Input.GetAxis ("Horizontal");
if (x == 0) {
Stop ();
} else if (x > 0) {
MoveRight ();
} else if (x < 0) {
MoveLeft ();
}
pos = transform.position; //left //right
pos.x=Mathf.Clamp (pos.x, "your boundry min to", "Your boundry max");
transform.position = pos;
for overlap problem u can make use of Parent/ child property in Block .Make one the child of another..in this way If u move left the right block will also move left and they will not overlap....
I have 2 images(bar and greenBall1). bar can be move up and down depends on the user response. While, greenBall1 is moving around the screen. I want to do an image collision if both the images touch each other, greenBall1 will change its velocity. The codes that I have for greenBall1 are as below.
private void OnUpdate(object sender, object e)
{
Canvas.SetLeft(this.GreenBall1, this.greenBallVelocityX + Canvas.GetLeft(this.GreenBall1));
Canvas.SetTop(this.GreenBall1, this.greenBallVelocityY + Canvas.GetTop(this.GreenBall1));
var greenBallPositionX1 = Canvas.GetLeft(this.GreenBall1);
var greenBallPositionY1 = Canvas.GetTop(this.GreenBall1);
var maximumGreenBallX = ActualWidth - this.GreenBall1.ActualWidth;
var maximumGreenBallY = 400 - this.GreenBall1.ActualHeight; //Improvise: Instead of 360, get maximum height of canvas
if (greenBallPositionX1 > maximumGreenBallX || greenBallPositionX1 < 0)
{
this.greenBallVelocityX *= -1;
}
if (greenBallPositionY1 > maximumGreenBallY || greenBallPositionY1 < 0)
{
this.greenBallVelocityY *= -1;
}
}
I don't see a reference to the bar object in your code. But the detection of the collision is much easier than the physics of handling the collision. There are several schools of thought to something as simple as Pong collision, and the way you choose to handle it depends on the gameplay you want.
Here is an easy way to detect and handle the collision, simply by negating the X velocity just as you are handling the wall collisions:
if(greenBallPositionX1 < leftBar.X || greenBallPositionX1 > rightBar.X)
{
this.greenBallVelocityX *= -1;
}
Keep in mind you might also have to take into account the width of the bar or the ball depending on where the coordinate is in relation to the image. For example:
if(greenBallPositionX1 < (leftBar.X + leftBar.Width) || greenBallPositionX1 > rightBar.X)
{
this.greenBallVelocityX *= -1;
}
You may also want to at this point move the ball away from the paddle one step to avoid the collision being detected more than once.
Hopefully this answers what you were asking, but if you were looking for a more complex reaction to the collision detection, then you may want to check out the following discussion on Pong type collisions here.
i think this might help you ....
.
Rectangle ballRect = new Rectangle((int)ballposition.X, (int)ballposition.Y, ballsprite.Width, ballsprite.Height);
Rectangle handRect = new Rectangle((int)paddlePosition.X, (int)paddlePosition.Y, paddleSprite.Width, paddleSprite.Height/2);
if (ballRect.Intersects(handRect))
{
// Increase ball speed
ballSpeed.Y += 50;
if (ballSpeed.X < 0)
ballSpeed.X -= 50;
else
ballSpeed.X += 50;
// Send ball back up the screen
ballSpeed.Y *= -1;
}
in this whenever the ball will collide with hand it will increase its speed and change its direction i think that is the think you are looking for as it is also a rectangular collision.
make a class which will give you value that wether two rects will collide or not
public bool Intersects(Rect r1,Rect r2)
{
r1.Intersect(r2);
if(r1.IsEmpty)
{
return false;
}
else
{
return true;
}
}
then you can use
if(Intersects(r1,r2))
{
MessageBox.Show("Collison Detected");
}