Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathanGorr/140684ecf6dd626c76bd7b91158b7eb2 to your computer and use it in GitHub Desktop.
Save JonathanGorr/140684ecf6dd626c76bd7b91158b7eb2 to your computer and use it in GitHub Desktop.
Made this script compatible for 3d use.
/*
Created by: Juan Sebastian Munoz Arango
naruse@gmail.com
2014
www.pencilsquaregames.com
Feel free to use it for your personal / commercial projects.
a mention of the source would be nice but if you dont feel like
its alright.
NOT for resale this on the asset store tho but can be part of your package
without any issue.
*/
/*
Edited by: Jonathan Gorr
jonathangorr@gmail.com
2017
www.jonathangorr.com
Changes:
1. Made it compatible for 3d AND 2d use.
2. Added bools.
3. Changed the green debug line to point towards the testPoint.
One problem: the arch doesn't reproduce well in 2d view.
*/
using UnityEngine;
using System.Collections;
public class FieldOfView : MonoBehaviour {
public bool debug = false; //turns on prints for info
public bool visible = false; //useful to show when the test point is in view
[Range(0.1f, 10f)]
public float radius = 1;
[Range(1.0f, 360f)]
public int fov = 90;//90 degrees
public Vector3 direction = -Vector3.forward;
float floorOffset = .01f; //how much to raise the debug rays off the ground to avoid zfighting
//used to test the FOV
public Transform testPoint;
private Vector3 leftLineFOV;
private Vector3 rightLineFOV;
public bool InsideFOV(Vector3 playerPos)
{
float squaredDistance = ((playerPos.x - transform.position.x)*(playerPos.x - transform.position.x)) + ((playerPos.z-transform.position.z)*(playerPos.z-transform.position.z));
//Debug.Log(squaredDistance);
if(radius * radius >= squaredDistance)
{
visible = true;
float signLeftLine = (leftLineFOV.x) * (playerPos.z - transform.position.z) - (leftLineFOV.z) * (playerPos.x-transform.position.x);
float signRightLine = (rightLineFOV.x) * (playerPos.z - transform.position.z) - (rightLineFOV.z) * (playerPos.x-transform.position.x);
if(fov <= 180)
{
if(debug) Debug.Log(signLeftLine + " " + signRightLine);
if(signLeftLine <= 0 && signRightLine >= 0)
return true;
}
else
{
if(!(signLeftLine >= 0 && signRightLine <= 0))
return true;
}
}
visible = false;
return false;
}
//Rotate point (px, py) around point (ox, oy) by angle theta you'll get:
//p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
//p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
private Vector3 RotatePointAroundTransform(Vector3 p, float angles)
{
return new Vector3(
Mathf.Cos((angles) * Mathf.Deg2Rad) * (p.x) - Mathf.Sin((angles) * Mathf.Deg2Rad) * (p.z),
p.y,
Mathf.Sin((angles) * Mathf.Deg2Rad) * (p.x) + Mathf.Cos((angles) * Mathf.Deg2Rad) * (p.z));
}
void OnDrawGizmos()
{
//draw forward green vector
Gizmos.color = Color.blue;
Gizmos.DrawRay(transform.position + new Vector3(0, floorOffset, 0), direction.normalized*(radius/3));
//draw a line pointing to the testPoint
if(testPoint != null)
{
rightLineFOV = RotatePointAroundTransform(direction.normalized*radius, -fov/2);
leftLineFOV = RotatePointAroundTransform(direction.normalized*radius, fov/2);
if(InsideFOV(new Vector3(testPoint.position.x, transform.position.z, testPoint.position.z)))
{
Gizmos.color = Color.green;
Vector3 d = testPoint.position - transform.position;
Gizmos.DrawRay(transform.position + new Vector3(0, floorOffset, 0), d.normalized*radius);
}
}
rightLineFOV = RotatePointAroundTransform(direction.normalized*radius, -fov/2);
leftLineFOV = RotatePointAroundTransform(direction.normalized*radius, fov/2);
//draw FOV cutoff angles
Gizmos.color = Color.yellow;
Gizmos.DrawRay(transform.position + new Vector3(0, floorOffset, 0), rightLineFOV);
Gizmos.DrawRay(transform.position + new Vector3(0, floorOffset, 0), leftLineFOV);
//draw arc or radius end
Vector3 p = rightLineFOV;
int arcResolution = 20;
for(int i = 1; i <= arcResolution; i++)
{
float step = fov/arcResolution;
Vector3 p1 = RotatePointAroundTransform(direction.normalized*radius, -fov/2 + step*(i));
Gizmos.DrawRay(new Vector3(transform.position.x, transform.position.y + floorOffset, transform.position.z) + p, p1-p);
p = p1;
}
Gizmos.DrawRay(new Vector3(transform.position.x, transform.position.y + floorOffset, transform.position.z) + p, leftLineFOV - p);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment