- Home /
Move a rigidbody smoothly by swipe
Hi to all, i'm very new on unity and i'm facing my first problem. On my 3d project i have a spheric rigidbody that will rolling constantly along z (on a big square rigidbody used as "floor"), and i would like to translate it on x axis (left and right) with swipe. This is the sphere controller script:
public class PlayerController : MonoBehaviour
{
public static PlayerController Instance { get; private set; }
private Rigidbody rb;
public float speed;
void Start()
{
Instance = this;
rb = GetComponent<Rigidbody>();
speed = 20f;
}
private void FixedUpdate()
{
rb.AddForce(0f, 0f, speed, ForceMode.Acceleration);
}
public void MovePlayer(float movement)
{
StartCoroutine(MovePlayerCoroutine(movement));
}
private IEnumerator MovePlayerCoroutine(float movement)
{
rb.position = new Vector3(
transform.position.x + (movement/ 20f),
transform.position.y,
transform.position.z);
yield return null;
}
(my rigidbody has mass, drag and angular drag 1, use gravity and interpolate).
this is the script (attached to Main Camera object) for detect left and righ swipe and move player:
public class SwipeController : MonoBehaviour
{
// detected position on last frame
private Vector3 lastTouchPosition;
// detected position on current frame
private Vector3 currentTouchPosition;
//minimum distance for a swipe to be detected
private float dragDistance;
void Start()
{
// dragDistance will be a portion of screen
dragDistance = Screen.width * 5 / 100;
}
private void Update()
{
foreach (Touch touch in Input.touches) //use loop to detect more than one swipe
{
if (touch.phase == TouchPhase.Began)
{
// first touch on screen
lastTouchPosition = touch.position;
}
else if (touch.phase == TouchPhase.Moved)
{
currentTouchPosition = touch.position;
if (Mathf.Abs(currentTouchPosition.x - lastTouchPosition.x) > dragDistance || Mathf.Abs(currentTouchPosition.y - lastTouchPosition.y) > dragDistance)
{//It's a drag
PlayerController.Instance.MovePlayer(currentTouchPosition.x - lastTouchPosition.x);
if ((currentTouchPosition.x > lastTouchPosition.x))
{ //Right swipe
Debug.Log("Right Swipe");
lastTouchPosition = currentTouchPosition;
}
else
{ //Left swipe
Debug.Log("Left Swipe");
lastTouchPosition = currentTouchPosition;
}
}
}
else if (touch.phase == TouchPhase.Ended)
{
// reset positions
lastTouchPosition = currentTouchPosition = new Vector3();
}
}
}
}
This code works but the movement is not smooth (it seems that sphere jump directly on new position). Whats the problem?
i think you want something more like this
so much simpler.....
Ps. You should check out Udemy.com and one that i noticed is half the price i paid quite good and where this is from is the Udemy "Complete C# Unity Developer 2D: and 3D: Learn to Code $$anonymous$$aking Games" courses by Ben Tristem.. $$anonymous$$ost of what i know the better half was learned by them 1/4 here and rest on my own.
k well, take a look at Slerp if that isn't it.
Answer by xxmariofer · Feb 21, 2019 at 10:03 AM
hello, that happens because you are teleporting inside the corroutine the object from one position to another. first i would suggest not using rb.position since thats just teleporting the object and collisions will get affected, you could be using rb.velocity for example and give the object your desired velocity in the x axis
rb.velocity = Vector3.right * speed;
but this will not make the object move to a position just will add a force and for stopping that object you will have to force the velocity in x axis to be 0 if swipped ended, if you want to use rb.position you can use the coroutine (since right now you are using it just as a method) you can add a for inside the coroutine and rather than moving once to that position iterate littlle by little.
Thank you for answering. i've made some edit to my code, check my answer below.
Answer by giozh89 · Feb 21, 2019 at 03:31 PM
After some tests i've implemented this (i've excluded to change velocity):
private IEnumerator MovePlayerCoroutine(float movement)
{
Vector3 targetPosition = new Vector3(transform.position.x +movement, transform.position.y, transform.position.z);
Vector3 direction = (targetPosition - transform.position).normalized;
rb.MovePosition(transform.position + direction * 20f * Time.deltaTime);
yield return null;
}
but movement is still not smooth (but smoother than my first implementation).
try this code and tell me if it works
private IEnumerator $$anonymous$$ovePlayerCoroutine(float movement)
{
int numberOfIterations = 20;
for(int i = 0; i < numberOfIterations; i++)
{
Vector3 targetPosition = new Vector3(transform.position.x + (movement / numberOfIterations), transform.position.y, transform.position.z);
Vector3 direction = (targetPosition - transform.position).normalized;
rb.$$anonymous$$ovePosition(transform.position + direction * 20f * Time.deltaTime);
yield return null;
}
}
if you increase the number of iterations value it will be smoother.
this snippet has two problem. If i keep
yield return null;
inside for statement, movement start after a while i'm start swiping. If i put it outside for statement, there's no delay between swipe and starting movement, but movement is still not smooth, also if i increase "numberOfIterations". If i do small swipe, my rigidbody still "jump" into position
yield return null breaks the syncronius of the code, and gives control to the editor. outside the for its just do nothing since the corroutine is "over". the yield return null inside the for should not be delaying the movemtn.
Answer by Shyamjadav · Aug 26, 2021 at 06:17 AM
if (inputValue > 0)
{
rigidbody.AddForce(new Vector3(0.5f, 0, 0)* smoothnessValue);
//Jump(Vector3.left);
}
else if (inputValue < 0)
{
rigidbody.AddForce(new Vector3(-0.5f, 0, 0) * smoothnessValue);
//Jump(Vector3.right);
}
Your answer
Follow this Question
Related Questions
rigidbody velocity on x axis and addforce on y axis ?? 1 Answer
Can an accelerometer be used for a RigidBody based movement? 0 Answers
AddForce to a randomly selected GameObject with a rigidbody 0 Answers
Rotate object towards target without influencing AddForce 0 Answers
How can I apply a force to an object in the opposite direction of the object it's colliding with? 2 Answers