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;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 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;
}
}
}
}
|
}