float GetDegree(Vector3 start, Vector3 end)
{
var dx = end.x - start.x;
var dz = end.z - start.z;
var degree = Mathf.Atan2(dx, dz) * Mathf.Rad2Deg;
return degree;
}
void main()
{
float range = 5;
float centerAngle = 30;
Vector3 centerPosition = new vector3 (0, 0, 0);
Vector3 mousePosition = new vector(5, 0, 2);
float R = Vector3.Distance(centerPosition, mousePosition);
float T = Mathf.Abs(GetDegree(centerPosition, mousePosition));
float tmin = Mathf.Abs(90f - (centerAngle) * 0.5f) * (T >= 0 ? 1F : -1F);
float tmax = (T >= 0 ? centerAngle : -centerAngle) + tmin;
float r = range;
float R1 = Mathf.Min(R, r);
float T1 = Mathf.Clamp(T, tmin, tmax);
float rcost = R1 * Mathf.Cos(T1);
float rsint = R1 * Mathf.Sin(T1);
Vector3 result = new vector3 (rcost, 0f, rsint);
}
using UnityEngine;
public class ImABigFan : MonoBehaviour
{
[SerializeField] Vector3 _fanOrigin = new Vector3(0,0,0);
[SerializeField] float _fanAngle = 30f;
[SerializeField] Vector2 _fanVector = new Vector3(5,0,0);
void OnDrawGizmos ()
{
Vector3 point;
{
Ray ray = UnityEditor.HandleUtility.GUIPointToWorldRay( Event.current.mousePosition );
var plane = new Plane( Vector3.up , _fanOrigin );
plane.Raycast( ray , out float dist );
point = ray.origin + ray.direction * dist;
}
float fanRadius = _fanVector.magnitude;
float angle = Vector3.Angle( _fanVector , point-_fanOrigin );
bool isPointInside = Vector3.Distance(_fanOrigin,point)<fanRadius && angle<_fanAngle*0.5;
Gizmos.color = isPointInside ? Color.green : Color.black;
Gizmos.DrawSphere( point , 0.1f );
UnityEditor.Handles.color = new Color(1f,0.92f,0.016f,0.2f);
UnityEditor.Handles.DrawSolidArc(
center: _fanOrigin ,
normal: Vector3.up ,
from: Quaternion.Euler(0,-_fanAngle*0.5f,0) * new Vector3(_fanVector.x,0,_fanVector.y) ,
angle: _fanAngle ,
radius: fanRadius
);
}
}
Hi @MaruArk , honestly I don’t know exactly what do you want to do with your script. It would be glad if you put some expressions in your picture to describe which parameter of the picture you describe in your script.
Maybe this problem seems simple, but it is not as easy as you think.
Please note the following, that reduce your problem that depends on degree to a point or vector problem. You can describe every point in the plane by P1( xcos(degree), xsinus(degree) ) when x is the distance from P0(0,0,0).
I don’t know how familiar you are with mathematics, but one thing you can do is to describe your “fan”-boundaries mathematically. Then you need to check if the current point you chose fits into the boundaries. Therefore you have to localize every point of your contour and describe the mathematical dependencies between two or more points (i.e. line, circle, second kind polynomial, third kind polynomial).
I think a more inaccurate method especially for unity is to define a custom Polygon2D or Edge2D collider with your custom shape. You can also define the shape (via path or points) in runtime. Then you can i.e. spawn a small circle collider on “click” inside the collider and let it travel between the spawn and the “click”-point direction. If it hits the Polygon2D or Edge2D collider it goes from inside to outside. Otherwise it was outside. Better maybe to let check to collision of the small collider inside continuously. If it really spawns inside the Polygon2D or Edge2D at the beginning every time collides it is outside and every time it collides again it is inside.
Once for short. You don’t want to let an object go out of the fan-shaped area.
- Describe the area with a Polygon2D or Edge2D collider
- Make sure you object is inside the area on start.
- Disable the movement of the object if it collides with the Polygon2D or Edge2D collider
By the way: you can also try to describe your problem with raycast methods.
What’s the problem - could you provide more details here? What is the current behavior?