I have this simple code. I have used the if statement to check that if i press the pause button, the jump animation will not be triggered. After the Paused Menu is activated, when i click resume, the game will start immediately and the character will jump straight away.
I have tried using Coroutines, with real time and time.timeScale = 0.001, but the action will still be triggered. Any ideas on how to solve?
private void Jump()
{
if (Input.touchCount > 0 && rb.velocity.y == 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
startTouchPosition = Input.GetTouch(0).position;
if (startTouchPosition.x < screenMinusButton.x || startTouchPosition.y < screenMinusButton.y)
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
}
}
Try to putting invisible full screen panel , back of the button/menu.
Does the character actually jumps or it's just an animation issue ?
Try to check your rb.velocity in the inspector. If is not visibile, try to enable debug mode in the upper corner.
If the Y doesn't change maybe it's just an animation triggered wrongly
Check if the EventSystem has any GameObject currently considered as active. If yes, the touch is performed over button else the touch is not over the button.
Add using UnityEngine.EventSystems; at the top of your script. Then modify your code as shown below.
if (Input.touchCount > 0 && EventSystem.current.currentSelectedGameObject == null && rb.velocity.y == 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
...
}
Use IsPointerOverGameObject()
if (!EventSystem.current.IsPointerOverGameObject() && Input.touchCount > 0 && rb.velocity.y == 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
}
I recently found the answer.
Related
This game plays correctly in the editor, with up and down arrows. When I built it for android, any touch makes the player jump. A downward swipe should cause a slide instead. The general idea of the touch direction came from another Q&A somewhere on the web, but obviously it's not working.
This is all in the Update() method of my PlayerController MonoBehaviour
//Check for Swipe Direction
if (Input.touchCount > 0)
{
theTouch = Input.GetTouch(0);
if(theTouch.phase == TouchPhase.Began)
{
touchStartPosition = theTouch.position;
}
if(theTouch.phase == TouchPhase.Ended)
{
touchEndPosition = theTouch.position;
swipeDirection = (int) (touchEndPosition.y - touchStartPosition.y); //probably should have named this swipeDirectionY, but swipeDirectionX won't be used in this game.
}
}
Then I have:
//JUMP
if ((Input.GetKeyDown(KeyCode.UpArrow) || (Input.touchCount > 0 && swipeDirection > 0 )) && isOnGround)
{/*JUMP CODE HERE*/}
and:
//SLIDE
if ((Input.GetKeyDown(KeyCode.DownArrow) || (Input.touchCount > 0 && swipeDirection < 0)) && isOnGround)
{/*SLIDE CODE HERE*/}
Make sure setting swipeDirection to 0 whenever player jump/slide. If not, it will keep repeating last swipe even if you don't move/swipe. Because touchCount will be positive in the moment you touch again and you will already have swipeDirection value that's not equal to 0.
I'm using this code to fade in a CanvasGroup at the beginning of my scene loading, and then if the player loses I want to fade out the scene and reload it from the beginning.
void Update () {
if (Time.time < 1 && fade.alpha >= 0)
fade.alpha = .99f - Time.time;
if (fadeOut)
fade.alpha += .02f;
if (fade.alpha >= 1)
{
Debug.Log("Change scene");
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
The problem is that when it hits this it shows the gamescene twice in the hierarchy, and neither one on the screen. I'll upload a picture below. When it does this is also hits the Debug.Log repeatedly. Does this not work if it's the only scene in the project? Only thing I can think of.
I've updated the method to include a boolean to ensure it SHOULD only run one time. Somehow it is still running countless times until I end the unity editor. The new update method is this :
void Update () {
if (Time.time < 1 && fade.alpha >= 0)
fade.alpha = .99f - Time.time;
if (fadeOut)
fade.alpha += .02f;
if (fade.alpha >= 1 && !reloadStarted)
{
Debug.Log("Change scene");
reloadStarted = true;
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
I guess Update is executed more rapidly than the scene is reloaded. So it starts to reload on every update. Introduce a bool property to indicate, that reload is already started.
if (fade.alpha >= 1 && !isReloadStarted)
{
Debug.Log("Change scene");
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
isReloadStarted = true;
}
Furthermore according to your description, you might want to reload when fade.alpha is less or equal to 0.
fade.alpha <= 0
I ended up refactoring the code and implementing this in a completely different way. I still don't know why it was acting so weird.
I have built a small game by unity. In which, when the player touch the screen a pin spawns. The problem I am having is, when I touch the screen, instead of one, two pin spawns at a time. I used this code-
if(Input.touchCount == 1)
{
Spawnpin();
}
Put the code inside TouchPhase.Began or TouchPhase.Ended so that it will be called once only and will only be called again when the touch is released and pressed again. Deciding between TouchPhase.Began and TouchPhase.Ended depends on whether you want the touch to register immediately when it is pressed or after it is released.
void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
if (Input.touchCount == 1)
{
Spawnpin();
}
}
}
}
When I run my app on Android, the first finger touch calls Input.GetMouseButtonDown(0)
and the second touch calls Input.GetMouseButtonDown(1).
I want to override GetMouseButtonDown(0) in some cases- so the second finger (1) touch will become the first (0) and I don't know how to do it.
Either this or how to force mouseButtonUp on the first finger touch- I want to remove this first "click" from the system so it'll not use Input.mousePosition in a case of 2 touches.
Why?
I'm creating a paint app when the user can draw lines.
There is an area when the user can paint (in a rectangle) and an area where he shouldn't, I know how to detect when pressed on unwanted area.
But sometimes the palm of my hand creates unwanted first touch Input.GetMouseButtonDown(0) on the unwanted area (without Input.GetMouseButtonUp(0)) and when I start to draw a line
Input.mousePosition gets the average of both touches, so I just want a way to remove a "down" touch/click from the system. Or another way to solve my problem.
Here is my code:
if (Input.touchCount == 0)
{ screenPoint = new Vector3(0, 0, 0);
currentTouch = 4; //currentTouch is for GetMouseButtonUp(currentTouch) }
for (int i=0; i< Input.touchCount; i++)
{
touch = Input.GetTouch(i);
screenPointTemp = touch.position;
screenPointTemp3 = new Vector3(screenPointTemp.x, screenPointTemp.y, zCam);
//if the touch is in a "good" zone-
if (Camera.main.ScreenToWorldPoint(screenPointTemp3).z > BottomNod.transform.position.z - nodeScale)
{
screenPoint = touch.position;
currentTouch = i;
}
}
}
if (Input.GetMouseButtonUp(currentTouch))
{...}
When working on mobile devices to detect a touch on the screen without clicking on any object, you should be using Input.touchCount with Input.GetTouch or Input.touches. Although I highly recommend Input.GetTouch since that doesn't even allocate temporary variables like Input.touches. To get the postion of the touch use, Input.GetTouch(index).position.
Each of these functions returns Touch so you can use Touch.fingerId to detect/keep track of how many touches you want at the-same time. You can also use the index that is passed in to Input.GetTouch to keep track of the touch. That's totally up to you.
This detects every touch down, move and up on mobile devices:
for (int i = 0; i < Input.touchCount; ++i)
{
//Touch Down
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
}
//Touch Moved
if (Input.GetTouch(i).phase == TouchPhase.Moved)
{
}
//Touch Up
if (Input.GetTouch(i).phase == TouchPhase.Ended)
{
}
}
Limit to one touch only(Use index 0):
if (Input.touchCount == 1)
{
//Touch Down
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
}
//Touch Moved
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
//Draw?
}
//Touch Up
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
}
}
Like I said, you can limit this with fingerId. The implementation depends on what exactly that you want.
Im trying to use touch controls to move my character on a device such as an iPhone. So far I have had limited success. This code works but only with one of the buttons. I have both a left and right button and the left button worked until I added the right button. Now only the right button works. Any help would be appreciated.
foreach (Touch touch in Input.touches)
{
if(leftButton.guiTexture.HitTest(touch.position) && touch.phase != TouchPhase.Ended)
{
move = -1;
anim.SetFloat ("Speed", Mathf.Abs (move));
}
else if(rightButton.guiTexture.HitTest(touch.position) && touch.phase != TouchPhase.Ended)
{
move = 1;
anim.SetFloat ("Speed", Mathf.Abs (move));
}
else if((leftButton.guiTexture.HitTest(touch.position) && touch.phase == TouchPhase.Ended) &&
(rightButton.guiTexture.HitTest(touch.position) && touch.phase == TouchPhase.Ended))
{
move = 0;
}
}
An much easier alternative method for clicking would be
if(Input.GetMouseButtonDown(0))
{
//Your stuff here
}
remember to change input for clickable object (which i think is touch)
First, do a sanity check and verify that the left and right buttons are setup correctly on your component.
I'm not currently on a computer with unity to test everything, but there is a lot of redundancy here, we can clean it up to make debugging the problem easier. Another red flag is I don't see move being set to 0 before the input check, so I'll add that. Try this code and see if you are still seeing the problem, and perhaps you will be able to better debug with monodevelop what is happening.
move = 0;
bool isLeftPressed = false;
bool isRightPressed = false;
foreach (Touch touch in Input.touches)
{
// Only process touches that aren't in the ended phase
if (touch.phase == TouchPhase.Ended)
return;
if (leftButton.guiTexture.HitTest(touch.position))
isLeftPressed = true;
if (rightButton.guiTexture.HitTest(touch.position))
isRightPressed = true;
}
if (isLeftPressed && isRightPressed)
{
// Do nothing when both are pressed (move already set to 0)
}
else if (isLeftPressed)
{
move = -1;
}
else if (isRightPressed)
{
move = 1;
}
anim.SetFloat ("Speed", Mathf.Abs (move));
I made a few assumptions about what you were trying to do with the check if both left and right are pressed. Rather than setting the move value in the foreach loop, we just set flags so that after processing each touch we can see which buttons are being pressed (If finger 0 is touching one, and finger 1 is touching the other, I assume that means you want there to be no movement?)