How to change alignment of mesh, issue with InverseTransformPoint/Vertices
Hello, I followed this tutorial => https://www.youtube.com/watch?v=73Dc5JTCmKI&t=1160s only I modified it for 2D instead and i'am having issues with the way the mesh is being displayed and positioned
I am trying to get the purple mesh cone to follow the mouse the same way as the Handles.DrawWireArc
It works the way I want in pictures 1 and 2, however if the mouse is at any other angle other than at the top or bottom the purple mesh cone appears at the other side.
I am very new to drawing meshes and don't really understand which part of the code is wrong, I believe it may be part of this code that is causing my issue, however I am unsure
void DrawFieldOfView()
{
int stepCount = Mathf.RoundToInt(viewAngle * meshResolution);
float stepAngleSize = viewAngle / stepCount;
List<Vector3> viewPoints = new List<Vector3>();
ViewCastInfo oldViewCast = new ViewCastInfo();
for (int i = 0; i <= stepCount; i++)
{
float angle = transform.eulerAngles.z - viewAngle / 2 + stepAngleSize * i;
ViewCastInfo newViewCast = ViewCast(angle);
if (i > 0)
{
bool edgeDstThresholdExceeded = Mathf.Abs(oldViewCast.dst - newViewCast.dst) > edgeDstThreshold;
if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDstThresholdExceeded))
{
EdgeInfo edge = FindEdge(oldViewCast, newViewCast);
if (edge.pointA != Vector3.zero)
{
viewPoints.Add(edge.pointA);
}
if (edge.pointB != Vector3.zero)
{
viewPoints.Add(edge.pointB);
}
}
}
viewPoints.Add(newViewCast.point);
oldViewCast = newViewCast;
}
int vertexCount = viewPoints.Count + 1;
Vector3[] vertices = new Vector3[vertexCount];
int[] triangles = new int[(vertexCount - 2) * 3];
vertices[0] = Vector3.zero;
for (int i = 0; i < vertexCount - 1; i++)
{
vertices[i + 1] = transform.InverseTransformPoint(viewPoints[i]);
if (i < vertexCount - 2)
{
triangles[i * 3] = 0;
triangles[i * 3 + 1] = i + 1;
triangles[i * 3 + 2] = i + 2;
}
}
viewMesh.Clear();
viewMesh.vertices = vertices;
viewMesh.triangles = triangles;
viewMesh.RecalculateNormals();
}
Thank you for taking the time to look at my post xxxx
Full mesh cone script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerAimingScript : MonoBehaviour
{
public float viewRadius;
[Range(0, 360)]
public float viewAngle;
public LayerMask targetMask;
public LayerMask obstacleMask;
[HideInInspector]
public List<Transform> visibleTargets = new List<Transform>();
public float meshResolution;
public int edgeResolveIterations;
public float edgeDstThreshold;
public MeshFilter viewMeshFilter;
Mesh viewMesh;
void Start()
{
viewMesh = new Mesh();
viewMesh.name = "View Mesh";
viewMeshFilter.mesh = viewMesh;
}
void LateUpdate()
{
DrawFieldOfView();
}
void DrawFieldOfView()
{
int stepCount = Mathf.RoundToInt(viewAngle * meshResolution);
float stepAngleSize = viewAngle / stepCount;
List<Vector3> viewPoints = new List<Vector3>();
ViewCastInfo oldViewCast = new ViewCastInfo();
for (int i = 0; i <= stepCount; i++)
{
float angle = transform.eulerAngles.z - viewAngle / 2 + stepAngleSize * i;
ViewCastInfo newViewCast = ViewCast(angle);
if (i > 0)
{
bool edgeDstThresholdExceeded = Mathf.Abs(oldViewCast.dst - newViewCast.dst) > edgeDstThreshold;
if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDstThresholdExceeded))
{
EdgeInfo edge = FindEdge(oldViewCast, newViewCast);
if (edge.pointA != Vector3.zero)
{
viewPoints.Add(edge.pointA);
}
if (edge.pointB != Vector3.zero)
{
viewPoints.Add(edge.pointB);
}
}
}
viewPoints.Add(newViewCast.point);
oldViewCast = newViewCast;
}
int vertexCount = viewPoints.Count + 1;
Vector3[] vertices = new Vector3[vertexCount];
int[] triangles = new int[(vertexCount - 2) * 3];
vertices[0] = Vector3.zero;
for (int i = 0; i < vertexCount - 1; i++)
{
vertices[i + 1] = transform.InverseTransformPoint(viewPoints[i]);
if (i < vertexCount - 2)
{
triangles[i * 3] = 0;
triangles[i * 3 + 1] = i + 1;
triangles[i * 3 + 2] = i + 2;
}
}
viewMesh.Clear();
viewMesh.vertices = vertices;
viewMesh.triangles = triangles;
viewMesh.RecalculateNormals();
}
EdgeInfo FindEdge(ViewCastInfo minViewCast, ViewCastInfo maxViewCast)
{
float minAngle = minViewCast.angle;
float maxAngle = maxViewCast.angle;
Vector3 minPoint = Vector3.zero;
Vector3 maxPoint = Vector3.zero;
for (int i = 0; i < edgeResolveIterations; i++)
{
float angle = (minAngle + maxAngle) / 2;
ViewCastInfo newViewCast = ViewCast(angle);
bool edgeDstThresholdExceeded = Mathf.Abs(minViewCast.dst - newViewCast.dst) > edgeDstThreshold;
if (newViewCast.hit == minViewCast.hit && !edgeDstThresholdExceeded)
{
minAngle = angle;
minPoint = newViewCast.point;
}
else
{
maxAngle = angle;
maxPoint = newViewCast.point;
}
}
return new EdgeInfo(minPoint, maxPoint);
}
ViewCastInfo ViewCast(float globalAngle)
{
Vector3 dir = DirFromAngle(globalAngle, true);
RaycastHit hit;
if (Physics.Raycast(transform.position, dir, out hit, viewRadius, obstacleMask))
{
return new ViewCastInfo(true, hit.point, hit.distance, globalAngle);
}
else
{
return new ViewCastInfo(false, transform.position + dir * viewRadius, viewRadius, globalAngle);
}
}
public Vector2 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
{
if (!angleIsGlobal)
{
angleInDegrees -= transform.eulerAngles.z;
}
return new Vector2(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), Mathf.Cos(angleInDegrees * Mathf.Deg2Rad));
}
public struct ViewCastInfo
{
public bool hit;
public Vector3 point;
public float dst;
public float angle;
public ViewCastInfo(bool _hit, Vector3 _point, float _dst, float _angle)
{
hit = _hit;
point = _point;
dst = _dst;
angle = _angle;
}
}
public struct EdgeInfo
{
public Vector3 pointA;
public Vector3 pointB;
public EdgeInfo(Vector3 _pointA, Vector3 _pointB)
{
pointA = _pointA;
pointB = _pointB;
}
}
}
Full Editor visuals script:
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(PlayerAimingScript))]
public class AimEditorScript : Editor
{
// this script creates a visual representation of the fov for the editor
void OnSceneGUI()
{
// creates the circle editor visual
PlayerAimingScript fow = (PlayerAimingScript)target;
Handles.color = Color.white;
Handles.DrawWireArc(fow.transform.position, Vector3.forward, Vector3.up, 360, fow.viewRadius);
// creates the editor view angle visual
Vector3 viewAngleA = fow.DirFromAngle(-fow.viewAngle / 2, false);
Vector3 viewAngleB = fow.DirFromAngle(fow.viewAngle / 2, false);
Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleA * fow.viewRadius);
Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleB * fow.viewRadius);
Handles.color = Color.red;
}
}
Answer by Cuckboii69 · Mar 24 at 11:36 AM
float angle = (-transform.eulerAngles.z) - viewAngle / 2 + stepAngleSize * i;