How to make GetTouch(1) not depending on GetTouch(0) and touchCount - unity3d

I'm making an app which asks to keep touch 2 things at same time, but sometimes only one.
So my problem is: GetTouch(1) depends on GetTouch(0) and touchCount.
If I release 1 time the getTouch(0) : getTouch(1) will not be called anymore.
I don't know if I'm clear so here is my code:
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
}
if (touch.phase == TouchPhase.Ended)
{
}
if (Input.touchCount == 2)
{
Touch touch_ = Input.GetTouch(1);
if (touch_.phase == TouchPhase.Began)
{
}
if (touch_.phase == TouchPhase.Ended)
{
}
}
}
How can I do to still keep the Touch(1) even without Touch(0) Pressed please ? Just keep doing my stuff during "touch_.phase == TouchPhase.Began".
Thank you in advance.

you will only be able to access Input.GetTouch(1) when the touchCount is 2 or greater. You are probably looking for some sort of state variable
bool firstPress = false;
bool secondPress = false;
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
firstPress = true;
}
if (touch.phase == TouchPhase.Ended)
{
firstPress = false;
}
if (Input.touchCount == 2)
{
Touch touch_ = Input.GetTouch(1);
if (touch_.phase == TouchPhase.Began)
{
secondPress = true;
}
if (touch_.phase == TouchPhase.Ended)
{
secondPress = false;
}
}
}
if (firstPress == true && secondPress == false)
{
...
}
if (firstPress == true && secondPress == true)
{
...
}

While the GetTouch has no guarantee that the same index returns the same touch in the next frame what you can use use the Touch.fingerIndex which is unique for each touch.
So instead of using GetTouch you can access the touches via Input.touches and then try to filter out the one for your stored fingerId e.g. like
foreach (Touch touch in Input.touches)
{
if (touch.fingerIndex == storedFingerIndex)
{
// Do something
}
}

Related

is it possible to select and move a on-screen joystick from script?

I try to add a Joystick programmatically by a touch. The prefab with the attached On-Screen Stick gameobject get instantiated and if I release this finger, the gameobject get destroyed. The only problem is, I cannot move the joystick. Is there a way to make the joystick responsible to the finger who instantiated the joystick prefab?
i tried this: but with no luck:
ExecuteEvents.Execute(leftJoyStick.GetComponent<OnScreenStick>().gameObject,
new BaseEventData(EventSystem.current), ExecuteEvents.selectHandler);
please help.
Ok i'm kinda stupid. i don't need a joystick and do it this way bellow.
when i touch the right side of screen i can look around, when i touch the left side of screen i can move around without a static joystick.
private bool hasLeftStick = false;
private Touch joystickLeftToch;
private Vector2 leftStickTouchStartPos;
private bool hasRightStick = false;
private Touch lookFinger;
private Vector2 rightStickTouchStartPos;
// used in Update()
private void ObserveTouches()
{
foreach (var touch in Input.touches)
{
if (Camera.main.ScreenToViewportPoint(touch.position).x > 0.5f)
{
if (!hasRightStick)
{
hasRightStick = true;
lookFinger = touch;
rightStickTouchStartPos = touch.position;
}
}
else
{
if (!hasLeftStick)
{
hasLeftStick = true;
joystickLeftToch = touch;
leftStickTouchStartPos = touch.position;
}
}
if(joystickLeftToch.fingerId == touch.fingerId && touch.phase == UnityEngine.TouchPhase.Moved)
{
Vector2 dir = (touch.position - leftStickTouchStartPos).normalized;
direction = new Vector3(dir.x, 0f, dir.y);
}
if (joystickLeftToch.fingerId == touch.fingerId && touch.phase == UnityEngine.TouchPhase.Ended)
{
direction = Vector3.zero;
hasLeftStick = false ;
}
if(lookFinger.fingerId == touch.fingerId && touch.phase == UnityEngine.TouchPhase.Moved)
{
look = touch.deltaPosition;
thridPersonCam.m_XAxis.m_InputAxisValue = look.x;
thridPersonCam.m_YAxis.m_InputAxisValue = look.y;
}
if (lookFinger.fingerId == touch.fingerId && touch.phase == UnityEngine.TouchPhase.Ended)
{
look = Vector2.zero;
thridPersonCam.m_XAxis.m_InputAxisValue = 0f;
thridPersonCam.m_YAxis.m_InputAxisValue = 0f;
hasRightStick = false;
}
}
if (Input.touchCount == 0)
{
lookFinger.fingerId = -1;
joystickLeftToch.fingerId = -1;
}
}

Swift animation doesn't update during while loop

I am new to Swift. I am trying to animate an object within a while loop, but the screen doesn't update until after the while loop is completed. If I run the function that the while loop is in by repeatedly clicking a button, it does work, but I want it run on its own. I have tried loading the screen every loop, but it didn't work.
func moveBall() {
while loopnumb <= 100 {
loopnumb += 1
print("animation loop cycled \(loopnumb) times")
print("inside of moveball() before startanimation, scratchX is \(scratchX), scratchY is \(scratchY), and the direction is \(direction).")
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .linear) {
self.direckEffeck()
self.scratch.frame = CGRect(x: self.scratchX, y: self.scratchY, width: 240, height: 128)
print("after and inside of animation command, scratchX is \(self.scratchX), scratchY is \(self.scratchY), and the direction is \(self.direction).")
}
animator.startAnimation()
if checkForOOBX() == true && checkForOOBY() == false {
direckCheckX()
}
if checkForOOBY() == true && checkForOOBX() == false {
direckCheckY()
}
if checkForOOBX() == true && checkForOOBY() == true {
if direction == 0 && done == false {
direction = 2
done = true
}
if direction == 1 && done == false {
direction = 3
done = true
}
if direction == 2 && done == false {
direction = 0
done = true
}
if direction == 3 && done == false {
direction = 1
done = true
}
cornerTouches += 1
print("ebic win, gamer's! the amount of corner touches is \(cornerTouches)")
}
done = false
DispatchQueue.main.async() {
self.scratch.setNeedsDisplay()
}
}
loopnumb = 0
}
Note that the object I am trying to move is called "scratch", and its coordinates are scratchX, scratchY. Thank you in advance.

touchCount difficulty on Android

This could be because I've been testing on a UnityRemote, however I'm trying to restart my main scene by touching with more than one finger on an android. endCondition is a variable I set as active when the player has been destroyed. Here is what my code looks like. All I want to do is restart the scene with multi-touch. Neither of the prints logged to the console so I doubt the multiple touches are being recognized. Here is my code that is inside of Update()
if (endCondition && (Input.touchCount > 1))
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch t = Input.GetTouch(i);
if (t.phase == TouchPhase.Began)
{
print("Made it here");
}
if (t.phase == TouchPhase.Ended)
{
print("Made it here");
SceneManager.LoadScene("Main");
}
}
}
This should fix it:
if (endCondition)
{
int fingersAmount = Input.touchCount;
//1 FINGER
if (fingersAmount == 1)
{
Touch t = Input.GetTouch(fingersAmount - 1);
if (t.phase == TouchPhase.Began)
{
Debug.Log("ONE FINGER");
}
if (t.phase == TouchPhase.Ended)
{
Debug.Log("ONE FINGER END");
//SceneManager.LoadScene("Main");
}
}
//2 FINGERS
else if (fingersAmount == 2)
{
Touch t = Input.GetTouch(fingersAmount - 1);
if (t.phase == TouchPhase.Began)
{
Debug.Log("TWO FINGERS");
}
if (t.phase == TouchPhase.Ended)
{
Debug.Log("TWO FINGERS END");
//SceneManager.LoadScene("Main");
}
}
//3 FINGERS
else if (fingersAmount == 3)
{
Touch t = Input.GetTouch(fingersAmount - 1);
if (t.phase == TouchPhase.Began)
{
Debug.Log("THREE FINGERS");
}
if (t.phase == TouchPhase.Ended)
{
Debug.Log("THREE FINGERS END");
//SceneManager.LoadScene("Main");
}
}
}

Drag and drop in unity 2d

I am trying to implement drag and drop functionality for my game in unity 2d. I have multiple copies of same object in my screen and they differ only by collider name. I attached the same script to them. Here is a piece of my code
function Start () {
playerTouches = [-1, -1];
}
function resetPlayer(touchNumber: int) {
for(var i = 0; i < playerTouches.length; ++i) {
if(touchNumber == playerTouches[i]) {
playerTouches[i] = -1;
}
}
}
function getCollider(vec: Vector2) {
var ray : Ray = Camera.main.ScreenPointToRay(vec);
var hit : RaycastHit2D = Physics2D.Raycast(ray.origin, ray.direction);
if (hit) {
if (hit.collider != null) {
Debug.Log(hit.collider.name);
return hit.collider.name;
} else {
Debug.Log("is null");
return "null";
}
} else {
Debug.Log("empty");
return "";
}
return "";
}
function processTouch(touch: Touch, touchNumber: int) {
if(touch.phase == TouchPhase.Began) {
var colliderName: String = getCollider(touch.position);
if(colliderName == "Object01" && playerTouches[0] == -1) {
playerTouches[0] = touchNumber;
} else if(colliderName == "Object02" && playerTouches[1] == -1) {
playerTouches[1] = touchNumber;
}
} else if(touch.phase == TouchPhase.Moved) {
// get object and change coords
} else if(touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) {
resetPlayer(touchNumber);
}
}
function Update() {
if(Input.touchCount > 0) {
//Debug.Log("count = " + Input.touchCount);
for(var i = 0; i < Input.touchCount; i++)
{
processTouch(Input.GetTouch(i), i);
//Debug.Log("touch : " + i + " " + Input.GetTouch(i).position);
}
}
}
For now I'm detecting on which object user touch. I need to be able to get that object and change it's position.
I also found this code snippet which allows to move rigidbody
var touchDeltaPosition: Vector2 = touch.deltaPosition;
var touchPosition: Vector2;
touchPosition.Set(touchDeltaPosition.x, touchDeltaPosition.y);
rigidbody2D.transform.position = Vector2.Lerp(transform.position, touchPosition, Time.deltaTime * spd);
but it moves all objects regardless of what object I select.
Well, you can do like this. If you have 12 copies of same object and want to move the object which selected by user. So when user Touches the object Change that GameObject tag or Name to another tag. Afterward you can use the some Conditional Statement to work with your code.
Example :
if(Input.GetMouseButtonDown(0)) {
Debug.Log("Mouse is down");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo = new RaycastHit();
//bool hit = Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hitInfo);
if(Physics.Raycast(ray, out hitInfo, 30)) {
Debug.Log("Hit " + hitInfo.transform.gameObject.name);
if(hitInfo.transform.gameObject.tag == "Deselected") {
//Debug.Log ("It's working! Attaching MoveCube Script to game :" + hitInfo.transform.gameObject.tag);
findObject = GameObject.FindGameObjectsWithTag("Deselected");
foreach(GameObject go in findObject) {
//go.gameObject.renderer.material.color = Color.white;
go.GetComponent<MoveCube>().enabled = false;
if(hitInfo.transform.gameObject.name.Equals(go.gameObject.name)) {
//hitInfo.transform.renderer.material.color = Color.white;
hitInfo.transform.gameObject.GetComponent<MoveCube>().enabled = true;
changeTAG = true;
} else {
hitInfo.transform.gameObject.tag = "Deselected"
}
}
playerObject = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject game in playerObject) {
count++;
if(count == 1) {
hitInfo.transform.gameObject.tag = "Player";
}
if(count >= 1) {
game.gameObject.tag = "Deselected";
game.gameObject.GetComponent<MoveCube>().enabled = false;
//game.gameObject.renderer.material.color = Color.white;
}
}
if(changeTAG) {
hitInfo.transform.gameObject.tag = "Player";
/*if (hitInfo.transform.gameObject.GetComponent<Rigidbody> ()) {
Debug.Log ("RigidBody is already added Can't add another RigidBody");
hitInfo.transform.rigidbody.WakeUp ();
} else {
hitInfo.transform.gameObject.AddComponent<Rigidbody> ().useGravity = false;
// hitInfo.transform.gameObject.GetComponent<Rigidbody> ().WakeUp ();
}*/
changeTAG = false;
} else if(!changeTAG) {
hitInfo.transform.gameObject.tag = "Deselected";
}
} else {
Debug.Log("Not Working");
}
} else {
Debug.Log("No hit");
}
Debug.Log("Mouse is down");
}
The above code is for Change the tag for selected and deselected cube. After that you can easily identify the Selected gameObject and can move it where ever you want.
You can use this code in the Update function.

Limiting JASidePanel Center panel slide

Hi I am using JASidePanels to create the left menu style but I want to do some particular changes.
The first is that I want the menu to have only 115 px wide. And for that I have found:
self.leftFixedWidth = 115;
Ok but, I can still slide the center panel to the right and see whats "hidden". Is there a way to fix its maximum position at 115 px? Just like the facebook menu?
go to JASidePanelController.m
find - (CGFloat)_correctMovement:(CGFloat)movement; method, replace it with this:
- (CGFloat)_correctMovement:(CGFloat)movement {
CGFloat position = _centerPanelRestingFrame.origin.x + movement;
if (self.state == JASidePanelCenterVisible) {
if (self.state != JASidePanelLeftVisible) {
if (position >= self.leftVisibleWidth) {
return self.leftVisibleWidth;
}
}
else if ((position > 0.0f && !self.leftPanel) || (position < 0.0f && !self.rightPanel)) {
return 0.0f;
}
} else if (self.state == JASidePanelRightVisible && !self.allowRightOverpan) {
if ((position + _centerPanelRestingFrame.size.width) < (self.rightPanelContainer.frame.size.width - self.rightVisibleWidth)) {
return 0.0f;
} else if (position > self.rightPanelContainer.frame.origin.x) {
return self.rightPanelContainer.frame.origin.x - _centerPanelRestingFrame.origin.x;
}
} else if (self.state == JASidePanelLeftVisible && !self.allowLeftOverpan) {
if (position > self.leftVisibleWidth) {
return 0.0f;
} else if (position < self.leftPanelContainer.frame.origin.x) {
return self.leftPanelContainer.frame.origin.x - _centerPanelRestingFrame.origin.x;
}
}
return movement;
}