Created
May 9, 2020 09:20
-
-
Save khokhryakov47/e08f7a524dbf484e3504a9a80fd5a891 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
wow, i needed that script week ago...
:C