I'm developing a mobile android game in Unity, and I have a menu panel that slides in from the right, using animation, when a button is clicked. Now I want to trigger the button to be clicked when the player swipes left. Basically I want to "click the menu button" when I swipe left on the screen without actually touching the button. This way it would trigger the animation and all other function of the button. Is it possible to achieve that? This is my script for the swipe detection:
//Swipe
private bool tap, swipeLeft, swipeRight, swipeUp, swipeDown;
private bool isDraging = false;
private Vector2 startTouch, swipeDelta;
private void Update()
{
tap = swipeLeft = swipeRight = swipeUp = swipeDown = false;
if (Input.touches.Length > 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
isDraging = true;
tap = true;
startTouch = Input.touches[0].position;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
isDraging = false;
Reset();
}
}
//Calculate Distance
swipeDelta = Vector2.zero;
if (isDraging)
{
if (Input.touches.Length > 0)
{
swipeDelta = Input.touches[0].position - startTouch;
}
}
if (swipeDelta.magnitude > 125)
{
float x = swipeDelta.x;
float y = swipeDelta.y;
if (Mathf.Abs(x) > Mathf.Abs(y))
{
//Left Or Right
if (x < 0)
{
swipeLeft = true;
}
else
{
swipeRight = true;
}
}
else
{
if (y < 0)
{
swipeDown = true;
}
else
{
swipeUp = true;
}
}
Reset();
}
}
private void Reset()
{
startTouch = Vector2.zero;
isDraging = false;
}
public Vector2 SwipeDelta { get { return swipeDelta; } }
public bool SwipeLeft { get { return swipeLeft; } }
public bool SwipeRight { get { return swipeRight; } }
public bool SwipeUp { get { return swipeUp; } }
public bool SwipeDown { get { return swipeDown; } }
How can I achieve my idea and how to implement it to my game?
Related
I want to make my element move until it hits something when i swipe.
I got following Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System;
public class PlayerController : MonoBehaviour
{
IEnumerator OnSwipeUp()
{
if(!isCurrentlyColliding)
{
transform.Translate(0,0.5f,0);
yield return null;
}else{
StopCoroutine(OnSwipeUp());
}
}
IEnumerator OnSwipeDown()
{
if(!isCurrentlyColliding)
{
transform.Translate(0,-0.5f,0);
yield return null;
}else{
StopCoroutine(OnSwipeUp());
}
}
IEnumerator OnSwipeLeft()
{
if(!isCurrentlyColliding)
{
transform.Translate(-0.5f,0,0);
yield return null;
}else{
StopCoroutine(OnSwipeUp());
}
}
IEnumerator OnSwipeRight()
{
if(!isCurrentlyColliding)
{
transform.Translate(0.5f,0,0);
yield return null;
}else{
StopCoroutine(OnSwipeUp());
}
}
bool isCurrentlyColliding = false;
void OnCollisionEnter2D(Collision2D col) {
isCurrentlyColliding = true;
}
void OnCollisionExit2D(Collision2D col) {
isCurrentlyColliding = false;
}
float verticalMove()
{
return Mathf.Abs(fingerDown.y - fingerUp.y);
}
float horizontalValMove()
{
return Mathf.Abs(fingerDown.x - fingerUp.x);
}
private Vector2 fingerDown;
private Vector2 fingerUp;
public float SWIPE_THRESHOLD = 20f;
void checkSwipe()
{
//Check if Vertical swipe
if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
{
//Debug.Log("Vertical");
if (fingerDown.y - fingerUp.y > 0)//up swipe
{
StartCoroutine(OnSwipeUp());
}
else if (fingerDown.y - fingerUp.y < 0)//Down swipe
{
StartCoroutine(OnSwipeDown());
}
fingerUp = fingerDown;
}
//Check if Horizontal swipe
else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
{
//Debug.Log("Horizontal");
if (fingerDown.x - fingerUp.x > 0)//Right swipe
{
StartCoroutine(OnSwipeRight());
}
else if (fingerDown.x - fingerUp.x < 0)//Left swipe
{
StartCoroutine(OnSwipeLeft());
}
fingerUp = fingerDown;
}
//No Movement at-all
else
{
//Debug.Log("No Swipe!");
}
}
// Update is called once per frame
void Update()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerUp = touch.position;
fingerDown = touch.position;
}
if (touch.phase == TouchPhase.Ended)
{
fingerDown = touch.position;
checkSwipe();
}
}
}
}
But it only moves one "Field" and it also doesn't stop if it collides with something. My Player has a 2D Box Collider and my Walls too. Do i need a Rigidbody or what? I used coroutines so it could check if it collides. Before i had while loops which stopped the code from executing further. I would be happy if you could help me.
My game is an endless runner and the character only needs to move along the y-axis. What I want to happen is that the player moves up or down depending on the swipe, and I thought that I could do it by stating that if the player triggered the onSwipeUp or down then they would move in that direction, but I couldn't get it working.
This is the player controller script before I tried implementing swipe controls into it:
public class Player : MonoBehaviour
{
private Vector2 targetPos;
public float yIncrement;
public float maxHeight;
public float minHeight;
private void Update()
{
transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.W) && transform.position.y < maxHeight)
{
Instantiate(effect, transform.position, Quaternion.identity);
targetPos = new Vector2(transform.position.x, transform.position.y + yIncrement);
}
else if (Input.GetKeyDown(KeyCode.S) && transform.position.y > minHeight)
{
Instantiate(effect, transform.position, Quaternion.identity);
targetPos = new Vector2(transform.position.x, transform.position.y - yIncrement);
}
}
And this is the swipe detecting script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwipeTest : MonoBehaviour
{
private Vector2 fingerDown;
private Vector2 fingerUp;
public bool detectSwipeOnlyAfterRelease = false;
public float SWIPE_THRESHOLD = 20f;
// Update is called once per frame
void Update()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerUp = touch.position;
fingerDown = touch.position;
}
//Detects Swipe while finger is still moving
if (touch.phase == TouchPhase.Moved)
{
if (!detectSwipeOnlyAfterRelease)
{
fingerDown = touch.position;
checkSwipe();
}
}
//Detects swipe after finger is released
if (touch.phase == TouchPhase.Ended)
{
fingerDown = touch.position;
checkSwipe();
}
}
}
void checkSwipe()
{
//Check if Vertical swipe
if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
{
//Debug.Log("Vertical");
if (fingerDown.y - fingerUp.y > 0)//up swipe
{
OnSwipeUp();
}
else if (fingerDown.y - fingerUp.y < 0)//Down swipe
{
OnSwipeDown();
}
fingerUp = fingerDown;
}
//Check if Horizontal swipe
else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
{
//Debug.Log("Horizontal");
if (fingerDown.x - fingerUp.x > 0)//Right swipe
{
OnSwipeRight();
}
else if (fingerDown.x - fingerUp.x < 0)//Left swipe
{
OnSwipeLeft();
}
fingerUp = fingerDown;
}
//No Movement at-all
else
{
//Debug.Log("No Swipe!");
}
}
float verticalMove()
{
return Mathf.Abs(fingerDown.y - fingerUp.y);
}
float horizontalValMove()
{
return Mathf.Abs(fingerDown.x - fingerUp.x);
}
//////////////////////////////////CALLBACK FUNCTIONS/////////////////////////////
public void OnSwipeUp()
{
Debug.Log("Swipe UP");
}
public void OnSwipeDown()
{
Debug.Log("Swipe Down");
}
void OnSwipeLeft()
{
Debug.Log("Swipe Left");
}
void OnSwipeRight()
{
Debug.Log("Swipe Right");
}
}
You could set a public boolean for each swipe direction. In the first lines of update set these booleans to false, in the onswipe functions set the respective booleans to true. Then reference the swipetest script from the player script and check if the desired swipe boolean is set to true.
The code would look something like this:
player:
public class Player : MonoBehaviour
{
private Vector2 targetPos;
public float yIncrement;
public float maxHeight;
public float minHeight;
public SwipeTest swipetest;
private void OnEnable()
{
swipetest = (SwipeTest)FindObjectOfType(typeof(SwipeTest));
}
private void Update()
{
transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
if (swipetest.swipeUp && transform.position.y < maxHeight)
{
Instantiate(effect, transform.position, Quaternion.identity);
targetPos = new Vector2(transform.position.x, transform.position.y + yIncrement);
}
else if (swipetest.swipeDown && transform.position.y > minHeight)
{
Instantiate(effect, transform.position, Quaternion.identity);
targetPos = new Vector2(transform.position.x, transform.position.y - yIncrement);
}
}
swipetest
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwipeTest : MonoBehaviour
{
private Vector2 fingerDown;
private Vector2 fingerUp;
public bool detectSwipeOnlyAfterRelease = false;
public float SWIPE_THRESHOLD = 20f;
public bool swipeUp = false;
public bool swipeDown = false;
public bool swipeLeft = false;
public bool swipeRight = false;
// Update is called once per frame
void Update()
{
swipeUp = false;
swipeDown = false;
swipeLeft = false;
swipeRight = false;
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerUp = touch.position;
fingerDown = touch.position;
}
//Detects Swipe while finger is still moving
if (touch.phase == TouchPhase.Moved)
{
if (!detectSwipeOnlyAfterRelease)
{
fingerDown = touch.position;
checkSwipe();
}
}
//Detects swipe after finger is released
if (touch.phase == TouchPhase.Ended)
{
fingerDown = touch.position;
checkSwipe();
}
}
}
void checkSwipe()
{
//Check if Vertical swipe
if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
{
//Debug.Log("Vertical");
if (fingerDown.y - fingerUp.y > 0)//up swipe
{
OnSwipeUp();
}
else if (fingerDown.y - fingerUp.y < 0)//Down swipe
{
OnSwipeDown();
}
fingerUp = fingerDown;
}
//Check if Horizontal swipe
else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
{
//Debug.Log("Horizontal");
if (fingerDown.x - fingerUp.x > 0)//Right swipe
{
OnSwipeRight();
}
else if (fingerDown.x - fingerUp.x < 0)//Left swipe
{
OnSwipeLeft();
}
fingerUp = fingerDown;
}
//No Movement at-all
else
{
//Debug.Log("No Swipe!");
}
}
float verticalMove()
{
return Mathf.Abs(fingerDown.y - fingerUp.y);
}
float horizontalValMove()
{
return Mathf.Abs(fingerDown.x - fingerUp.x);
}
//////////////////////////////////CALLBACK FUNCTIONS/////////////////////////////
public void OnSwipeUp()
{
swipeUp = true;
}
public void OnSwipeDown()
{
swipeDown = true;
}
void OnSwipeLeft()
{
swipeLeft = true;
}
void OnSwipeRight()
{
swipeRight = true;
}
}
I've been dealing with this problem (that started happening for no reason) for the past 3 days, and with deadlines tightening, it's driving me crazy.
So the gist is, the player presses a button, and the camera moves to a location and unlocks the mouse, so the player can click on the interactable (in this case, a diary).
What I've done to try and fix this:
-Created development build, no errors, and nothing in the output.log
-Reimported all the assets
-Started a new project and imported the assets there
-Upgraded from Unity 2018.1 to 2018.3
-Removed the script and attached it again
-Built for different systems
-Restarted Unity and my PC
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiaryController : MonoBehaviour
{
public Camera mainCam;
public float moveSpeed = 10.0f;
public GameObject cameraObject;
public GameObject targetObject;
private bool movingTowardsTarget = false;
private float lerpSpeed = 0.225f;
public Transform fromRot;
public Transform toRot;
private bool inPosition = false;
public bool onSwitch = false;
public bool freezecamera = false;
public bool freezeplayer = false;
public WheelchairController Mov;
public bool EPressed = false;
public GameObject Crosshair;
public MouseControl myMouseScript;
private bool onDiary = false;
void Start()
{
onDiary = false;
mainCam = Camera.main;
}
// Update is called once per frame
void Update()
{
FreezeCamera();//Checks if the camera has been frozen
FreezePlayer();//Checks if the player has been frozen
if (onSwitch && Input.GetKeyDown(KeyCode.E))
{
CheckPlayer();
EPressed = true;
}
if (onSwitch && movingTowardsTarget)
{
GoToDiary();
Crosshair.SetActive(false);
}
else if (onSwitch && !movingTowardsTarget && EPressed)
{
GoToChair();
Crosshair.SetActive(true);
}
}
void CheckPlayer()
{
if (movingTowardsTarget)
{
movingTowardsTarget = false;
freezecamera = false;
}
else
{
fromRot = fromRot.transform;
toRot = toRot.transform;
// freezecamera = true;
freezeplayer = true;
movingTowardsTarget = true;
}
}
void GoToDiary()
{
StartCoroutine(DelayFreeze());
MoveTowardsTarget(targetObject);
Cursor.visible = true;
Cursor.lockState = CursorLockMode.Confined;
Crosshair.SetActive(false);
freezecamera = true;
freezeplayer = true;
onDiary = true;
}
void GoToChair()
{
StartCoroutine(DelayMov());
MoveTowardsTarget(cameraObject);
freezecamera = false;
Cursor.lockState = CursorLockMode.Locked;
Crosshair.SetActive(true);
onDiary = false;
}
IEnumerator DelayMov()
{
Debug.Log("DelayActivated");
yield return new WaitForSeconds(2);
freezeplayer = false;
}
IEnumerator DelayFreeze()
{
if (!freezeplayer)
{
Debug.Log("DelayActivated");
yield return new WaitForSeconds(1);
freezeplayer = true;
}
}
void MoveTowardsTarget(GameObject target)
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, moveSpeed * Time.deltaTime);
transform.rotation = target.transform.rotation;
if (Vector3.Distance(transform.position, target.transform.position) < 0.1)
{
inPosition = true;
Debug.Log("InPosition");
if (inPosition)
{
transform.rotation = target.transform.rotation;
if (Mathf.Abs(fromRot.localEulerAngles.y - toRot.localEulerAngles.y) < 3)
{
transform.rotation = target.transform.rotation;
//movingTowardsTarget = false;
inPosition = false;
Debug.Log("RotatingCamera");
}
}
else
{
transform.rotation = Quaternion.Lerp(fromRot.rotation, toRot.rotation, Time.time * lerpSpeed);
Debug.Log("RotatingCamera2");
}
}
}
void FreezeCamera()
{
if (freezecamera)
{
Debug.Log("CameraFrozen");
myMouseScript.rotationSpeed = 0.0f;
// MouseControl.mouseLookEnabled = false;
ZoomIn.zoomEnable = false;
Crosshair.SetActive(false);
}
else if (!freezecamera)
{
myMouseScript.rotationSpeed = 0.5f;
//MouseControl.mouseLookEnabled = true;
//ZoomIn.zoomEnable = true;
//Crosshair.SetActive(true);
}
}
void FreezePlayer()
{
if (freezeplayer)
{
Debug.Log("PlayerFrozen");
Mov.moveSpeed = 0.0f;
Mov.turnSpeed = 0.0f;
Mov.freeze = true;
}
else if (!freezeplayer)
{
Mov.moveSpeed = 0.4f;
Mov.turnSpeed = 2.5f;
Mov.freeze = false;
}
}
void OnGUI()
{
if (onSwitch)
{
if (!freezeplayer)
{
GUI.Box(new Rect(0, 0, 200, 20), "Press E to open diary");
}
else
{
GUI.Box(new Rect(0, 0, 200, 20), "Press E to close diary");
}
}
}
}
Here's how it behaves in the editor:
https://i.gyazo.com/4570740f027b736789ed1ab13488bf44.gif
Here's how it behaves in the build:
https://i.gyazo.com/6f1b0485855c24c81abb2278f4361a36.gif
I am practicing in Unity; I want to move an object to the right and left according to how I swipe. I have gotten the script so far but the problem occurs when I am playing it. It is setting the objects location to the center; swipe actions are working just fine. However, I don't want it to set the object to the center.
Script:
public class swipeTest : MonoBehaviour {
public SwipeManager swipeControls;
public Transform Player;
private Vector3 desiredPosition;
private void Update() {
if (swipeControls.SwipeLeft)
desiredPosition += Vector3.left;
if (swipeControls.SwipeRight)
desiredPosition += Vector3.right;
Player.transform.position = Vector3.MoveTowards
(Player.transform.position, desiredPosition, 0.5f * Time.deltaTime);
}
}
And Another
public class SwipeManager : MonoBehaviour {
private bool tap, swipeLeft, swipeRight, swipeUp, swipeDown;
private bool isDraging = false;
private Vector2 startTouch, swipeDelta;
public Vector2 SwipeDelta { get { return swipeDelta; } }
public bool Tap { get { return tap; } }
public bool SwipeLeft { get { return swipeLeft; } }
public bool SwipeRight { get { return swipeRight; } }
public bool SwipeUp { get { return swipeUp; } }
public bool SwipeDown { get { return swipeDown; } }
private void Update() {
tap = swipeLeft = swipeRight = swipeUp = swipeDown = false;
#region Standalone Inputs
if (Input.GetMouseButtonDown(0)) {
tap = true;
isDraging = true;
startTouch = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(0)) {
isDraging = false;
Reset();
}
#endregion
#region Mobile Input
if (Input.touches.Length > 0) {
if (Input.touches[0].phase == TouchPhase.Began) {
isDraging = true;
tap = true;
startTouch = Input.touches[0].position;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled) {
isDraging = false;
Reset();
}
}
#endregion
// Calculate the distance
swipeDelta = Vector2.zero;
if (isDraging) {
if (Input.touches.Length > 0)
swipeDelta = Input.touches[0].position - startTouch;
else if (Input.GetMouseButton(0))
swipeDelta = (Vector2)Input.mousePosition - startTouch;
}
//Did we cross the distance?
if (swipeDelta.magnitude > 125) {
//Which direction?
float x = swipeDelta.x;
float y = swipeDelta.y;
if (Mathf.Abs(x) > Mathf.Abs(y)) {
//Left or right
if (x < 0)
swipeLeft = true;
else
swipeRight = true;
}
else {
// Up or down
if (y < 0)
swipeDown = true;
else
swipeUp = true;
}
Reset();
}
}
void Reset() {
startTouch = swipeDelta = Vector2.zero;
isDraging = false;
}
}
It seems like you never initialised desiredPosition in your code.
I did not successfully reproduce your issue, but theoretically I believe this should work. Please let us know if it helped.
Assuming no other forces act on the Player tranform (it won't be moved other than by this script):
public class swipeTest : MonoBehaviour {
private void Start() {
desiredPosition = Player.position;
}
}
Or if other forces act on Player you should update it every time:
public class swipeTest : MonoBehaviour {
private void Update() {
desiredPosition = Player.position;
if (swipeControls.SwipeLeft)
desiredPosition += Vector3.left;
if (swipeControls.SwipeRight)
desiredPosition += Vector3.right;
Player.transform.position = Vector3.MoveTowards
(Player.transform.position, desiredPosition, 0.5f * Time.deltaTime);
}
}
i already make the player character to move to it is destination (animate the character to move to that destination), i wanted to disable the GUI button when the player character is moving, but i can't get it and work it out. Could you guys help me?
Here is the code:
public class UserPlayer : Player
{
public override void TurnUpdate()
{
//Moving animation
if (positionQueue.Count > 0)
{
GUI.enabled = false; // This is the one that i want when the character still moving (animation still moving), disabled the GUI. But i can't get it
transform.position += (positionQueue[0] - transform.position).normalized * moveSpeed * Time.deltaTime;
if (Vector3.Distance(positionQueue[0], transform.position) <= 0.1f)
{
transform.position = positionQueue[0];
positionQueue.RemoveAt(0);
if (positionQueue.Count == 0)
{
actionPoints--;
}
}
}
base.TurnUpdate();
}
public override void TurnOnGUI()
{
base.TurnOnGUI();
}
}
public class Player : MonoBehaviour
{
//for movement animation
public List<Vector3> positionQueue = new List<Vector3>();
public virtual void TurnUpdate()
{
if (actionPoints <= 0)
{
actionPoints = 2;
magicAttacking = false;
moving = false;
attacking = false;
GameManager.instance.NextTurn();
}
}
public virtual void TurnOnGUI()
{
if (GameManager.instance.currentPlayerIndex == 0 || GameManager.instance.currentPlayerIndex == 2)
{
//ToolTip Text
move = GUI.Button(buttonRect, new GUIContent("Move", "Move the Player"));
GUI.Label(tooltipRect, GUI.tooltip, label1);
GUI.tooltip = null;
//Move Button
if (move)
{
if (!moving)
{
GameManager.instance.RemoveTileHighlights();
moving = true;
attacking = false;
GameManager.instance.HighlightTilesAt(gridPosition, Color.blue, movementPerActionPoint);
}
else
{
moving = false;
attacking = false;
GameManager.instance.RemoveTileHighlights();
}
}
}
Your question has been already made, take a look here.
Adapt your code in this way:
public virtual void TurnOnGUI() {
if (GameManager.instance.currentPlayerIndex == 0 || GameManager.instance.currentPlayerIndex == 2) {
...
if(!moving) {
move = GUI.Button(buttonRect, new GUIContent("Move", "Move the Player"));
GUI.Label(tooltipRect, GUI.tooltip, label1);
}
...
}
}