Detect Swipe Even the Finger Hasn't been Released - c#

I want to detect the mouse swipe up and swipe down, I tried the script below but it only works:
1 - if the finger has been released between any two swipes.
2 - if the finger hasn't been released, but only if the second swipe has exceed the original finger position (firstPressPos).
What I want exactly is:
For example, I put my finger on the screen and I swipe down, then after I swipe up (without releasing the finger between the two swipes), I want to detect the two swipes in the real time.
How can I do that?
Script:
if (Input.GetMouseButtonDown(0))
{
firstPressPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
}
if (Input.GetMouseButton(0))
{
secondPressPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
currentSwipe.Normalize();
if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
//Swipe Up
}
if (currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
//Swipe Down
}
}

You need to add a couple of flags to know which swipe status you're in if your are in one.
private bool _swiping;
private bool _swipingDown;
private Vector3 _previousSwipePosition;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
_previousSwipePosition = Input.mousePosition;
_swiping = true;
Debug.log("Started Swipe");
}
else if (Input.GetMouseButtonUp(0))
{
_swiping = false;
Debug.log("Finished Swipe");
}
if (_swiping)
{
Vector3 newPosition = Input.mousePosition;
if (newPosition.y < _previousSwipePosition.y)
{
if (!_swipingDown)
{
Debug.Log("Started Swipe Down");
_swipingDown = true;
}
}
if (newPosition.y> _previousSwipePosition.y)
{
if (_swipingDown)
{
Debug.Log("Started Swipe Up");
_swipingDown = false;
}
}
_previousSwipePosition = newPosition;
}
}
This will let you know when a Swipe is Started, Finished and Changes direction using flags.
flags - booleans to signify something

Related

Swipe movement to a defined coordinate [duplicate]

That is my code to try and simulate a swipe gesture so when I build to mobile I know it will work. Nothing is being logged and I am confused on why it seems to not work. I want it to print out in the console that I either swiped RTL (Right to Left) or LTR (Left to right). I do not see what I am doing wrong.
void Update()
{
if (Input.GetMouseButtonDown(0))
{
startPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
if (Input.GetMouseButtonUp(0))
{
endPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
if (startPosition != endPosition && startPosition != Vector3.zero && endPosition != Vector3.zero)
{
float deltaX = endPosition.x - startPosition.x;
float deltaY = endPosition.y - startPosition.y;
if ((deltaX > 5.0f || deltaX < -5.0f) && (deltaY >= -1.0f || deltaY <= 1.0f))
{
if (startPosition.x < endPosition.x)
{
print("LTR");
}
else
{
print("RTL");
}
}
startPosition = endPosition = Vector3.zero;
}
}
I can spot some few problems in your code. It's not a good idea to compare Vector3 with == or !=. Approximate comparison is fine. You are using Input.GetMouseButtonDown on a mobile platform.
You need to use Input.touches to do this. Loop over it, store the beginning position in TouchPhase.Began and then the end position in TouchPhase.Ended. You can then use both variables to figure it which direction the finger went.
The code below detects swipe direction even when the finger is not yet released with the help of TouchPhase.Moved. You can disable that by enabling the detectSwipeOnlyAfterRelease boolean variable. You can also modify SWIPE_THRESHOLD for sensitivity.
public class SwipeDetector : 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/////////////////////////////
void OnSwipeUp()
{
Debug.Log("Swipe UP");
}
void OnSwipeDown()
{
Debug.Log("Swipe Down");
}
void OnSwipeLeft()
{
Debug.Log("Swipe Left");
}
void OnSwipeRight()
{
Debug.Log("Swipe Right");
}
}
Thanks to Programmer, I used his suggestion and wrote a small component which works both with mouse and touch. The mouse will allow you to debug app on PC. I also added time threshold in seconds, since swipe cannot be too long.
using System;
using UnityEngine;
using UnityEngine.Events;
public class SwipeManager : MonoBehaviour {
public float swipeThreshold = 50f;
public float timeThreshold = 0.3f;
public UnityEvent OnSwipeLeft;
public UnityEvent OnSwipeRight;
public UnityEvent OnSwipeUp;
public UnityEvent OnSwipeDown;
private Vector2 fingerDown;
private DateTime fingerDownTime;
private Vector2 fingerUp;
private DateTime fingerUpTime;
private void Update () {
if (Input.GetMouseButtonDown(0)) {
this.fingerDown = Input.mousePosition;
this.fingerUp = Input.mousePosition;
this.fingerDownTime = DateTime.Now;
}
if (Input.GetMouseButtonUp(0)) {
this.fingerDown = Input.mousePosition;
this.fingerUpTime = DateTime.Now;
this.CheckSwipe();
}
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
this.fingerDown = touch.position;
this.fingerUp = touch.position;
this.fingerDownTime = DateTime.Now;
}
if (touch.phase == TouchPhase.Ended) {
this.fingerDown = touch.position;
this.fingerUpTime = DateTime.Now;
this.CheckSwipe();
}
}
}
private void CheckSwipe() {
float duration = (float)this.fingerUpTime.Subtract(this.fingerDownTime).TotalSeconds;
if (duration > this.timeThreshold) return;
float deltaX = this.fingerDown.x - this.fingerUp.x;
if (Mathf.Abs(deltaX) > this.swipeThreshold) {
if (deltaX > 0) {
this.OnSwipeRight.Invoke();
//Debug.Log("right");
} else if (deltaX < 0) {
this.OnSwipeLeft.Invoke();
//Debug.Log("left");
}
}
float deltaY = fingerDown.y - fingerUp.y;
if (Mathf.Abs(deltaY) > this.swipeThreshold) {
if (deltaY > 0) {
this.OnSwipeUp.Invoke();
//Debug.Log("up");
} else if (deltaY < 0) {
this.OnSwipeDown.Invoke();
//Debug.Log("down");
}
}
this.fingerUp = this.fingerDown;
}
}
Modified Developper's approach for a more precise controller (and less code! =D ) :
using System;
using UnityEngine;
using UnityEngine.Events;
using Utilities;
public class SwipeManager : MonoBehaviour {
public float swipeThreshold = 40f;
public float timeThreshold = 0.3f;
public UnityEvent onSwipeLeft;
public UnityEvent onSwipeRight;
public UnityEvent onSwipeUp;
public UnityEvent onSwipeDown;
private Vector2 _fingerDown;
private DateTime _fingerDownTime;
private Vector2 _fingerUp;
private DateTime _fingerUpTime;
private void Update () {
if (Input.GetMouseButtonDown(0)) {
_fingerDown = Input.mousePosition;
_fingerUp = Input.mousePosition;
_fingerDownTime = DateTime.Now;
}
if (Input.GetMouseButtonUp(0)) {
_fingerDown = Input.mousePosition;
_fingerUpTime = DateTime.Now;
CheckSwipe();
}
foreach (var touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
_fingerDown = touch.position;
_fingerUp = touch.position;
_fingerDownTime = DateTime.Now;
}
if (touch.phase == TouchPhase.Ended) {
_fingerDown = touch.position;
_fingerUpTime = DateTime.Now;
CheckSwipe();
}
}
}
private void CheckSwipe() {
var duration = (float)_fingerUpTime.Subtract(_fingerDownTime).TotalSeconds;
var dirVector = _fingerUp - _fingerDown;
if (duration > timeThreshold) return;
if (dirVector.magnitude < swipeThreshold) return;
var direction = dirVector.Rotation(180f).Round();
print(direction);
if (direction >= 45 && direction < 135) onSwipeUp.Invoke();
else if (direction >= 135 && direction < 225) onSwipeRight.Invoke();
else if (direction >= 225 && direction < 315) onSwipeDown.Invoke();
else if (direction >= 315 && direction < 360 || direction >= 0 && direction < 45) onSwipeLeft.Invoke();
}
}
I searched for the same thing, and found it reasonable to create asset for easy swipe detection, and share it with community. So here it is on github. My solution supports different usecases, including: 8-directions swipe detection, 4-directions, 2-directions (left-right or up-down), swipes on hexagonal grid. All listed is included as a presets, but also you can configure it to detect any number of Vector3 directions. So ti`s really flexible. Also, you can try WebGL build or see video tutorial. If you try it, please, let me know (via youtube comment, or see Contacts section on github), was it suitable for your case, and was it comfortable enough.
Try this Out.
I hope this helps.
void Update(){
if (Input.GetMouseButtonDown(0)){
startPosition = Input.mousePosition;
}
if (Input.GetMouseButtonUp(0)){
float swipe = startPosition.x - Input.mousePosition.x;
}
if (swipe < 0)
{
print("LTR");
} else{
print("RTL");
}
}
}
}

How to delay movement in unity while animation plays

I am having difficulty delaying the movement of my character in Unity 2018.4, I suspect this is more of just a problem with my code as apposed to unity.
Edit:
I want to be able to hold down the right arrow key, have the character not move for 415ms, then be able to move for 580ms, after which he cannot move for 350ms (to let the animation finish playing)
I tried using countdown in a IE numerator to wait and then call my movement function but this results in my character not moving after the animation has played.
//What makes the character move, works fine if executed on its own in update
private void ExecuteMovement(float dir)
{
currentPosition = transform.position;
currentPosition.x += dir * Time.deltaTime * speed;
transform.position = currentPosition;
}
//Trying to use waitforseconds to delay the execution while the animation plays
private IEnumerator Movement(float dir)
{
yield return new WaitForSeconds(0.5f);
ExecuteMovement(dir);
}
void Update()
{
if (0 > Input.GetAxis("Horizontal"))
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 180, 0);
//starts animation
animator.SetBool("isSkipping", true);
//calls the movement function with the direction to move in
Movement(Input.GetAxis("Horizontal"));
}
else if (0 < Input.GetAxis("Horizontal"))
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 0, 0);
//starts animation
animator.SetBool("isSkipping", true);
//calls the movement function with the direction to move in
Movement(Input.GetAxis("Horizontal"));
}
}
I'm happy to try any alternatives to delaying movement of the character. The animation shows the character charging up to jump and then jumps. I want to only move while it is in the air which is approximately half a second into the animation.
You are trying to call your IEnumerator like a method.
Instead you have to start it as a Coroutine using StartCoroutine
StartCoroutine(Movement(Input.GetAxis("Horizontal")));
Saw your edit
I want to be able to hold down the right arrow key, have the character not move for 415ms, then be able to move for 580ms, after which he cannot move for 350ms (to let the animation finish playing)
until now so since you want a continues movement but still fully control the speed I would keep it in Update and use the coroutine only for controlling a flag. Coroutine is still way better to read/write and maintain. (Now it also allows direction switch midair .. not sure if you want this or not):
// control the ability to move with a simple flag
// instead of various states
public bool canMove;
// check if a jumping is already being animated/executed
// -> disallow a new jumping animation until it is finished
private bool canJump = true;
private void Update()
{
// avoid repeated API calls
var input = Input.GetAxis("Horizontal");
if (input < 0)
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 180, 0);
if(canJump)
{
//starts the movement
StartCoroutine(Jump());
}
}
else if (input > 0)
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 0, 0);
if(canJump)
{
//starts the movement
StartCoroutine(Jump());
}
}
// if can not move do nothing else
if(!canMove) return;
// execute the movement
transform.position += Vector3.right * input * speed * Time.deltaTime;
}
private IEnumerator Jump()
{
// disable jumping
canJump = false;
// disable move during animation
canMove = false;
//starts animation
animator.SetBool("isSkipping", true);
// not move for 415ms
yield return new WaitForSeconds(0.415f);
// enable move
canMove = true;
// be able to move for 580ms
yield return new WaitForSeconds(0.580f);
// disable move
canMove = false;
// cannot move for 350ms during end of animation
yield return new WaitForSeconds(0.350f);
// enable move again
canMove = true;
// re-enable jumping
canJump = true;
}
How about using timer in Update?
float timer = 0f;
void Update()
{
var dir = Input.GetAxis("Horizontal");
if (0 > dir)
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 180, 0);
//starts animation
animator.SetBool("isSkipping", true);
//calls the movement function with the direction to move in
timer +=Time.deltaTime;
if(timer >= 0.5){
ExecuteMovement(dir);
timer -=0.5f;
}
//Movement(Input.GetAxis("Horizontal"));
}
else if (0 < dir)
{
//This is to flip image
transform.eulerAngles = new Vector3(0, 0, 0);
//starts animation
animator.SetBool("isSkipping", true);
//calls the movement function with the direction to move in
timer +=Time.deltaTime;
if(timer >= 0.5){
ExecuteMovement(dir);
timer -=0.5f;
}
//Movement(Input.GetAxis("Horizontal"));
}
}
I found a rather crude way of making this work after heavily modifying Gray_Rhino's answer to this question. I set up 3 stages of my jump animation, when continually moving one direction a timer will check to see how far into the animation it is and decide whether or not to allow movement input. the timer resets after the animation is finished or the character is told to move in the other direction.
bool facingRight;
int jumpPhase = 1;
float timer = 0f;
float dir;
void Update()
{
if (jumpPhase != 3)
{
dir = Input.GetAxis("Horizontal");
}
if (0 > dir || (jumpPhase == 3 && facingRight == true))
{
timer += Time.deltaTime;
if (facingRight != true)
{
transform.eulerAngles = new Vector3(0, 180, 0);
jumpPhase = 1;
timer = 0f;
facingRight = true;
}
else if (jumpPhase == 1)
{
//starts animation
animator.SetBool("isSkipping", true);
if (timer >= 0.415f)
{
jumpPhase = 2;
}
}
else if (jumpPhase == 2)
{
ExecuteMovement(dir);
if (timer >= 0.995f)
{
jumpPhase = 3;
}
}
if (jumpPhase == 3)
{
if (timer >= 1.5f)
{
jumpPhase = 1;
timer = 0f;
}
}
}
else if (0 < dir || (jumpPhase == 3 && facingRight != true))
{
timer += Time.deltaTime;
if (facingRight == true)
{
transform.eulerAngles = new Vector3(0, 0, 0);
jumpPhase = 1;
timer = 0f;
facingRight = false;
}
else if (jumpPhase == 1)
{
//starts animation
animator.SetBool("isSkipping", true);
if (timer >= 0.415f)
{
jumpPhase = 2;
}
}
else if (jumpPhase == 2)
{
ExecuteMovement(dir);
if (timer >= 0.995f)
{
jumpPhase = 3;
}
}
if (jumpPhase == 3)
{
if (timer >= 1.5f)
{
jumpPhase = 1;
timer = 0f;
}
}
}
}

Playing animation with swipe controls and transform.position problem Unity

I've set up my swipe controls to transform my player left/right/up/down and I've restricted the movement on 3 lines; -1, 0, 1. Everything works fine but the movement is not smooth at all and the player seems to be "teleporting" from one position to another. I wanted to smooth the movement by playing the animation but the result was that the animation was being played after the player has changed his position.
Is there any way to play the animation while the player is changing his position or a way to smooth the movement so it looks right ?
I've tried everything and now I'm stuck with the problem, please help
Here's my code
public class SwipeControls : MonoBehaviour {
public float speed = 5.0f;
private Vector3 startpos; // start position
private Vector3 endpos; //end position
public int pozioma = 0;
public int pionowa = 0;
Animator anim;
void Start() {
GetComponent<Animator>();
}
void Update() {
foreach (Touch touch in Input.touches) {
Vector3 newPosition;
if (touch.phase == TouchPhase.Began) {
startpos = touch.position;
endpos = touch.position;
}
if (touch.phase == TouchPhase.Moved) {
endpos = touch.position;
}
if (touch.phase == TouchPhase.Ended) {
newPosition = transform.position;
if (Mathf.Abs(startpos.y - endpos.y) > Mathf.Abs(startpos.x - endpos.x)) {
if ((startpos.y - endpos.y) > 100 && pionowa > -1) //swipe down
{
pionowa--;
newPosition.y -= speed;
transform.position = newPosition;
anim.SetTrigger("Flydown");
}
if ((startpos.y - endpos.y) < -100 && pionowa < 1) //swipe up
{
pionowa++;
newPosition.y += speed;
transform.position = newPosition;
anim.SetTrigger("Flyup");
}
}
else {
if ((startpos.x - endpos.x) > 100 && pozioma > -1) //swipe left
{
pozioma--;
newPosition.z -= speed;
transform.position = newPosition;
anim.SetTrigger("Flyleft");
}
}
if ((startpos.x - endpos.x) < -100 && pozioma < 1) //swipe right
{
pozioma++;
newPosition.z += speed;
transform.position = newPosition;
anim.SetTrigger("Flyright");
}
}
}
}
}
Modify your code instead of using just
transform.position = newPosition;
in all position use
transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
where smooth is float variable assign it required value may be 0.5f or whatever you want
Note : What it actually does is that it makes game object to move little based on smooth value, every frame
Note that we do not know your animator setup. If in those animation clips there is anywhere a keyframe for the position then the animator will always overrule anything done by scripts!
Instead of setting the new position immediately you could use a Coroutine with StartCoroutine like (also fixing some coding styles)
public class SwipeControls : MonoBehaviour
{
// Flag for ignoring input until current animation finished
private bool routineRunning;
// Configure in the Inspector distance to swipe
// in unity units
[SerializeField] private float swipeDistance = 5;
// configure this in the Inspector
// How long should the swiping take in seconds
[SerializeField] private float swipeDuration = 1;
private Vector3 _startpos; // start position
private Vector3 _endpos; //end position
public int pozioma = 0;
public int pionowa = 0;
private Animator _anim;
private void Start()
{
GetComponent<Animator>();
}
private void Update()
{
// Ignore any Input while a routine is running
if (routineRunning) return;
foreach (var touch in Input.touches)
{
switch (touch.phase)
{
case TouchPhase.Began:
_startpos = touch.position;
_endpos = touch.position;
break;
case TouchPhase.Moved:
_endpos = touch.position;
break;
case TouchPhase.Ended:
if (Mathf.Abs(_startpos.y - _endpos.y) > Mathf.Abs(_startpos.x - _endpos.x))
{
if (_startpos.y - _endpos.y > 100 && pionowa > -1) //swipe down
{
pionowa--;
StartCoroutine(MoveSmooth(Vector3.up * -1, swipeDuration));
_anim.SetTrigger("Flydown");
}
else if (_startpos.y - _endpos.y < -100 && pionowa < 1) //swipe up
{
pionowa++;
StartCoroutine(MoveSmooth(Vector3.up, swipeDuration));
_anim.SetTrigger("Flyup");
}
}
else
{
if (_startpos.x - _endpos.x > 100 && pozioma > -1) //swipe left
{
pozioma--;
StartCoroutine(MoveSmooth(Vector3.forward * -1, swipeDuration));
_anim.SetTrigger("Flyleft");
}
else if (_startpos.x - _endpos.x < -100 && pozioma < 1) //swipe right
{
pozioma++;
StartCoroutine(MoveSmooth(Vector3.forward, swipeDuration));
_anim.SetTrigger("Flyright");
}
}
break;
}
}
}
private IEnumerator MoveSmooth(Vector3 direction, float duration)
{
routineRunning = true;
var currentPosition = transform.localPosition;
var targetPosition = currentPosition + direction * swipeDistance;
var timePassed = 0f;
do
{
// Additionally add some ease in and out to the movement to get
// even smoother movement
var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / duration);
// Interpolate the position between currentPosition and targetPosition
// using the factor between 0 and 1
transform.localPosition = Vector3.Lerp(currentPosition, targetPosition, lerpFactor);
// increase by time since last frame
timePassed += Time.deltaTime;
// let this frame render and go on from
// here in the next frame
yield return null;
} while (timePassed <= duration);
// To avoid over or undershooting in the end set a fixed value
transform.localPosition = targetPosition;
routineRunning = false;
}
}
I don't know why you are using y+= and z+= .. it seems to me that it meeans the Camera is facing left in your scene e.g. with rotation = 0, -90, 0 and e.g. position = 10, 0, 0 than this should be the result (Note I copied the same code into if(GetMouseButtonDown(0)) etc in order to simulate the touch on the PC.)

Unity game Drag Object with finger movement

I am new to Unity and develop mobile 2d game,now I am able to make an object move right and left when I touch the screen before or after the screen center. But I want to touch the object and drag it on the x axis while my finger is still touching the screen and move,so I want the object to be in the same x position of my finger,
Any One can help me how to do it correctly:
here is the code of how I am moving the object if I touched before or after the screen center:
public class paddle : MonoBehaviour {
public Rigidbody2D rb;
public float speed;
public float maxX;
bool currentisAndroid=false;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody2D> ();
#if UNITY_ANDROID
currentisAndroid=true;
#else
currentisAndroid=false;
#endif
}
// Update is called once per frame
void Update () {
if (currentisAndroid == true) {
if (Input.GetTouch (0).position.x < Screen.width/2 && Input.GetTouch (0).phase == TouchPhase.Stationary)
moveLeft ();
else if (Input.GetTouch (0).position.x > Screen.width/2 && Input.GetTouch (0).phase == TouchPhase.Stationary)
moveRight ();
else
stop ();
} else {
float x = Input.GetAxis ("Horizontal");
//if (Input.GetTouch (0).position.x == rb.position.x && Input.GetTouch (0).phase == TouchPhase.Moved)
if (x == 0)
stop ();
if (x < 0)
moveLeft ();
if (x > 0)
moveRight ();
Vector2 pos = transform.position;
pos.x=Mathf.Clamp (pos.x,-maxX,maxX);
transform.position = pos;
}
}
void moveLeft()
{
rb.velocity = new Vector2 (-speed, 0);
}
void moveRight()
{
rb.velocity = new Vector2 (speed, 0);
}
void stop()
{
rb.velocity = new Vector2 (0, 0);
}
public float getposition()
{
return rb.position.y;
}
}
Easiest way:
Add component DragRigidbody script and you will be able to drag objects via mouse or touchScreen touches.
If I Understand correctly:
1 - Raycast from finger location vertically with your camera into the scene.
2 - select the hit object.
3 - map your camera to world coordinates and move that object according to hit point of your ray with map or game object\objects.
Physics.Raycast();
RaycastHit.collider();
Camera.main.ScreenToWorldPoint(Input.GetTouch(<0 or 1 or all>).position);
If you want to move object across a map you can track your touch and when its close to the corners move the camera on that direct (horizontal - vertical).

Smoothly lerp a rigidbody

I'm wanting my player to move to the left when the player hits the left of the screen. Right now, my player only moves as and when I hold down my mouse button. What I'm really wanting is for him to continually move to the left until he hits the target position when I press the screen once.
Can someone please tell me what I'm missing from my code to allow this to happen?
void FixedUpdate()
{
if(Input.GetMouseButtonDown(0))
{
if(Input.mousePosition.x < (Screen.width*2)/3 && Input.mousePosition.y > Screen.height/3)
{
if(position == middle)
{
MoveLeft();
}
}
}
}
void MoveLeft()
{
var pos = rigidbody.position;
float xPosition = left.transform.position.x;
pos.x = Mathf.Lerp(pos.x, xPosition, speed * Time.deltaTime);
rigidbody.position = pos;
}
My method is in the FixedUpdate because I'm moving the players rigidbody as oppose to translating the actual player.
Right now the player only moves when you hit mouse button because that's how your code is written: you check if the mouse is pressed every frame, and only if it is move the rigidbody.
If you want the player to move regardless of whether the mouse is still pressed or not, you should create some kind of variable to save the state of the player, and set to move left when the mouse button is pressed and set it to stop when the player reaches his target.
If I correctly understood your goal, it would look something like this:
bool moveLeft = false;
void FixedUpdate()
{
if(Input.GetMouseButtonDown(0)
&& (Input.mousePosition.x < (Screen.width*2)/3 && Input.mousePosition.y > Screen.height/3))
{
moveLeft = true;
}
if (moveLeft
&& (position == middle))
{
MoveLeft();
}
else
{
moveLeft = false;
}
}
void MoveLeft()
{
var pos = rigidbody.position;
float xPosition = left.transform.position.x;
pos.x = Mathf.Lerp(pos.x, xPosition, speed * Time.deltaTime);
rigidbody.position = pos;
}

Categories

Resources