using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class Mover2D : MonoBehaviour
{
//Editor Fields
[SerializeField] protected float BaseSpeed = 1f;
[SerializeField] protected LayerMask layerMask;
[SerializeField] protected int SkinWidth = 1;

protected Rigidbody2D rb;
protected ContactFilter2D contactFilter;

protected RaycastHit2D[] hits = new RaycastHit2D[16];

protected Vector2 velocity;
protected Vector2 inputVector;

protected Vector2 remainder;
protected Vector2 previousInputVector;


private void Awake()
{
    rb = GetComponent<Rigidbody2D>();
}

// Start is called before the first frame update
void Start()
{
    contactFilter.SetLayerMask(layerMask);
    previousInputVector = Vector2.zero;
    remainder = Vector2.zero;
}

// Update is called once per frame
void Update()
{
    //get input
    inputVector = Vector2.zero;
    inputVector.x = Mathf.RoundToInt(Input.GetAxisRaw("Horizontal"));
    inputVector.y = Mathf.RoundToInt(Input.GetAxisRaw("Vertical"));
    //Debug.Log($"input vector: x:{inputVector.x}, y:{inputVector.y}");

    inputVector.Normalize();

    velocity = Vector2.zero;
    velocity.x = inputVector.x * BaseSpeed;
    velocity.y = inputVector.y * BaseSpeed;

}


private void FixedUpdate()
{
    Move();
    previousInputVector = inputVector;
}

private void Move()
{
    Vector2 deltaPosition = velocity * Time.deltaTime;


    //horizontal move
    MoveX(deltaPosition.x);

    //vertical move
    MoveY(deltaPosition.y);
}


private void MoveX(float distance)
{
    remainder.x += distance; //remainder allows subpixel movement
    int move = Mathf.RoundToInt(remainder.x);

    if (move != 0)
    {
        remainder.x -= move;
        int sign = (int)Mathf.Sign(move);

        while (move != 0)
        {
            //check for collision 1 px forwards
            int collisions = rb.Cast(Vector2.right, contactFilter, hits, sign);

            if (collisions == 0) //there is no solid
            {
                rb.position = new Vector2(rb.position.x + sign, rb.position.y);
                move -= sign;
            }

            else//if there are collisions...
            {
                Debug.Log("Collision X");
                break;
            }
        }
    }
}

private void MoveY(float distance)
{
    remainder.y += distance;

    int move = Mathf.RoundToInt(remainder.y);

    if (move != 0)
    {
        remainder.y -= move;
        int sign = (int)Mathf.Sign(move);

        while (move != 0) //step through move distance 1 pixel at a time
        {
            //check for collision 1 px forwards
            int collisions = rb.Cast(Vector2.up, contactFilter, hits, sign);

            if (collisions == 0) //there is no solid
            {
                rb.position = new Vector2(rb.position.x, rb.position.y + sign);
                move -= sign;
            }

            else//if there are collisions...
            {
                //do collision event here;
                Debug.Log("Collision Y");
                break;
            }
        }
    }
}

}

Edit
Pub: 04 Jul 2023 17:22 UTC
Views: 33