- Home /
The question is answered, right answer was accepted
How do i stop rigidbody2D bounce
So im quite new to unity and ive decided to start working on a 2d rpg, using sources from this site ive manged to get a code that gives me grid movement much like that in the older pokemon games. Now i want to introduce collisions and physics to my game but after attaching the rigidbody component and moving around i realise my movement has become very clumsy and well - not nice - to look at. But the real problem is that when ever i walk into an object with a collider - say a tree or something like that - instead of simply refusing to go further it bumbs into the object gets pushed back and repeats and i get stuck in this state. heres my player controller script, i'd appreciate any pointers tips or an entire resolution to my problem THANKS :D
public class AnnaController : MonoBehaviour {
private Rigidbody2D rgdbdy;
public Animator anmtr;
private static bool playerExists;
private float mSpeed;
public bool overworld;
public Vector2 forwardVector;
public Vector2 mvmntVector;
private Vector3 pos;
private bool hasStepped;
private bool isWalking;
private bool Up;
private bool Down;
private bool Left;
private bool Right;
// Use this for initialization
void Start () {
anmtr = GetComponent<Animator> ();
rgdbdy = GetComponent<Rigidbody2D> ();
mSpeed = 0.75f;
pos = transform.position;
forwardVector = Vector2.zero;
if (overworld) {
if (!playerExists) {
playerExists = true;
DontDestroyOnLoad (transform.gameObject);
} else {
Destroy (gameObject);
}
}
}
// Update is called once per frame
void FixedUpdate () {
anmtr.SetFloat ("ForwardX", forwardVector.x);
anmtr.SetFloat ("ForwardY", forwardVector.y);
Right = false;
Left = false;
Down = false;
Up = false;
if (Input.GetKey (KeyCode.B)) {
mSpeed = 1.25f;
}
else {
mSpeed = 0.5f;
}
if (!Right) {
if (Input.GetAxisRaw ("Horizontal") > 0.5f && transform.position == pos) {
pos += (Vector3.right * 0.32f);
forwardVector = Vector2.right;
}
}
if (!Up) {
if (Input.GetAxisRaw ("Vertical") > 0.5f && transform.position == pos) {
pos += (Vector3.up * 0.32f);
forwardVector = Vector2.up;
}
}
if (!Left) {
if (Input.GetAxisRaw ("Horizontal") < -0.5f && transform.position == pos) {
pos += new Vector3(-0.32f, 0, 0);
forwardVector = Vector2.left;
}
}
if (!Down) {
if (Input.GetAxisRaw ("Vertical") < -0.5f && transform.position == pos) {
pos += new Vector3(0, -0.32f, 0);
forwardVector = Vector2.down;
}
}
transform.position = Vector2.MoveTowards (transform.position, pos, Time.deltaTime * mSpeed);
}
}
Answer by lunoland · Aug 15, 2016 at 09:59 PM
For a classic, snappy, 2D feel, you probably don't want to use the built-in, realistic physics.
If the objects your player will be colliding against do not move, you can make them all static colliders (objects that only have a collider component, and not a rigidbody) and then move the player using Rigidbody2D.MovePosition in Update.
If you've got other moving colliders, you'll have to set the isKinematic flag on their Rigidbody2D components (the player object included) and write your own collision checking.
This involves using the Physics2D overlap or raycast functions before you move the player to a new position to test against any colliders at the new position; You then only move the player to the position if the player's collider will fit.
See https://docs.unity3d.com/Manual/CollidersOverview.html for more info on isKinematic and colliders/physics.
Okay so this has made things a slight bit better but i'm still getting problems. The objects my player is supposed to be colliding against are already static colliders. I ticked the is$$anonymous$$inematic Flag on the players Rigidbody and i changed transform.position =Vector2.$$anonymous$$oveTowards (transform.position, pos, Time.deltaTime * mSpeed);
to Rigidbody2D.$$anonymous$$ovePosition (Vector2.$$anonymous$$oveTowards (transform.position, pos, Time.deltaTime * mSpeed));
the movement became smooth but the player ceased to collide with anything. Then i turned off is$$anonymous$$inematic and now up and down movement works fine but once i go left or right the movement stops working. This also occurs when i collide with something no matter what input i had made before
Ah yeah, I addressed that in my answer. Using is$$anonymous$$inematic requires you to do your own collision checking; it assumes you're going to be controlling the objects explicitly in script. If you move an object somewhere by changing transform.position or $$anonymous$$ovePosition + is$$anonymous$$inematic, Unity just trusts that you will be putting it in the exact place you wanted it (ignoring colliders, physics, etc.).
Definitely check out that link to the manual I posted. I know it's boring, but I would start by reading the manual and watching some of Unity's tutorials on each part of the engine you're currently working with before you start coding. You'll be less reliant on people on the forums writing your code for you, so you'll learn more that way.
I'm not sure why changing is$$anonymous$$inematic would affect left or right movement, but your movement code looks really unclear and seems to be doing a lot of unnecessary work. If you only want the player to be able to move in 4 directions, start with something like this (note that I wrote this at work and did not test it):
float moveSpeed = 0.5f;
Rigidbody2D rigidbody;
void Awake() {
rigidbody = GetComponent<Rigidbody2D>();
}
void Update() {
float runSpeed$$anonymous$$ultiplier = 1f;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.B))
runSpeed$$anonymous$$ultiplier = 2.5f; // This way your run speed will be relative to the base movement speed.
int horizontal = $$anonymous$$athf.RoundToInt(Input.GetAxisRaw("Horizontal")); // Rounding to an integer means it will be -1, 0, or 1.
int vertical = $$anonymous$$athf.RoundToInt(Input.GetAxisRaw("Horizontal"));
Vector2 direction;
if (horizontal == 0 && vertical == 0)
return; // No movement, so we're done
else if (horizontal > 0)
direction = Vector2.right
else if (horizontal < 0)
direction = Vector2.left
else if (vertical > 0)
direction = Vector2.up
else if (vertical < 0)
direction = Vector2.down
Vector2 newPosition = transform.position + (direction * moveSpeed * runSpeed$$anonymous$$ultiplier * Time.deltaTime);
rigidbody.$$anonymous$$ovePosition(newPosition);
}
Follow this Question
Related Questions
Change a specific Gameobjects rigidbody gravity to horizontal (left) 1 Answer
2D physics object acts weird when pressed into other physics object 0 Answers
How can I increase or decrease jump speed while keeping the jump arc the same? 1 Answer
Can a collider be solid along one axis only? 2 Answers
Player Knockback Without Physics 0 Answers