-
-
Save JonathanGorr/140684ecf6dd626c76bd7b91158b7eb2 to your computer and use it in GitHub Desktop.
Made this script compatible for 3d use.
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
/* | |
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