Determinates if a Contact Point belongs to a drawed field view in a plane using just the Collider 2D.
Last active
February 18, 2023 05:10
-
-
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.
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 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 | |
} |
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 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