Unity 2D: player character speeds up unintantionally
I'm trying to move my player character on grid but when I hold down one of the directional keys the player speeds up unintentionally and the slow back down, and it does it periodically.
I'm using some of the code from the 2D roguelike tutorial. Thank you for the answers.
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : Entity
{
public float restartDelay = 1f;
public int damage = 1;
private int health;
protected override void Start()
{
health = GameManager.instance.playerHealthPoints;
base.Start();
}
private void Update()
{
if (Vector3.Distance(transform.position, point.position) <= margin)
{
int horizontal = (int)Input.GetAxisRaw("Horizontal");
int vertical = (int)Input.GetAxisRaw("Vertical");
if (horizontal != 0 || vertical != 0)
{
AttemptMove<Wall>(horizontal, vertical);
}
}
}
protected override void AttemptMove<T>(int xDir, int yDir)
{
base.AttemptMove<T>(xDir, yDir);
RaycastHit2D hit;
}
protected override void OnCantMove<T>(T component)
{
Wall hitWall = component as Wall;
hitWall.DamageWall(damage);
}
private void OnDisable()
{
GameManager.instance.playerHealthPoints = health;
}
public void LoseHealth (int loss)
{
health -= loss;
CheckIfGameOver();
}
private void Restart()
{
SceneManager.LoadScene(0);
}
private void CheckIfGameOver()
{
if (health <= 0)
{
GameManager.instance.GameOver();
}
}
}
Entity.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class Entity : MonoBehaviour
{
public float margin = 0.05f;
public float movementSpeed = 4f;
public LayerMask blockingLayer;
public Transform point;
private BoxCollider2D boxCollider2D;
private Rigidbody2D rb2D;
protected virtual void Start()
{
boxCollider2D = GetComponent<BoxCollider2D>();
rb2D = GetComponent<Rigidbody2D>();
point.parent = null;
}
public bool Move (int xDir, int yDir, out RaycastHit2D hit)
{
Vector2 start = transform.position;
Vector2 end = start + new Vector2(xDir, yDir);
boxCollider2D.enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer);
boxCollider2D.enabled = true;
if(hit.transform == null) {
StartCoroutine(Movement(xDir, yDir));
return true;
}
return false;
}
private IEnumerator Movement(int xDir, int yDir)
{
point.position += new Vector3(xDir, yDir, 0f);
while(Vector3.Distance(rb2D.position,point.position) > float.Epsilon)
{
rb2D.position = Vector3.MoveTowards(rb2D.position, point.position, movementSpeed * Time.deltaTime);
yield return null;
}
}
protected virtual void AttemptMove<T>(int xDir, int yDir)
where T : Component
{
RaycastHit2D hit;
bool canMove = Move(xDir, yDir, out hit);
if(hit.transform == null)
{
return;
}
T hitComponent = hit.transform.GetComponent<T>();
if (!canMove && hitComponent != null)
OnCantMove(hitComponent);
}
protected abstract void OnCantMove<T>(T component)
where T : Component;
}
Answer by Jacob551228 · Aug 11, 2020 at 08:06 PM
While I couldn't fix the problem with this code, I fixed my problem by rewriting the player and entity script.
Answer by Jacob551228 · Aug 08, 2020 at 05:17 PM
For now I fixed it like seen below, but I would like if it could be improved:
private void Update()
{
if (Vector3.Distance(transform.position, point.position) <= margin)
{
int horizontal = (int)Input.GetAxisRaw("Horizontal");
int vertical = (int)Input.GetAxisRaw("Vertical");
if (Vector3.Distance(transform.position, point.position) <= 0f && horizontal != 0 || vertical != 0)
{
AttemptMove<Wall>(horizontal, vertical);
}
}
}
Answer by jimau · Aug 09, 2020 at 07:27 PM
You can adjust how Input.GetAxis(...)
values accelerate/decelerate under Edit > Project Settings > Input Manager > Axes > Horizontal / Vertical:
Gravity Speed in units per second that the axis falls toward neutral when no input is present.
Dead How far the user needs to move an analog stick before your application registers the movement. At runtime, input from all analog devices that falls within this range will be considered null.
Sensitivity Speed in units per second that the axis will move toward the target value. This is for digital devices only.
If I understand correctly then Input.getAxis(...) uses those values to smooth and filter the input, while Input.getAxisRaw(...) ignores them and I use the latter one. $$anonymous$$y problem is that if I hold down a direction key (for example 'D'). the player character moves and then it speeds up for a little bit, then slows back down. It does it repeatedly while I hold down the key.
But thank you for the answer.
Your answer
Follow this Question
Related Questions
Switching lanes 1 Answer
Isometric movement for MoveTowards 0 Answers
Why is my bool being set to true when program is run? 1 Answer
How to have a child object camera with gaze move its parent object 0 Answers
Movement input problem? 1 Answer