Skip to content

Instantly share code, notes, and snippets.

@khokhryakov47
Created May 9, 2020 09:20
Show Gist options
  • Save khokhryakov47/e08f7a524dbf484e3504a9a80fd5a891 to your computer and use it in GitHub Desktop.
Save khokhryakov47/e08f7a524dbf484e3504a9a80fd5a891 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsMovement : MonoBehaviour
{
[SerializeField] private float _minGroundNormalY = .65f;
[SerializeField] private float _gravityModifier = 1f;
[SerializeField] private Vector2 _velocity;
[SerializeField] private LayerMask _layerMask;
private Vector2 _targetVelocity;
private bool _grounded;
private Vector2 _groundNormal;
private Rigidbody2D _rigidbody2d;
private ContactFilter2D _contactFilter;
private RaycastHit2D[] _hitBuffer = new RaycastHit2D[16];
private List<RaycastHit2D> _hitBufferList = new List<RaycastHit2D>(16);
private const float _minMoveDistance = 0.001f;
private const float _shellRadius = 0.01f;
private void OnEnable()
{
_rigidbody2d = GetComponent<Rigidbody2D>();
}
private void Start()
{
_contactFilter.useTriggers = false;
_contactFilter.SetLayerMask(_layerMask);
_contactFilter.useLayerMask = true;
}
private void Update()
{
_targetVelocity = new Vector2(Input.GetAxis("Horizontal"), 0);
if (Input.GetKey(KeyCode.Space) && _grounded)
_velocity.y = 5;
}
private void FixedUpdate()
{
_velocity += _gravityModifier * Physics2D.gravity * Time.deltaTime;
_velocity.x = _targetVelocity.x;
_grounded = false;
Vector2 deltaPosition = _velocity * Time.deltaTime;
Vector2 moveAlongGround = new Vector2(_groundNormal.y, -_groundNormal.x);
Vector2 move = moveAlongGround * deltaPosition.x;
Movement(move, false);
move = Vector2.up * deltaPosition.y;
Movement(move, true);
}
private void Movement(Vector2 move, bool yMovement)
{
float distance = move.magnitude;
if (distance > _minMoveDistance)
{
int count = _rigidbody2d.Cast(move, _contactFilter, _hitBuffer, distance + _shellRadius);
_hitBufferList.Clear();
for (int i = 0; i < count; i++)
{
_hitBufferList.Add(_hitBuffer[i]);
}
for (int i = 0; i < _hitBufferList.Count; i++)
{
Vector2 currentNormal = _hitBufferList[i].normal;
if (currentNormal.y > _minGroundNormalY)
{
_grounded = true;
if (yMovement)
{
_groundNormal = currentNormal;
currentNormal.x = 0;
}
}
float projection = Vector2.Dot(_velocity, currentNormal);
if (projection < 0)
{
_velocity = _velocity - projection * currentNormal;
}
float modifiedDistance = _hitBufferList[i].distance - _shellRadius;
distance = modifiedDistance < distance ? modifiedDistance : distance;
}
}
_rigidbody2d.position = _rigidbody2d.position + move.normalized * distance;
}
}
@SupinePandora43
Copy link

wow, i needed that script week ago...
:C

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment