Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@javier-games
Last active February 18, 2023 05:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javier-games/32d0e32928ab714a0f6a98f84365b6ad to your computer and use it in GitHub Desktop.
Save javier-games/32d0e32928ab714a0f6a98f84365b6ad to your computer and use it in GitHub Desktop.
Determinates if a point belongs to a drawable field view in 2D.

Field View 2D

Determinates if a Contact Point belongs to a drawed field view in a plane using just the Collider 2D.

Unity Version

using UnityEngine;
/// <summary>
/// Field View.
///
/// <para>
/// Determinates if a point belongs to a drawable field view in 2D.
/// </para>
///
/// <para> By Javier García | @jvrgms | 2019 </para>
/// </summary>
[System.Serializable]
public struct FieldView2D {
#region Class Members
public Vector2 offset; // Offset from the center.
public float magnitude; // Magnitude of the field of view.
[Range (0, 360)]
public float angle; // Angle of direction according to Vector.righ.
[Range (0, 360)]
public float aperture; // Aperture of the field of view.
public Color color; // Color to draw the field of view.
#endregion
#region Public Static Accesors
/// <summary> Gets a Field View 2D for top. </summary>
/// <value> The Top Field View 2D. </value>
public static FieldView2D Top {
get {
return new FieldView2D () {
offset = Vector2.up,
magnitude = 1f,
angle = 90,
aperture = 60,
color = Color.grey
};
}
}
/// <summary> Gets a Field View 2D for Bottom. </summary>
/// <value> The Bottom Field View 2D. </value>
public static FieldView2D Bottom {
get {
return new FieldView2D () {
offset = Vector2.down,
magnitude = 1f,
angle = 270,
aperture = 60,
color = Color.grey
};
}
}
/// <summary> Gets a Field View 2D for right. </summary>
/// <value> The Right Field View 2D. </value>
public static FieldView2D Right {
get {
return new FieldView2D () {
offset = Vector2.right,
magnitude = 1f,
angle = 0,
aperture = 60,
color = Color.grey
};
}
}
/// <summary> Gets a Field View 2D for Left. </summary>
/// <value> The Left Field View 2D. </value>
public static FieldView2D Left {
get {
return new FieldView2D () {
offset = Vector2.left,
magnitude = 1f,
angle = 180,
aperture = 60,
color = Color.grey
};
}
}
#endregion
#region Drawing Methods
/// <summary> Draw the field view at the specified position. </summary>
/// <param name="position">Position.</param>
public void Draw (Vector2 position) {
#if UNITY_EDITOR
// TODO: Replace the guidelines for an arc.
int n = 8; // Number of guide lines to simulate an abanico.
float half = angle - aperture * 0.5f;
float segment = aperture / n;
for (int i = 0; i <= n; i++) {
float alpha = (half + (i * segment)) * Mathf.Deg2Rad;
// Getting the start and end of the guide line.
Vector2 start = position + offset;
Vector2 end = start + magnitude * new Vector2 (
x: Mathf.Cos (alpha),
y: Mathf.Sin (alpha)
);
Gizmos.color = color;
Gizmos.DrawLine (start, end);
}
#endif
}
#endregion
#region Struct Implementation
/// <summary> Defines if the field view contains the gived point. </summary>
/// <returns>The contains.</returns>
/// <param name="point">Point.</param>
public bool Contains (Vector2 point) {
Vector2 portedPoint = point - offset;
if (portedPoint.magnitude > magnitude)
return false;
float alpha = Mathf.Atan2 (portedPoint.y, portedPoint.x);
float gamma = angle - (alpha * Mathf.Rad2Deg) + (aperture * 0.5f);
while (gamma >= 360)
gamma -= 360;
while (gamma <= -360)
gamma += 360;
return gamma > 0 && gamma <= aperture;
}
#endregion
}
using UnityEngine;
/// <summary>
/// Field View 2D Test.
///
/// <para>
/// Script to test the field view 2D structure in a game object.
/// </para>
///
/// <para> By Javier García | @jvrgms | 2019 </para>
/// </summary>
[RequireComponent (typeof (Collider2D))]
public class FieldView2DTest: MonoBehaviour {
#region Class Methods
// Parameters to read physics.
[Space, Header ("Physic Inputs")]
[SerializeField]
private FieldView2D topView = FieldView2D.Top;
[SerializeField]
private FieldView2D bottomView = FieldView2D.Bottom;
[SerializeField]
private FieldView2D rightView = FieldView2D.Right;
[SerializeField]
private FieldView2D leftView = FieldView2D.Left;
// Bools to track walls and surfaces.
[SerializeField]
protected bool facingTop, facingBottom, facingRight, facingLeft;
private new Collider2D collider; // Collider attached.
private ContactPoint2D[] contacts; // Array to store contacts.
private int contactCounter; // Number of contact points.
private readonly int contactsLimit = 10; // Limit of contact points.
#endregion
#region MonoBehaviour Methods
// Called on inspector to draw gizmos.
private void OnDrawGizmos () {
topView.Draw (transform.position);
bottomView.Draw (transform.position);
rightView.Draw (transform.position);
leftView.Draw (transform.position);
}
// Called on awake.
private void Awake () {
collider = GetComponent<Collider2D> ();
contacts = new ContactPoint2D[contactsLimit];
}
// Update is called once per frame
private void Update () {
ReadInputPhysics ();
}
#endregion
#region Class Implementation
// Method to read physics interactions.
private void ReadInputPhysics () {
contactCounter = collider.GetContacts (contacts);
facingTop = facingBottom = facingLeft = facingRight = false;
for (int i = 0; i < contactCounter; i++) {
Vector2 point = transform.InverseTransformPoint (contacts[i].point);
facingTop |= topView.Contains (point);
facingBottom |= bottomView.Contains (point);
facingRight |= rightView.Contains (point);
facingLeft |= leftView.Contains (point);
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment