8 hours Code/Asset
While not perfect this works as a functioning shield that creates a dynamic mesh. All you need is to place this onto a child empty object then place a material on it. Then modify it to the right size.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshRenderer))]
public class CircleMesh : MonoBehaviour
{
public int elements = 60;
public float startAngle = 0f;
private float internalStartAngle = -1f;
public float endAngle = 360f;
private float internalEndAngle = -1f;
public float innerRadius = 50f;
private float savedInnerRadius = 50f;
public float circleWidth = 10f;
private float savedCircleWidth = 10f;
private float circleRadius = 360f;
public bool addCaps = false;
private Vector3[] allVertices = new Vector3[0];
private Vector2[] allUVs = new Vector2[0];
private int[] allTriangles = new int[0];
public Vector2 uv1 = new Vector2(0f, 0f);
public Vector2 uv2 = new Vector2(0f, 1f);
public Mesh mesh = null;
public bool createNewMeshInAwake = true;
public bool fullCircle = true;
private bool savedFullCircle = false;
public int count = 0;
private int savedCount = -1;
private bool busy = false;
void Awake()
{
if (createNewMeshInAwake)
{
MeshFilter mF = transform.GetComponent<MeshFilter>();
if (mF) mF.sharedMesh = null;
mesh = null;
RecalculateMesh();
}
}
void Update()
{
if (startAngle != internalStartAngle || endAngle != internalEndAngle || innerRadius != savedInnerRadius || circleWidth != savedCircleWidth || mesh == null)
{
RecalculateMesh(uv1, uv2, (mesh == null) ? true : false);
transform.rotation = Quaternion.Euler(90, 0, (endAngle / 2) - (circleRadius / elements /2));
}
}
public void ForceRefreshMesh()
{
StartCoroutine(ForceRefreshMeshNow());
}
IEnumerator ForceRefreshMeshNow()
{
while (busy) yield return null;
RecalculateMesh(uv1, uv2, true);
}
void RecalculateMesh()
{
RecalculateMesh(uv1, uv2, false);
}
void RecalculateMesh(Vector2 uvOne, Vector2 uvTwo, bool forceRefresh)
{
if (busy) return;
busy = true;
float degreeStep = 360f / elements;
internalStartAngle = startAngle;
internalEndAngle = endAngle;
if (internalEndAngle > 360f) internalEndAngle = 360f;
if (internalStartAngle < 0f) internalStartAngle = 0f;
if (internalStartAngle > 0f || internalEndAngle < 360f) fullCircle = false;
else fullCircle = true;
count = 0;
float deg = 0f;
for (int c = 0; c < elements; c++)
{
if (deg >= internalStartAngle && deg <= internalEndAngle) count++;
deg += degreeStep;
}
if (count < 2)
{
GetComponent<Renderer>().enabled = false;
busy = false;
return;
}
else GetComponent<Renderer>().enabled = true;
if (!forceRefresh && count == savedCount && fullCircle == savedFullCircle && innerRadius == savedInnerRadius && circleWidth == savedCircleWidth)
{
busy = false;
return;
}
savedCount = count;
savedFullCircle = fullCircle;
savedInnerRadius = innerRadius;
savedCircleWidth = circleWidth;
if (addCaps && !fullCircle) count += 2;
allVertices = new Vector3[count * 2];
allUVs = new Vector2[count * 2];
int numTris = count * 6;
if (!fullCircle) numTris -= 6;
allTriangles = new int[numTris];
if (addCaps && !fullCircle) count -= 2;
if (!gameObject.GetComponent("MeshFilter")) gameObject.AddComponent<MeshFilter>();
if (!gameObject.GetComponent("MeshRenderer")) gameObject.AddComponent<MeshRenderer>();
if (!mesh) mesh = GetComponent<MeshFilter>().sharedMesh;
if (!mesh)
{
mesh = new Mesh();
mesh.name = "Circle Mesh for " + gameObject.name;
GetComponent<MeshFilter>().sharedMesh = mesh;
}
mesh.Clear();
Quaternion quat = Quaternion.identity;
deg = 0f;
while (deg < internalStartAngle) deg += degreeStep;
for (int i = 0; i < count * 2; i += 2)
{
quat = Quaternion.AngleAxis(deg, -Vector3.forward);
allVertices[i] = quat * new Vector3(0f, innerRadius, 0f);
allVertices[i + 1] = quat * new Vector3(0f, innerRadius + circleWidth, 0f);
allUVs[i] = uvOne;
allUVs[i + 1] = uvTwo;
int nextDown = i + 2;
int nextUp = i + 3;
if (i + 2 >= count * 2)
{
nextUp = 1; nextDown = 0;
}
if (i + 2 >= count * 2 && !fullCircle) break;
allTriangles[(i * 3)] = i;
allTriangles[(i * 3) + 1] = i + 1;
allTriangles[(i * 3) + 2] = nextUp;
allTriangles[(i * 3) + 3] = i;
allTriangles[(i * 3) + 4] = nextUp;
allTriangles[(i * 3) + 5] = nextDown;
deg += degreeStep;
}
if (addCaps && !fullCircle)
{
float capAngleOffset = Mathf.Lerp(2f, 30f, circleWidth / innerRadius);
quat = Quaternion.AngleAxis(internalStartAngle - capAngleOffset, -Vector3.forward);
allVertices[count * 2] = quat * new Vector3(0f, innerRadius, 0f);
allVertices[count * 2 + 1] = quat * new Vector3(0f, innerRadius + circleWidth, 0f);
allUVs[count * 2] = uvOne + new Vector2(1f, 0f);
allUVs[count * 2 + 1] = uvTwo + new Vector2(1f, 0f);
allTriangles[(count * 2 * 3)] = count * 2;
allTriangles[(count * 2 * 3) + 1] = count * 2 + 1;
allTriangles[(count * 2 * 3) + 2] = 0;
allTriangles[(count * 2 * 3) + 3] = count * 2 + 1;
allTriangles[(count * 2 * 3) + 4] = 1;
allTriangles[(count * 2 * 3) + 5] = 0;
quat = Quaternion.AngleAxis(internalEndAngle + capAngleOffset, -Vector3.forward);
allVertices[count * 2 + 2] = quat * new Vector3(0f, innerRadius, 0f);
allVertices[count * 2 + 3] = quat * new Vector3(0f, innerRadius + circleWidth, 0f);
allUVs[count * 2 + 2] = uvOne + new Vector2(1f, 0f);
allUVs[count * 2 + 3] = uvTwo + new Vector2(1f, 0f);
allTriangles[(count * 2 * 3) - 6] = count * 2 - 2;
allTriangles[(count * 2 * 3) - 5] = count * 2 - 1;
allTriangles[(count * 2 * 3) - 4] = count * 2 + 3;
allTriangles[(count * 2 * 3) - 3] = count * 2 - 2;
allTriangles[(count * 2 * 3) - 2] = count * 2 + 3;
allTriangles[(count * 2 * 3) - 1] = count * 2 + 2;
}
mesh.vertices = allVertices;
mesh.uv = allUVs;
mesh.triangles = allTriangles;
mesh.bounds = new Bounds(Vector3.zero, new Vector3(innerRadius + circleWidth, 0.1f, innerRadius + circleWidth));
busy = false;
}
}
Thursday, 23 April 2015
Thursday, 2 April 2015
Unity 5: Create Mesh then Deform It
3 hours Code/Asset
Ok where to start, I have been busy following a tutorial and have come up with this, this code creates a cube then when you click on different vertices it makes the selected vertices go up or down in real time. I have been working on my commenting. It still needs more work.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DeformableMesh : MonoBehaviour
{
public float pointDeformation = 0.01f;
Mesh mesh;
Material mat;
List<Vector3> Points;
List<Vector3> Verts;
List<int> Tris;
List<Vector2> UVs;
float size = 0.5f;
// Use to set up refernces between scripts Awake is called before Start.
// Is called after all objects are initialzed but before scripts are run.
void Awake ()
{
}
// Use this for initialization
void Start ()
{
Points = new List<Vector3>();
//Setting the poistions of the verts
Points.Add(new Vector3(-size, size,-size));
Points.Add(new Vector3( size, size,-size));
Points.Add(new Vector3( size,-size,-size));
Points.Add(new Vector3(-size,-size,-size));
Points.Add(new Vector3( size, size, size));
Points.Add(new Vector3(-size, size, size));
Points.Add(new Vector3(-size,-size, size));
Points.Add(new Vector3( size,-size, size));
Verts = new List<Vector3>();
Tris = new List<int>();
UVs = new List<Vector2>();
CreateMesh();
}
// Render update is called once per frame
void Update ()
{
// Controls to raise and lower points
// If its not working check the mesh collider mesh slot
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit ))
{
RaisePoint(FindNearestPoint(hit.point));
Debug.Log(hit.point);
}
}
if (Input.GetMouseButton(1))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
LowerPoint(FindNearestPoint(hit.point));
}
}
}
// Pysics update is called once per 1/60 seconds
void FixedUpdate ()
{
}
private Vector3 FindNearestPoint(Vector3 point)
{
Vector3 NearestPoint = new Vector3();
float lastDistance = 99999999f;
for (int i = 0; i < Points.Count; i++)
{
float distance = GetDistance(point, Points[i]);
if (distance < lastDistance)
{
lastDistance = distance;
NearestPoint = Points[i];
}
}
return NearestPoint;
}
// Using math finding the distance between 2 points;
private float GetDistance(Vector3 start, Vector3 end)
{
return Mathf.Sqrt(Mathf.Pow((start.x - end.x), 2) + Mathf.Pow((start.y - end.y), 2) + Mathf.Pow((start.z - end.z), 2));
}
private void RaisePoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y += pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void LowerPoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y -= pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void CreateMesh()
{
// Adding the requite components to show a mesh
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.AddComponent<MeshCollider>();
mat = Resources.Load("Materials/Defualt") as Material;
if (mat == null)
{
Debug.LogError("Material not found");
return;
}
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter == null)
{
Debug.LogError("meshFilter not found");
return;
}
mesh = meshFilter.sharedMesh;
if (mesh == null)
{
meshFilter.mesh = new Mesh();
mesh = meshFilter.sharedMesh;
}
MeshCollider meshCollier = GetComponent<MeshCollider>();
if (meshCollier == null)
{
Debug.LogError("MeshCollider not found");
return;
}
mesh.Clear();
UpdateMesh();
}
private void UpdateMesh()
{
// Front Plane
Verts.Add(Points[0]); Verts.Add(Points[1]); Verts.Add(Points[2]); Verts.Add(Points[3]);
// Back Plane
Verts.Add(Points[4]); Verts.Add(Points[5]); Verts.Add(Points[6]); Verts.Add(Points[7]);
// Left Plane
Verts.Add(Points[5]); Verts.Add(Points[0]); Verts.Add(Points[3]); Verts.Add(Points[6]);
// Right Plane
Verts.Add(Points[1]); Verts.Add(Points[4]); Verts.Add(Points[7]); Verts.Add(Points[2]);
// Top Plane
Verts.Add(Points[5]); Verts.Add(Points[4]); Verts.Add(Points[1]); Verts.Add(Points[0]);
// Bottum Plane
Verts.Add(Points[3]); Verts.Add(Points[2]); Verts.Add(Points[7]); Verts.Add(Points[6]);
//Front Plane
Tris.Add(0); Tris.Add(1); Tris.Add(2);
Tris.Add(2); Tris.Add(3); Tris.Add(0);
//Back Plane
Tris.Add(4); Tris.Add(5); Tris.Add(6);
Tris.Add(6); Tris.Add(7); Tris.Add(4);
//Left Plane
Tris.Add(8); Tris.Add(9); Tris.Add(10);
Tris.Add(10); Tris.Add(11); Tris.Add(8);
//Right Plane
Tris.Add(12); Tris.Add(13); Tris.Add(14);
Tris.Add(14); Tris.Add(15); Tris.Add(12);
//Top Plane
Tris.Add(16); Tris.Add(17); Tris.Add(18);
Tris.Add(18); Tris.Add(19); Tris.Add(16);
//Bottum Plane
Tris.Add(20); Tris.Add(21); Tris.Add(22);
Tris.Add(22); Tris.Add(23); Tris.Add(20);
// Front Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Back Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Left Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Right Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Top Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Bottum Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
//Setting everything to arrays;
mesh.vertices = Verts.ToArray();
mesh.triangles = Tris.ToArray();
mesh.uv = UVs.ToArray();
//Clearing all the lists, so new ones can be created;
Verts.Clear();
Tris.Clear();
UVs.Clear();
//Telling unity to create the mesh with the above information
MeshCollider meshCollider = GetComponent<MeshCollider>();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
RecalculateTangents(mesh);
meshCollider.sharedMesh = null; // need to set shared mesh to null before setting the mesh.
meshCollider.sharedMesh = mesh;
gameObject.GetComponent<Renderer>().material = mat; // To access the renderer you need to get the component
mesh.Optimize();
}
//Storing the data
private static void RecalculateTangents(Mesh mesh)
{
int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;
Vector2[] uv = mesh.uv;
Vector3[] normals = mesh.normals;
int triangleCount = triangles.Length;
int vertexCount = vertices.Length;
Vector3[] tan1 = new Vector3[vertexCount];
Vector3[] tan2 = new Vector3[vertexCount];
Vector4[] tangents = new Vector4[vertexCount];
for (long a = 0; a < triangleCount; a += 3)
{
//Triangle Storage
long tris1 = triangles[a + 0];
long tris2 = triangles[a + 1];
long tris3 = triangles[a + 2];
//Vertices Storage
Vector3 verts1 = vertices[tris1];
Vector3 verts2 = vertices[tris2];
Vector3 verts3 = vertices[tris3];
//UV Storage
Vector2 w1 = uv[tris1];
Vector2 w2 = uv[tris2];
Vector2 w3 = uv[tris3];
//Verticies
float x1 = verts2.x - verts1.x;
float x2 = verts3.x - verts1.x;
float y1 = verts2.y - verts1.y;
float y2 = verts3.y - verts1.y;
float z1 = verts2.z - verts1.z;
float z2 = verts3.z - verts1.z;
//UVS
float s1 = w2.x - w1.x;
float s2 = w3.x - w1.x;
float t1 = w2.y - w1.y;
float t2 = w3.y - w1.y;
float div = s1 * t2 - s2 * t1;
float r = div == 0.0f ? 0.0f : 1.0f / div;
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
Vector3 tdir = new Vector3((s2 * x2 - s1 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
tan1[tris1] += sdir;
tan1[tris2] += sdir;
tan1[tris3] += sdir;
tan2[tris1] += tdir;
tan2[tris2] += tdir;
tan2[tris3] += tdir;
}
for (long a = 0; a < vertexCount; ++a)
{
Vector3 n = normals[a];
Vector3 t = tan1[a];
Vector3.OrthoNormalize(ref n, ref t);
tangents[a].x = t.x;
tangents[a].x = t.y;
tangents[a].x = t.z;
tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
}
mesh.tangents = tangents;
}
}
Ok where to start, I have been busy following a tutorial and have come up with this, this code creates a cube then when you click on different vertices it makes the selected vertices go up or down in real time. I have been working on my commenting. It still needs more work.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DeformableMesh : MonoBehaviour
{
public float pointDeformation = 0.01f;
Mesh mesh;
Material mat;
List<Vector3> Points;
List<Vector3> Verts;
List<int> Tris;
List<Vector2> UVs;
float size = 0.5f;
// Use to set up refernces between scripts Awake is called before Start.
// Is called after all objects are initialzed but before scripts are run.
void Awake ()
{
}
// Use this for initialization
void Start ()
{
Points = new List<Vector3>();
//Setting the poistions of the verts
Points.Add(new Vector3(-size, size,-size));
Points.Add(new Vector3( size, size,-size));
Points.Add(new Vector3( size,-size,-size));
Points.Add(new Vector3(-size,-size,-size));
Points.Add(new Vector3( size, size, size));
Points.Add(new Vector3(-size, size, size));
Points.Add(new Vector3(-size,-size, size));
Points.Add(new Vector3( size,-size, size));
Verts = new List<Vector3>();
Tris = new List<int>();
UVs = new List<Vector2>();
CreateMesh();
}
// Render update is called once per frame
void Update ()
{
// Controls to raise and lower points
// If its not working check the mesh collider mesh slot
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit ))
{
RaisePoint(FindNearestPoint(hit.point));
Debug.Log(hit.point);
}
}
if (Input.GetMouseButton(1))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
LowerPoint(FindNearestPoint(hit.point));
}
}
}
// Pysics update is called once per 1/60 seconds
void FixedUpdate ()
{
}
private Vector3 FindNearestPoint(Vector3 point)
{
Vector3 NearestPoint = new Vector3();
float lastDistance = 99999999f;
for (int i = 0; i < Points.Count; i++)
{
float distance = GetDistance(point, Points[i]);
if (distance < lastDistance)
{
lastDistance = distance;
NearestPoint = Points[i];
}
}
return NearestPoint;
}
// Using math finding the distance between 2 points;
private float GetDistance(Vector3 start, Vector3 end)
{
return Mathf.Sqrt(Mathf.Pow((start.x - end.x), 2) + Mathf.Pow((start.y - end.y), 2) + Mathf.Pow((start.z - end.z), 2));
}
private void RaisePoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y += pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void LowerPoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y -= pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void CreateMesh()
{
// Adding the requite components to show a mesh
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.AddComponent<MeshCollider>();
mat = Resources.Load("Materials/Defualt") as Material;
if (mat == null)
{
Debug.LogError("Material not found");
return;
}
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter == null)
{
Debug.LogError("meshFilter not found");
return;
}
mesh = meshFilter.sharedMesh;
if (mesh == null)
{
meshFilter.mesh = new Mesh();
mesh = meshFilter.sharedMesh;
}
MeshCollider meshCollier = GetComponent<MeshCollider>();
if (meshCollier == null)
{
Debug.LogError("MeshCollider not found");
return;
}
mesh.Clear();
UpdateMesh();
}
private void UpdateMesh()
{
// Front Plane
Verts.Add(Points[0]); Verts.Add(Points[1]); Verts.Add(Points[2]); Verts.Add(Points[3]);
// Back Plane
Verts.Add(Points[4]); Verts.Add(Points[5]); Verts.Add(Points[6]); Verts.Add(Points[7]);
// Left Plane
Verts.Add(Points[5]); Verts.Add(Points[0]); Verts.Add(Points[3]); Verts.Add(Points[6]);
// Right Plane
Verts.Add(Points[1]); Verts.Add(Points[4]); Verts.Add(Points[7]); Verts.Add(Points[2]);
// Top Plane
Verts.Add(Points[5]); Verts.Add(Points[4]); Verts.Add(Points[1]); Verts.Add(Points[0]);
// Bottum Plane
Verts.Add(Points[3]); Verts.Add(Points[2]); Verts.Add(Points[7]); Verts.Add(Points[6]);
//Front Plane
Tris.Add(0); Tris.Add(1); Tris.Add(2);
Tris.Add(2); Tris.Add(3); Tris.Add(0);
//Back Plane
Tris.Add(4); Tris.Add(5); Tris.Add(6);
Tris.Add(6); Tris.Add(7); Tris.Add(4);
//Left Plane
Tris.Add(8); Tris.Add(9); Tris.Add(10);
Tris.Add(10); Tris.Add(11); Tris.Add(8);
//Right Plane
Tris.Add(12); Tris.Add(13); Tris.Add(14);
Tris.Add(14); Tris.Add(15); Tris.Add(12);
//Top Plane
Tris.Add(16); Tris.Add(17); Tris.Add(18);
Tris.Add(18); Tris.Add(19); Tris.Add(16);
//Bottum Plane
Tris.Add(20); Tris.Add(21); Tris.Add(22);
Tris.Add(22); Tris.Add(23); Tris.Add(20);
// Front Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Back Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Left Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Right Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Top Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Bottum Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
//Setting everything to arrays;
mesh.vertices = Verts.ToArray();
mesh.triangles = Tris.ToArray();
mesh.uv = UVs.ToArray();
//Clearing all the lists, so new ones can be created;
Verts.Clear();
Tris.Clear();
UVs.Clear();
//Telling unity to create the mesh with the above information
MeshCollider meshCollider = GetComponent<MeshCollider>();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
RecalculateTangents(mesh);
meshCollider.sharedMesh = null; // need to set shared mesh to null before setting the mesh.
meshCollider.sharedMesh = mesh;
gameObject.GetComponent<Renderer>().material = mat; // To access the renderer you need to get the component
mesh.Optimize();
}
//Storing the data
private static void RecalculateTangents(Mesh mesh)
{
int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;
Vector2[] uv = mesh.uv;
Vector3[] normals = mesh.normals;
int triangleCount = triangles.Length;
int vertexCount = vertices.Length;
Vector3[] tan1 = new Vector3[vertexCount];
Vector3[] tan2 = new Vector3[vertexCount];
Vector4[] tangents = new Vector4[vertexCount];
for (long a = 0; a < triangleCount; a += 3)
{
//Triangle Storage
long tris1 = triangles[a + 0];
long tris2 = triangles[a + 1];
long tris3 = triangles[a + 2];
//Vertices Storage
Vector3 verts1 = vertices[tris1];
Vector3 verts2 = vertices[tris2];
Vector3 verts3 = vertices[tris3];
//UV Storage
Vector2 w1 = uv[tris1];
Vector2 w2 = uv[tris2];
Vector2 w3 = uv[tris3];
//Verticies
float x1 = verts2.x - verts1.x;
float x2 = verts3.x - verts1.x;
float y1 = verts2.y - verts1.y;
float y2 = verts3.y - verts1.y;
float z1 = verts2.z - verts1.z;
float z2 = verts3.z - verts1.z;
//UVS
float s1 = w2.x - w1.x;
float s2 = w3.x - w1.x;
float t1 = w2.y - w1.y;
float t2 = w3.y - w1.y;
float div = s1 * t2 - s2 * t1;
float r = div == 0.0f ? 0.0f : 1.0f / div;
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
Vector3 tdir = new Vector3((s2 * x2 - s1 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
tan1[tris1] += sdir;
tan1[tris2] += sdir;
tan1[tris3] += sdir;
tan2[tris1] += tdir;
tan2[tris2] += tdir;
tan2[tris3] += tdir;
}
for (long a = 0; a < vertexCount; ++a)
{
Vector3 n = normals[a];
Vector3 t = tan1[a];
Vector3.OrthoNormalize(ref n, ref t);
tangents[a].x = t.x;
tangents[a].x = t.y;
tangents[a].x = t.z;
tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
}
mesh.tangents = tangents;
}
}
Unity 5: Creating a Shield With Custom Polygons.
3 Hours Research
I have been looking at more ways to make a shield and the guys from Unity Answers gave me an option. http://answers.unity3d.com/questions/938443/how-do-you-create-a-custom-radial-object-or-partic.html Basicly Sunny is telling me to make my own meshes from scratch. Lucky for me I am a modeler first and know what most of what the API is telling me. Most of the research time I have put in that has led to many dead ends. I have been experimenting with this for several hours.
Creating my own meshs seems to be the answer. I will get back once I have a working prototype.
http://docs.unity3d.com/ScriptReference/Mesh.html
I have been looking at more ways to make a shield and the guys from Unity Answers gave me an option. http://answers.unity3d.com/questions/938443/how-do-you-create-a-custom-radial-object-or-partic.html Basicly Sunny is telling me to make my own meshes from scratch. Lucky for me I am a modeler first and know what most of what the API is telling me. Most of the research time I have put in that has led to many dead ends. I have been experimenting with this for several hours.
Creating my own meshs seems to be the answer. I will get back once I have a working prototype.
http://docs.unity3d.com/ScriptReference/Mesh.html
Subscribe to:
Posts (Atom)