Reputation: 3
I am creating a 3D endless runner that's a little different than the norm. There are 5 Lanes that are 1 unit wide, and the player can fall off the sides if they move too far to the left or right. The Player does not move Forward, Jump or Slide. It only has left or right movement. The player can get bounced backward if hit by an oncoming obstacle that increases in speed over time.
In regards to the player's left/right movement, I got it pretty close. But I'm having trouble getting precise positioning of the player.
Sometimes when the player moves over a lane the position will sometimes be off by 0.1, and may start to stack up over time. i.e. Starting in the 0 position, move left, it stops at 0.9 or 1.1.
This is the code so far -
{
public float speed;
public float mleft = -0.7f;
public float mright = 0.7f;
private Rigidbody rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetKeyDown("a"))
{
rb.velocity = new Vector3(mleft, 0, 0) * speed;
StartCoroutine(stopLaneCH());
}
Debug.Log(GetComponent<Transform>().position);
if (Input.GetKeyDown("d"))
{
rb.velocity = new Vector3(mright, 0, 0) * speed;
StartCoroutine(stopLaneCH());
}
}
IEnumerator stopLaneCH ()
{
yield return new WaitForSeconds(0.5f);
GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
}
}
I've had to try and find a balance between the speed and the mleft/mright variables that would move the player 1 unit.
I am still fairly new to Unity and programming, but any help with this problem is greatly appreciated.
And I may even name my 3rd child after anyone that helps solve this problem.
Upvotes: 0
Views: 148
Reputation: 313
Here, You can use Time.deltaTime property. And the value of speed should be "How many units you want to sweep in 1 second" multiplied by 2 Since your coroutine will get stopped in just 0.5 seconds.
Or alternatively, If your coroutine would have to be stopped in 1.0 seconds. then the value of the speed would be "How many units you want to seep in 1 second" only.
I hope, it helps to you!
public float speed;
public float mleft = -0.7f;
public float mright = 0.7f;
private Rigidbody rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetKeyDown("a"))
{
rb.velocity = new Vector3(mleft, 0, 0) * speed * Time.deltaTime;
StartCoroutine(stopLaneCH());
}
Debug.Log(GetComponent<Transform>().position);
if (Input.GetKeyDown("d"))
{
rb.velocity = new Vector3(mright, 0, 0) * speed * Time.deltaTime;
StartCoroutine(stopLaneCH());
}
}
IEnumerator stopLaneCH ()
{
yield return new WaitForSeconds(0.5f);
GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
}
Upvotes: 0
Reputation: 51
If I am understanding this correct, instead of changing the velocity, because to get it to move 1 unit exactly would be near impossible. Instead, why not move the player one unit exactly? Using a Coroutine you can use the Vector3.Lerp method to move from your current position to your desired position over time. Your desired position is 1 unit, or, the distance between each of your lanes from your current position.
void Update(){
//For Moving Left
if (Input.GetKeyDown(KeyCode.A))
StartCoroutine(MoveToPosition(transform, new Vector3(transform.position.x - 1, transform.position.y, transform.position.z), 0.5f));
//For Moving Right
if (Input.GetKeyDown(KeyCode.D))
StartCoroutine(MoveToPosition(transform, new Vector3(transform.position.x - 1, transform.position.y, transform.position.z), 0.5f));
}
public IEnumerator MoveToPosition(Transform transform, Vector3 position, float timeToMove)
{
var currentPos = transform.position;
var t = 0f;
while (t < 1)
{
t += Time.deltaTime / timeToMove;
transform.position = Vector3.Lerp(currentPos, position, t);
yield return null;
}
}
I presume you are moving left/right on the X axis, if not, simply change the - 1 to the axis that you are moving on. You can change the TimeToMove float to your liking as well.
Hope this helps. If you have any questions feel free to ask!
Upvotes: 1