Skip to content

Instantly share code, notes, and snippets.

@HolyMonkey
Created June 25, 2019 12:59
Show Gist options
  • Save HolyMonkey/3fb141d186797fd6743e839cd4c44022 to your computer and use it in GitHub Desktop.
Save HolyMonkey/3fb141d186797fd6743e839cd4c44022 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsMovement : MonoBehaviour
{
public float MinGroundNormalY = .65f;
public float GravityModifier = 1f;
public Vector2 Velocity;
public LayerMask LayerMask;
protected Vector2 targetVelocity;
protected bool grounded;
protected Vector2 groundNormal;
protected Rigidbody2D rb2d;
protected ContactFilter2D contactFilter;
protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
protected const float minMoveDistance = 0.001f;
protected const float shellRadius = 0.01f;
void OnEnable()
{
rb2d = GetComponent<Rigidbody2D>();
}
void Start()
{
contactFilter.useTriggers = false;
contactFilter.SetLayerMask(LayerMask);
contactFilter.useLayerMask = true;
}
void Update()
{
targetVelocity = new Vector2(Input.GetAxis("Horizontal"), 0);
if (Input.GetKey(KeyCode.Space) && grounded)
Velocity.y = 5;
}
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);
}
void Movement(Vector2 move, bool yMovement)
{
float distance = move.magnitude;
if (distance > minMoveDistance)
{
int count = rb2d.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;
}
}
rb2d.position = rb2d.position + move.normalized * distance;
}
}
@Mazday21
Copy link

изображение

@Siero2017
Copy link

ничего не понятно, но очень интересно

@xjncx
Copy link

xjncx commented Aug 28, 2022

нет более худшей идеи, чем объяснять что-то на готовой портянке кода

@ghostofgamer
Copy link

да тоже ничего не понял)

@GoodComrade
Copy link

Что-то понял только благодаря тому, что до этого очень долго понимал линейную алгебру.

@talatari
Copy link

talatari commented Dec 1, 2023

Да ваще всё изи.
Протягиваем наш объект передвижение в желаемом направлении и смотрим с чем столкнулись, и если с чем-то столкнулись, то двигаем до ближайшего объекта (минимальной дистанции между объектом передвижения и его препятствием). Дополнительно проверяя, на земле мы сейчас или нет, это вносит свои поправки на передвижение объекта - падать, скользить.

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