- Home /
2D smooth top-down movement
Hi. I'm new to unity. I don't know how to smotoh my top-down movement. Can someone help?
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
mouse = cam.ScreenToWorldPoint(Input.mousePosition);
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + movement * speed * Time.fixedDeltaTime);
Vector2 lookDir = mouse - rb.position;
float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90f;
rb.rotation = angle;
}
I am also a beginner, but try changing, Input.GetAxis to Input.GetAxis. I am not sure if that will work, but try it and see. GetAxisRaw is for more snappy movement. Also, if you can't get that to work try this Brackeys tutorial: https://www.youtube.com/watch?v=whzomFgjT50
Answer by kirbygc00 · May 09, 2020 at 05:50 PM
Some static helper function, should be in its own class c# class, but you could put it on your player if you like. We are using a plane (assuming your level is flat) to simplify detection for where the mouse is. All mouse values will contain a "height" of zero (which is what i wanted, you can change this)
// MouseHelper.cs
static Plane plane = new Plane(Vector3.up, 0f);
public static Vector3 GetWorldPosition()
{
if (cam != null)
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out float distanceToPlane))
{
return ray.GetPoint(distanceToPlane);
}
}
return Vector3.zero;
}
player script: We are grabbing the input in the update method and storing it in a class field. In the fixed update we use the input to change the character position. This script assumes your "Up" is Y and your forward is Z.
// playerscripts.cs
vector3 motion;
public void Update()
{
// grabbing our motion from update because it runs more frequently
motion = GetMovementFromInput();
}
public void FixedUpdate()
{
// applying position/rotation changes when the physics engine runs because we are using Rigidbody.ApplyForce
UpdatePlayerRotation(motion);
UpdatePlayerPosition(motion);
}
private void UpdatePlayerRotation(Vector3 motion)
{
// get mouse pos
var mousePos = MouseHelper.GetWorldPosition();
// lock y to unit's current y
var lookTarget = new Vector3(mousePos.x, gameObject.transform.position.y, mousePos.z);
Owner.transform.LookAt(lookTarget);
}
// i'm using the new input system... you can sub out the input.horizontal and forward for what you have now- Input.GetAxis("Horizontal")
private Vector3 GetMovementFromInput(InputValues input)
{
var posX = input.Horizontal * movementSpeed * Time.deltaTime;
var posY = 0;
var posZ = input.Forward * movementSpeed * Time.deltaTime;
var motion = new Vector3(posX, posY, posZ);
return motion;
}
private void UpdatePlayerPosition(Vector3 motion)
{
rb.AddForce( motion.normalized * movementSpeed);
}
Hope it helps =)
Your answer
Follow this Question
Related Questions
Unity 2D - Smooth movement over tiles?? 1 Answer
Top-down movement in 2D 1 Answer
Anchored Rotation with Gradual Movement 0 Answers
Complex 2D movement (X,Y) using velocity. 1 Answer
Smooth Character Movement 1 Answer