надоело пользоваться всякими GL\Graphics (которые у меня постоянно не работают из-за кривых рук)...
Лучше рендерить квад в камеру, а потом выводить его в экранных координатах на процедурном плейнике!
Что делает скрипт:
Выводит в указанном ректе экрана квад с нужным материалом (если меняем рект - квад обновляется).
Планирую часто использовать эту технологию в работе, поэтому бекаплю здесь на всякий пожарный (и может кому-то будет полезно).
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProceduralScreenQuad : MonoBehaviour
{
public Rect rect = new Rect(100,100,256,256);
Rect old_rect;
MeshFilter mf;
public Camera cam;
void Start()
{
mf = gameObject.GetComponent<MeshFilter>();
old_rect = rect;
GenerateQuad(rect);
//cam = Camera.main;
// мега хак... репортнуть
transform.Translate(new Vector3(0,0,0));
}
void Update()
{
if (rect != old_rect)
{
ChangeQuadRect(rect);
}
old_rect = rect;
}
void ChangeQuadRect(Rect newRect)
{
Vector2[] rect_points = GetPointsFromRect(newRect);
Vector3[] verts = GetWorldPointsFromScreenPoints(rect_points);
mf.mesh.vertices = verts;
}
void GenerateQuad(Rect newRect)
{
Mesh mesh = new Mesh();
Vector2[] uvs = new Vector2[]{ new Vector2(0,0), new Vector2(1,0), new Vector2(0,1), new Vector2(1,1)};
//1 quad * 2 triangles * 3 vert.indices per triangle
int[] tris = new int[]{ 2,1,0,
3,1,2 };
Vector2[] rect_points = GetPointsFromRect(newRect);
Vector3[] verts = GetWorldPointsFromScreenPoints(rect_points);
mesh.vertices = verts;
mesh.uv = uvs;
mesh.triangles = tris;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mf.mesh = mesh;
}
Vector3[] GetWorldPointsFromScreenPoints(Vector2[] rect_points)
{
Vector3[] verts = new Vector3[4];
for (int i = 0; i < 4; i++)
{
verts[i] = cam.ScreenToWorldPoint(new Vector3(rect_points[i].x, rect_points[i].y, 2f));
verts[i] = transform.InverseTransformPoint(verts[i]);
}
return verts;
}
Vector2[] GetPointsFromRect(Rect newRect)
{
Vector2[] points = new Vector2[4];
points[0] = new Vector2(newRect.x, newRect.y);
points[1] = new Vector2(newRect.xMax, newRect.y);
points[2] = new Vector2(newRect.x, newRect.yMax);
points[3] = new Vector2(newRect.xMax, newRect.yMax);
return points;
}
}
using System.Collections;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProceduralScreenQuad : MonoBehaviour
{
public Rect rect = new Rect(100,100,256,256);
Rect old_rect;
MeshFilter mf;
public Camera cam;
void Start()
{
mf = gameObject.GetComponent<MeshFilter>();
old_rect = rect;
GenerateQuad(rect);
//cam = Camera.main;
// мега хак... репортнуть
transform.Translate(new Vector3(0,0,0));
}
void Update()
{
if (rect != old_rect)
{
ChangeQuadRect(rect);
}
old_rect = rect;
}
void ChangeQuadRect(Rect newRect)
{
Vector2[] rect_points = GetPointsFromRect(newRect);
Vector3[] verts = GetWorldPointsFromScreenPoints(rect_points);
mf.mesh.vertices = verts;
}
void GenerateQuad(Rect newRect)
{
Mesh mesh = new Mesh();
Vector2[] uvs = new Vector2[]{ new Vector2(0,0), new Vector2(1,0), new Vector2(0,1), new Vector2(1,1)};
//1 quad * 2 triangles * 3 vert.indices per triangle
int[] tris = new int[]{ 2,1,0,
3,1,2 };
Vector2[] rect_points = GetPointsFromRect(newRect);
Vector3[] verts = GetWorldPointsFromScreenPoints(rect_points);
mesh.vertices = verts;
mesh.uv = uvs;
mesh.triangles = tris;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mf.mesh = mesh;
}
Vector3[] GetWorldPointsFromScreenPoints(Vector2[] rect_points)
{
Vector3[] verts = new Vector3[4];
for (int i = 0; i < 4; i++)
{
verts[i] = cam.ScreenToWorldPoint(new Vector3(rect_points[i].x, rect_points[i].y, 2f));
verts[i] = transform.InverseTransformPoint(verts[i]);
}
return verts;
}
Vector2[] GetPointsFromRect(Rect newRect)
{
Vector2[] points = new Vector2[4];
points[0] = new Vector2(newRect.x, newRect.y);
points[1] = new Vector2(newRect.xMax, newRect.y);
points[2] = new Vector2(newRect.x, newRect.yMax);
points[3] = new Vector2(newRect.xMax, newRect.yMax);
return points;
}
}