I'm trying to create a 2d game with a player ( a ball ) that jumps when I touch the screen. I accomplish this with :
if (Input.GetMouseButtonDown (0) || Input.GetKeyDown("space")) {
gameObject.GetComponent<Rigidbody2D>().velocity=Vector.up*speed;
gameObject.GetComponent<AudioSource>().Play();
}
(The code is in Update())
There isn't any type of problem in the Editor, but when I debug the game on my Android phone the ball doesn't jump every time I touch the screen and, due to the gravity, it fall down, as if I had not touched. In particular I noticed that the problem is more evident after some minutes of play, or every time I realod the level. I've tried many things but none helped me. What am I doing wrong?
Both Input.GetMouseButtonDown() and Input.GetKeyDown() are not associated with Mobile Touch input detection. For touch detection, check this reference.
Input.GetMouseButtonDown(0) does not officially work with touches, however, it sometimes still gets called, which is undocumented behavior and should therefore not be relied on.
If you want to check for a touch you can use:
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
As a sidenote (This is not part of the touch input problem you're having) : Try to add forces to the rigidbody instead of setting the velocity directly as this might otherwise "break" the physics simulation.
Related
I am working on a game in unity, a type of sliding number puzzle where you have to line up each piece in ascending order. My code of checking collisions is only working when I start the game, so if I move a piece, it won't tell the near pieces that I moved the near piece. I hope you understood my problem, every help is appreciated. Thank you.
This is how my code looks with the up check. I
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "Piece" || collision.gameObject.name == "Up_Collider")
{
piece_Script.Collide_Up = true;
Debug.LogError("Up");
}
else
{
piece_Script.Collide_Up = false;
}
}
I Thought that the else statement will solve this problem but it didn't.
Make sure all the things I write below are correct in your project:
1- You are using "2D" colliders on both objects.
2- At least 1 of the objects has a "Rigidbody2D".
3- IsTrigger Checkbox is active in your collider.
4- You are using the correct Tag.
5- Check layer collision matrix in - Edit > Project Setting > Physics2D.
And it is better to use tag instead of name
Based on your code in your question and your video, I see at least a couple issues.
First, there's an issue with how you're moving pieces. Your movement code for a Piece is:
Piece.transform.position = Vector3.Lerp(a, b, t);
This is not correct if you want to trigger collider events. These require interactions with rigidbodies, which means you should instead be changing the position of the piece's rigidbody with Rigidbody2D.MovePosition(). This will move your rigidbody within the physics system, which means taking into account collisions/triggers.
So (assuming you get the rigidbody for each Piece when you initialize them), your code might look like:
// Note also that I used Vector2 here - it's best you keep it consistent
pieceRigidbody.MovePosition(Vector2.Lerp(a, b, t));
Second, OnTriggerEnter2D() is not fired when two colliders stop touching. So I don't see your "else" condition being particularly useful. To achieve that with your current code, you could theoretically introduce OnTriggerExit2D() to take care of the "else" condition. However, you run into complications because while moving, a Piece may Enter and Exit the same directional colliders of two other Pieces before coming to rest. You'd have to take into account the order that occurs to get an accurate final state.
While workable, I have an alternative approach to suggest: Abandon using Trigger Collider events, and only check for a valid move at the time a Piece is clicked. Eliminate the collider event handlers, and just execute a Physics2D.OverlapBox() in each position around a Piece when it is clicked. If the position is occupied by another piece or an edge, that's not a valid move. If there is a position without something blocking it, then move the piece there.
I have a game in Unity where cubes are repeatedly moved past the camera. I move the cube using a script where I set its Rigidbody's velocity each update. Once it moves out of view my script instantiates a new cube on the other side which begins the process again.
Recently I've found that it works fine for a random amount of cubes before, seemingly randomly, a cube is instantiated that does not move. Using the inspector I can see that this object has velocity. If I move it even a small amount using the editor it starts to move as normal.
Has anyone seen something like this before?
I'm fairly certain the problem was related to the fact I was trying to directly modify the velocity( The physics engine decided the object was at rest and stopped it moving. ). By setting the object to be kinematic and modifying its position in my code I solved the problem.
May be you are changing the velocity of your gameObject when it goes through a specific coordinate (in an if statement for example), unity is not very accurate sometimes with coordinates so it may be happening that the condition is never met. Change that condition and add a margin range to solve this error.
I've created a player character in Unity and jumping works like it should.
But when she starts to fall back down to the ground, I want her to fall quickly.
She is almost floating back down, which interrupts the level's feel.
What parameter am I missing that allows her to fall back to the ground?
I'm going for a Mario feel, where he crests at the jump and then falls fairly quickly back down to the ground.
Simply add more gravity to whatever component that controls your characters' physics e.g. If you are using a rigidbody component then increase the gravity property.
I have this code to make the spaceship go up and not let gravity crush it against the floor.
if (Input.touchCount > 0)
GetComponent<Rigidbody2D>().AddForce(Vector2.up * force);
But when I go play the game on my phone, the game is tracking whether or not I keep pressing/touching the screen, and increasing the force with which I go up according to it. This makes it really difficult because it is very sensitive, I need to really focus and tap really fast to not make it go puf up the sky (and against the roof which is another obstacle in my game).
Also, if any of you can give me some pointers on how to make the GUI scale according to device screen I'd REALLY appreciate it, I can't seem to figure it out even with a couple of tutorials, I feel stupid.
You can use a boolean variable to make sure that the force is applied only once per touch.
private bool touchCont = false;
void Update(){
if (!touchCont && Input.touchCount > 0){
touchCont = true;
GetComponent<Rigidbody2D>().AddForce(Vector2.up * force);
}
if (Input.touchCount == 0){
touchCont = false;
}
}
Even though FixedUpdate() is usually recommended for rigidbodies, my algorithm is using Update(), because touch events are changing for every update. This way and with the help of the boolean variable the force is only add once per new beginning of touch events.
Or if you want to apply the force on every new touch, even they are concurrent, you can use Input.touches to get all the touches. If any of the touches are TouchPhase.Began, it means they have just started.
If you are setting your GUI sizes in code, one way to make GUI scale is that you can use for example Screen.width / 8 instead of 200. For better scaling, even the font size can be set the same way.
I've got a coin RigidBody and walls around it with box colliders. For trial purpose I've applied the following code to the coin.
private void OnMouseDown()
{
rigidbody.AddForce(30.0f, 0f, 5.0f, ForceMode.Impulse);
}
But, sometimes the coin passes through the walls, but when I increase the speed from 30 to 50 points it passes through the walls on the first click. I've googled a lot and still got nothing except for the DontGoThroughThings Script which doesn't work for me or I don't really know how to use it.
I've always added a continuous dynamic on the coin and continuous collision detection on the walls but still doesn't work.
the problem with physics collision detection is that sometimes when the speed of an object is too high (in this case as a result of a force added to the rigid body) the collision wont be detected. The reason is that the code you are executing is running at x ammount of steps per seconds so sometimes the rigidbody will go through the collider between one step to another. Lets say you have a ball at 100 miles per hour and a wall that is 1 feet wide, the code will move the ball a determined ammount of feets everytime the code is runned according the physics of it, so the movement of the ball is virtualized but its not a real physical movement so it can happen that from one step to another the ball can move from point a to b and the wall is between those points and as a result the collision will not be detected.
Possible Solutions.
You have a simple solution that wont be as accurate as it should be and a harder one that will be perfectly accurate.
The solution number one will be increasing the colliders size, according to the max speed your coin can get, that way the collider will be big enough so that the collision wont be missed between one frame to another.
The second and harder solution will be adding an auxiliar to your collision detection, some kind of a security check. For example using physical raycast. You can set a raycast to forward direction and determine if that object is an inminent collision, if it does and once the object isnt being collided by the raycast anymore then your collision detection had failed that way you have your auxiliar to confirm that and call the collision state.
I hope it helped and sorry about my english. If you didnt understound it very much i could help you with code but i will need some code from your project.
See if the colliders have their 'Is Trigger' unchecked.
Also, check if the gameObjects have colliders.
I have faced this problem many times..
Make sure Your coin's Rigidbody has "Is Kinamatic" False, Is Triggger:false,
And also "Is Trigger" of walls is False.
You could save the velocity and position on each update and then test for out of bounds, if the coin leaves the valid area you can restore it at the last valid position or plot the collision yourself if you want to