Destroy GetMouseButtonDown event and position or force mousebuttonup - c#

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.

Related

How can I get the swipe direction in android when coding a game in Unity3d engine?

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.

Touchphase.Ended does not run

I am trying to give force to a rigidbody object by touch and dragging away from it and then releasing the touch. But the Touchphase.End just doesn't run. I can't find the answer to this problem. I get input from one touch until the touch releases, on releasing the touch the distance between the starting and final position is calculated and a similar force is applied on the rigidbody to make it move. The object on which the code is attached is the same object which needs to move.
// Update is called once per frame
void Update()
{
//Update the Text on the screen depending on current TouchPhase, and the current direction vector
// Track a single touch as a direction control.
if (Input.GetMouseButton(0))
{
Touch touch = Input.GetTouch(0);
_touchPosWorld =
Camera.main.ScreenToWorldPoint(touch.position); //get the position where the screen was touched
RaycastHit2D hitInformation = Physics2D.Raycast(_touchPosWorld, Vector2.zero);
FirstTouch = (hitInformation.collider.CompareTag("ball"));
if (FirstTouch || IsInTouch)
{
// Handle finger movements based on TouchPhase
switch (touch.phase)
{
//When a touch has first been detected, change the message and record the starting position
case TouchPhase.Began:
// Record initial touch position.
IsInTouch = true;
_startPos = touch.position;
GameManager.GetInstance().ChangeAccordinglyText.text = "clicked Inside";//test text
//Movement started
break;
//Determine if the touch is a moving touch
case TouchPhase.Moved:
// Determine direction by comparing the current touch position with the initial one
_direction = touch.position - _startPos;
GameManager.GetInstance().ChangeAccordinglyText.text = "MovingTouch to " + touch.position; //test text
//moving
break;
case TouchPhase.Ended:
// Report that the touch has ended when it ends
//end of movement of touch
GameManager.GetInstance().EndedText.text = "EndOfTouch";
float force = 0;
force = _direction.x > _direction.y ? _direction.x : _direction.y;
_rigidbody.AddForce(_direction * force);
FirstTouch = false;
IsInTouch = false;
break;
}
}
}
}
Your TouchPhase.End will never be reached since in the moment you release the touch also GetMouseButton(0) will be false and thus the entire block skipped!
To avoid the errors you are talking about before trying to access a certain touch, first check if there is any touch to access using Input.touchCount
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
// ...
}
In general for development you should rather check for e.g. Input.touchSupported and implement an alternative mouse system for simulating the touches
if(Input.touchSupported)
{
/* Implement touches */
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
// ...
}
}
// Optional
else
{
/* alternative mouse implementation for development */
if(Input.GetMouseButtonDown(0))
{
// simulates touch begin
}
else if(Input.GetMouseButton(0))
{
// simulates touch moved
}
// I've seen in strange occasions that down and up might get called within one frame
if(Input.GetMouseButtonUp(0))
{
// simulates touch end
}
}

Can't solve hitbox issues in mobile game made in Unity

I am developing a game where objects fall from the top of the screen, and you try to and tap on them before they reach the bottom of the screen. The code works fine when I played the game in the editor (with the touch controls swapped to mouse controls), except when I run the game on a phone, the game only seems to register a successful hit if you tap slightly in front of the object in the direction that it is traveling, and does not register a hit if you tap towards the back end or center of the object. I have built and ran the game over 10 times now, each time trying to fix this issue but nothing seems to help. My theory at the moment is that my code for the touch controls have too much going on and/ or have redundancies and by the time it checks whether or not an object is at the position of the touch, the object has moved to a different location. Any thoughts on why the hit boxes are off, and is there a better way to do hit detection with touch screen?
void FixedUpdate()
{
if (IsTouch())
{
CheckTouch(GetTouchPosition());
}
}
// Returns true if the screen is touched
public static bool IsTouch()
{
if (Input.touchCount > 0)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
return true;
}
}
return false;
}
// Gets the position the touch
private Vector2 GetTouchPosition()
{
Vector2 touchPos = new Vector2(0f, 0f);
Touch touch = Input.GetTouch(0);
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
touchPos = touch.position;
}
return touchPos;
}
// Checks the position of the touch and destroys the ball if the
ball is touched
private void CheckTouch(Vector2 touchPos)
{
RaycastHit2D hit =
Physics2D.Raycast(Camera.main.ScreenToWorldPoint(
(Input.GetTouch(0).position)), Vector2.zero);
if (hit.collider != null)
{
destroy(hit.collider.gameObject);
}
}

Unity Touch Input

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();
}
}
}
}

Touch Controls Unity2D

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?)

Categories

Resources