- Home /
Problems at using touch and buttons inputs,Problems at using touch input on Android
Game description:
The game is a kind of “one tower defense” game, with “only” the tower in the middle of the game defending itself against the incoming opponents on the corresponding lanes. The tower is controlled directly by the player and shoots with his weapons in the direction where the player clicks.
See game screenshot:
Thus, the user controls the actions by touch. This game should (only) appear "for now" for Android. I implemented the control for the tower and for the buttons in a corresponding class for Android "GetTouch" and for simulation on the PC with a click of the mouse.
See code:
public class Controls : MonoBehaviour {
public Transform tower;
private bool aiming = false;
private TowerWeaponSystems towerWeaponSystems;
private Transform target;
public enum Mode {
Default,
Laser,
Missile
}
public Mode mode = Mode.Default;
void Start () {
towerWeaponSystems = tower.GetComponent<TowerWeaponSystems>();
target = GameObject.Find("#GlobalObjects").transform.Find("Target");
towerWeaponSystems.MachineGun.target = target;
if (towerWeaponSystems.LaserGun != null) {
towerWeaponSystems.LaserGun.target = target;
}
if (towerWeaponSystems.MissileLauncher != null) {
towerWeaponSystems.MissileLauncher.defaultTarget = target;
}
}
void FixedUpdate () {
#if UNITY_IPHONE
...
}
#elif UNITY_ANDROID
for (int i = 0; i < Input.touchCount; ++i) {
// Construct a ray from the current touch coordinates
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
// Create a particle if hit
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
HandleTouch(hit.collider.gameObject, 10, hit.point, Input.GetTouch(i).phase);
}
}
#else
// Simulate touch events from mouse events
if (Input.touchCount == 0) {
Vector3 mousePosition = Input.mousePosition;
Ray screenRay = Camera.main.ScreenPointToRay(mousePosition);
RaycastHit hit;
if (Physics.Raycast(screenRay, out hit, Mathf.Infinity)) {
if (Input.GetMouseButtonDown(0) ) {
HandleTouch(hit.collider.gameObject, 10, hit.point, TouchPhase.Began);
}
if (Input.GetMouseButton(0) ) {
HandleTouch(hit.collider.gameObject, 10, hit.point, TouchPhase.Moved);
}
if (Input.GetMouseButtonUp(0) ) {
HandleTouch(hit.collider.gameObject, 10, hit.point, TouchPhase.Ended);
}
}
}
#endif
if (GC.settingsProvider.GetPerpetualFire())
{
shoot();
}
}
private void HandleTouch(GameObject target, int touchFingerId, Vector3 touchPosition, TouchPhase touchPhase) {
if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) {
return;
}
if (target.GetComponent<Button>() != null) {
return;
}
switch (touchPhase) {
case TouchPhase.Began:
aiming = false;
// If an item was clicked, pick it up.
if(target.CompareTag("Item")) {
var itemComponent = target.GetComponent<Item>();
if (itemComponent != null) {
itemComponent.PickUp();
}
}
// Otherwise use weapon according to mode.
else if (mode == Mode.Missile) {
towerWeaponSystems.MissileLauncher.shoot(touchPosition);
mode = Mode.Default;
}
else {
aiming = true;
this.target.position = touchPosition;
}
break;
case TouchPhase.Moved:
if (aiming) {
this.target.position = touchPosition;
}
break;
case TouchPhase.Ended:
if (mode == Mode.Laser) {
mode = Mode.Default;
}
break;
}
shoot();
}
Now to my two problems.
1st problem:
Use case: A user clicks the InGame button to use the missile (one of the buttons at the bottom left). Then the (entire) tower with its weapon system turns in the direction of the InGame buttons.
Requirement: The tower should not turn in the direction of the InGame buttons, but should stay where it was. For mouse control, the requirement also works that the tower does NOT turn in the direction when the player has clicked one of the buttons. The whole thing just doesn't work for the touch! What could be wrong with the (Android) code?
2nd problem:
Error description: By repeated, different and simultaneous clicking of the InGame weapon system buttons the weapon systems are NOT deactivated. Assumption: The user touched the laser weapon for at least 2 seconds without letting go on the InGame playing field. The player then leaves the screen with his finger. So the laser is not deactivated when the player leaves the screen (touch). The error occurs very rarely. Unfortunately I cannot reproduce this error 100%. Perhaps someone can recognize from the code how one of these errors can occur.
Requirement: The weapon system (the laser or the gun) must deactivate again when you leave the screen.
Answer by MenaceLio · Feb 04, 2020 at 11:42 AM
It seems to be a problem with line: if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()). But also if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(touchFingerId)) or if(EventSystem.current.IsPointerOverGameObject(Input.touches[0].fingerId) is for "fingerId" = 0 while touching. Has someone a solution?