Skip to content

Instantly share code, notes, and snippets.

@InfiniteAmmoInc
Last active January 5, 2023 20:54
Show Gist options
  • Save InfiniteAmmoInc/039e5c28a876286c103d369f9ab61a0c to your computer and use it in GitHub Desktop.
Save InfiniteAmmoInc/039e5c28a876286c103d369f9ab61a0c to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BoxMover : MonoBehaviour
{
public enum Slide
{
None,
Perpendicular,
}
public Vector3 boxScale, boxOffset;
private const float shim = .01f;
private bool overlapping;
private int layerMask;
void Awake()
{
layerMask = LayerMask.GetMask("Default");
}
public bool Move(Vector3 move, Slide slide = Slide.None)
{
var distance = move.magnitude;
var direction = move / distance;
var pos = transform.position;
float castDistance;
if (BoxCastHit(pos, direction, distance, out castDistance))
{
var bailPos = pos + (castDistance - shim) * direction;
if (slide == Slide.None)
{
transform.position = bailPos;
return false;
}
var newDirection = Vector3.zero;
if (!TrySlide(direction, distance, ref newDirection))
{
transform.position = bailPos;
return false;
}
transform.position = pos + newDirection * distance;
return true;
}
pos += move;
transform.position = pos;
return true;
}
public bool MoveX(float xAmount, Slide slide = Slide.None)
{
return Move(Vector3.right * xAmount, slide);
}
public bool MoveY(float yAmount, Slide slide = Slide.None)
{
return Move(Vector3.up * yAmount, slide);
}
private bool TrySlide(Vector3 direction, float distance, ref Vector3 newDirection)
{
var maxAdjust = 1.5f;
if (direction == Vector3.down)
maxAdjust = .5f;
const float adjustStep = .1f;
var pos = transform.position;
float castDistance;
for (var adjust = adjustStep; adjust < maxAdjust; adjust += adjustStep)
{
if (direction == Vector3.right || direction == Vector3.left)
{
newDirection = (direction + Vector3.up * adjust).normalized;
if (!BoxCastHit(pos, newDirection, distance, out castDistance))
return true;
}
else if (direction == Vector3.down)
{
newDirection = (direction + Vector3.right * adjust).normalized;
if (!BoxCastHit(pos, newDirection, distance, out castDistance))
return true;
newDirection = (direction + Vector3.left * adjust).normalized;
if (!BoxCastHit(pos, newDirection, distance, out castDistance))
return true;
}
}
return false;
}
private bool BoxCastHit(Vector3 pos, Vector3 direction, float distance, out float castDistance)
{
RaycastHit raycastHit;
if (Physics.BoxCast(pos + boxOffset, boxScale * .5f, direction, out raycastHit, Quaternion.identity, distance,
layerMask))
{
castDistance = raycastHit.distance;
return true;
}
castDistance = distance;
return false;
}
void OnDrawGizmosSelected()
{
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(boxOffset, boxScale);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment