Last active
July 13, 2017 20:25
-
-
Save mfep/fab2d5c7d4230a1395eabb7f650cf6fa 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 Duality; | |
using Duality.Components.Physics; | |
using Duality.Components.Renderers; | |
using Duality.Drawing; | |
using Duality.Editor; | |
namespace mfep.Duality.Snippets | |
{ | |
[RequiredComponent (typeof(SpriteRenderer))] | |
public class CharacterController : Component | |
{ | |
[Flags] | |
public enum Sides | |
{ | |
None = 0b0000, | |
Top = 0b0001, | |
Right = 0b0010, | |
Bottom = 0b0100, | |
Left = 0b1000, | |
TopRight = 0b0011, | |
BottomRight = 0b0110, | |
TopLeft = 0b1001, | |
BottomLeft = 0b1100 | |
} | |
public int RayCount { get; set; } = 3; | |
public float Skin { get; set; } = 1f; | |
public bool Visualize { get; set; } = false; | |
[EditorHintFlags(MemberFlags.ReadOnly)] | |
public Sides Collision { get; private set; } = Sides.None; | |
public void Move (Vector2 deltaPos) | |
{ | |
Collision = Sides.None; | |
MoveX (deltaPos); | |
MoveY (deltaPos); | |
} | |
private void MoveX (Vector2 deltaPos) | |
{ | |
if (!(MathF.Abs (deltaPos.X) > 0.0f)) return; | |
var bounds = GameObj.GetComponent<SpriteRenderer> ().Rect.WithOffset(GameObj.Transform.Pos.Xy); | |
var dx = Vector2.UnitX * deltaPos.X; | |
var dirX = deltaPos.X > 0.0f ? 1.0f : -1.0f; | |
var skinV = Vector2.UnitX * dirX * this.Skin; | |
var topCenter = bounds.Center - Vector2.UnitY * (bounds.H * 0.5f - this.Skin); | |
var height = bounds.H - 2.0f * this.Skin; | |
var rayDivision = Vector2.UnitY * height / (this.RayCount - 1.0f); | |
var offs = Vector2.UnitX * (bounds.W * 0.5f * dirX) - skinV; | |
var minFraction = 1.0f; | |
var hit = false; | |
var frac = 1.0f; | |
for (int i = 0; i < RayCount; i++) | |
{ | |
var origin = topCenter + i * rayDivision + offs; | |
if (RigidBody.RayCast(origin, origin + dx + skinV, data => 1.0f, out RayCastData firstHit)) | |
{ | |
hit = true; | |
frac = firstHit.Fraction; | |
minFraction = MathF.Min(minFraction, firstHit.Fraction); | |
} | |
if (this.Visualize) | |
{ | |
VisualLog.Default.BaseColor = hit ? ColorRgba.Red : ColorRgba.White; | |
VisualLog.Default.DrawVector (new Vector3 (origin), (dx + skinV) * frac); | |
} | |
} | |
var xMove = (dx + skinV) * minFraction - skinV; | |
GameObj.Transform.MoveByAbs(xMove); | |
if (hit) { | |
var side = dirX > 0.0f ? Sides.Right : Sides.Left; | |
Collision |= side; | |
} | |
} | |
private void MoveY (Vector2 deltaPos) | |
{ | |
if (!(MathF.Abs(deltaPos.Y) > 0.0f)) return; | |
var bounds = GameObj.GetComponent<SpriteRenderer>().Rect.WithOffset(GameObj.Transform.Pos.Xy); | |
var dy = Vector2.UnitY * deltaPos.Y; | |
var dirY = deltaPos.Y > 0.0f ? 1.0f : -1.0f; | |
var skinV = Vector2.UnitY * dirY * this.Skin; | |
var leftCenter = bounds.Center - Vector2.UnitX * (bounds.W * 0.5f - this.Skin); | |
var width = bounds.W - 2.0f * this.Skin; | |
var rayDivision = Vector2.UnitX * width / (this.RayCount - 1.0f); | |
var offs = Vector2.UnitY * (bounds.H * 0.5f * dirY) - skinV; | |
var minFraction = 1.0f; | |
var hit = false; | |
var frac = 1.0f; | |
for (int i = 0; i < RayCount; i++) | |
{ | |
var origin = leftCenter + i * rayDivision + offs; | |
if (RigidBody.RayCast(origin, origin + dy + skinV, data => 1.0f, out RayCastData firstHit)) | |
{ | |
hit = true; | |
frac = firstHit.Fraction; | |
minFraction = MathF.Min(minFraction, firstHit.Fraction); | |
} | |
if (this.Visualize) | |
{ | |
VisualLog.Default.BaseColor = hit ? ColorRgba.Red : ColorRgba.White; | |
VisualLog.Default.DrawVector (new Vector3 (origin), (dy + skinV) * frac); | |
} | |
} | |
var yMove = (dy + skinV) * minFraction - skinV; | |
GameObj.Transform.MoveByAbs(yMove); | |
if (hit) { | |
var side = dirY > 0.0f ? Sides.Bottom : Sides.Top; | |
Collision |= side; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment