void setLight () { bool sortAngles = false; allVertices.Clear();// Since these lists are populated every frame, clear them first to prevent overpopulation layer = 1 << 8; //--Step 2: Obtain vertices for each mesh --// //---------------------------------------------------------------------// // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) bool lows = false; // check si hay menores a -0.5 bool his = false; // check si hay mayores a 2.0 float magRange = 0.15f; List <verts> tempVerts = new List<verts>(); for (int m = 0; m < allMeshes.Length; m++) { //for (int m = 0; m < 1; m++) { tempVerts.Clear(); PolygonCollider2D mf = allMeshes[m]; // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) lows = false; // check si hay menores a -0.5 his = false; // check si hay mayores a 2.0 if(((1 << mf.transform.gameObject.layer) & layer) != 0){ for (int i = 0; i < mf.GetTotalPointCount(); i++) { // ...and for ever vertex we have of each mesh filter... verts v = new verts(); // Convert to world space Vector3 worldPoint = mf.transform.TransformPoint(mf.points[i]); // Reforma fecha 24/09/2014 (ultimo argumento lighradius X worldPoint.magnitude (expensivo pero preciso)) RaycastHit2D ray = Physics2D.Raycast(transform.position, worldPoint - transform.position, (worldPoint - transform.position).magnitude, layer); if(ray){ v.pos = ray.point; if( worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange) ) v.endpoint = true; }else{ v.pos = worldPoint; v.endpoint = true; } Debug.DrawLine(transform.position, v.pos, Color.white); //--Convert To local space for build mesh (mesh craft only in local vertex) v.pos = transform.InverseTransformPoint(v.pos); //--Calculate angle v.angle = getVectorAngle(true,v.pos.x, v.pos.y); // -- bookmark if an angle is lower than 0 or higher than 2f --// //-- helper method for fix bug on shape located in 2 or more quadrants if(v.angle < 0f ) lows = true; if(v.angle > 2f) his = true; //--Add verts to the main array if((v.pos).sqrMagnitude <= lightRadius*lightRadius){ tempVerts.Add(v); } if(sortAngles == false) sortAngles = true; } } // Indentify the endpoints (left and right) if(tempVerts.Count > 0){ sortList(tempVerts); // sort first int posLowAngle = 0; // save the indice of left ray int posHighAngle = 0; // same last in right side //Debug.Log(lows + " " + his); if(his == true && lows == true){ //-- FIX BUG OF SORTING CUANDRANT 1-4 --// float lowestAngle = -1f;//tempVerts[0].angle; // init with first data float highestAngle = tempVerts[0].angle; for(int d=0; d<tempVerts.Count; d++){ if(tempVerts[d].angle < 1f && tempVerts[d].angle > lowestAngle){ lowestAngle = tempVerts[d].angle; posLowAngle = d; } if(tempVerts[d].angle > 2f && tempVerts[d].angle < highestAngle){ highestAngle = tempVerts[d].angle; posHighAngle = d; } } }else{ //-- convencional position of ray points // save the indice of left ray posLowAngle = 0; posHighAngle = tempVerts.Count-1; } tempVerts[posLowAngle].location = 1; // right tempVerts[posHighAngle].location = -1; // left //--Add vertices to the main meshes vertexes--// allVertices.AddRange(tempVerts); //allVertices.Add(tempVerts[0]); //allVertices.Add(tempVerts[tempVerts.Count - 1]); // -- r ==0 --> right ray // -- r ==1 --> left ray for(int r = 0; r<2; r++){ //-- Cast a ray in same direction continuos mode, start a last point of last ray --// Vector3 fromCast = new Vector3(); bool isEndpoint = false; if(r==0){ fromCast = transform.TransformPoint(tempVerts[posLowAngle].pos); isEndpoint = tempVerts[posLowAngle].endpoint; }else if(r==1){ fromCast = transform.TransformPoint(tempVerts[posHighAngle].pos); isEndpoint = tempVerts[posHighAngle].endpoint; } if(isEndpoint == true){ Vector3 dir = (fromCast - transform.position); fromCast += (dir * .01f); float mag = (lightRadius);// - fromCast.magnitude; RaycastHit2D rayCont = Physics2D.Raycast(fromCast, dir, mag, layer); //Debug.DrawLine(fromCast, dir.normalized*mag ,Color.green); Vector3 hitp; if(rayCont){ hitp = rayCont.point; }else{ hitp = transform.TransformPoint( dir.normalized * mag); } Debug.DrawLine(fromCast, hitp, Color.green); verts vL = new verts(); vL.pos = transform.InverseTransformPoint(hitp); vL.angle = getVectorAngle(true,vL.pos.x, vL.pos.y); allVertices.Add(vL); } } } } //--Step 3: Generate vectors for light cast--// //---------------------------------------------------------------------// int theta = 0; //float amount = (Mathf.PI * 2) / lightSegments; int amount = 360 / lightSegments; for (int i = 0; i < lightSegments; i++) { theta =amount * (i); if(theta == 360) theta = 0; verts v = new verts(); //v.pos = new Vector3((Mathf.Sin(theta)), (Mathf.Cos(theta)), 0); // in radians low performance v.pos = new Vector3((PseudoSinCos.SinArray[theta]), (PseudoSinCos.CosArray[theta]), 0); // in dregrees (previous calculate) v.angle = getVectorAngle(true,v.pos.x, v.pos.y); v.pos *= lightRadius; v.pos += transform.position; RaycastHit2D ray = Physics2D.Raycast(transform.position,v.pos - transform.position,lightRadius, layer); //Debug.DrawRay(transform.position, v.pos - transform.position, Color.white); if (!ray){ //Debug.DrawLine(transform.position, v.pos, Color.white); v.pos = transform.InverseTransformPoint(v.pos); allVertices.Add(v); } } //-- Step 4: Sort each vertice by angle (along sweep ray 0 - 2PI)--// //---------------------------------------------------------------------// if (sortAngles == true) { sortList(allVertices); } //----------------------------------------------------------------------------- //--auxiliar step (change order vertices close to light first in position when has same direction) --// float rangeAngleComparision = 0.00001f; for(int i = 0; i< allVertices.Count-1; i+=1){ verts uno = allVertices[i]; verts dos = allVertices[i +1]; // -- Comparo el angulo local de cada vertex y decido si tengo que hacer un exchange-- // if(uno.angle >= dos.angle-rangeAngleComparision && uno.angle <= dos.angle + rangeAngleComparision){ if(dos.location == -1){ // Right Ray if(uno.pos.sqrMagnitude > dos.pos.sqrMagnitude){ allVertices[i] = dos; allVertices[i+1] = uno; //Debug.Log("changing left"); } } // ALREADY DONE!! if(uno.location == 1){ // Left Ray if(uno.pos.sqrMagnitude < dos.pos.sqrMagnitude){ allVertices[i] = dos; allVertices[i+1] = uno; //Debug.Log("changing"); } } } } }
void setLight() { bool sortAngles = false; allVertices.Clear();// Since these lists are populated every frame, clear them first to prevent overpopulation layer = 1 << 32; //--Step 2: Obtain vertices for each mesh --// //---------------------------------------------------------------------// // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) bool lows = false; // check si hay menores a -0.5 bool his = false; // check si hay mayores a 2.0 float magRange = 0.15f; List <verts> tempVerts = new List <verts>(); for (int m = 0; m < allMeshes.Length; m++) { //for (int m = 0; m < 1; m++) { tempVerts.Clear(); PolygonCollider2D mf = allMeshes[m]; // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) lows = false; // check si hay menores a -0.5 his = false; // check si hay mayores a 2.0 if (((1 << mf.transform.gameObject.layer) & layer) != 0) { for (int i = 0; i < mf.GetTotalPointCount(); i++) { // ...and for ever vertex we have of each mesh filter... verts v = new verts(); // Convert to world space Vector3 worldPoint = mf.transform.TransformPoint(mf.points[i]); // Reforma fecha 24/09/2014 (ultimo argumento lighradius X worldPoint.magnitude (expensivo pero preciso)) RaycastHit2D ray = Physics2D.Raycast(transform.position, worldPoint - transform.position, (worldPoint - transform.position).magnitude, layer); if (ray) { v.pos = ray.point; if (worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange)) { v.endpoint = true; } } else { v.pos = worldPoint; v.endpoint = true; } Debug.DrawLine(transform.position, v.pos, Color.white); //--Convert To local space for build mesh (mesh craft only in local vertex) v.pos = transform.InverseTransformPoint(v.pos); //--Calculate angle v.angle = getVectorAngle(true, v.pos.x, v.pos.y); // -- bookmark if an angle is lower than 0 or higher than 2f --// //-- helper method for fix bug on shape located in 2 or more quadrants if (v.angle < 0f) { lows = true; } if (v.angle > 2f) { his = true; } //--Add verts to the main array if ((v.pos).sqrMagnitude <= lightRadius * lightRadius) { tempVerts.Add(v); } if (sortAngles == false) { sortAngles = true; } } } // Indentify the endpoints (left and right) if (tempVerts.Count > 0) { sortList(tempVerts); // sort first int posLowAngle = 0; // save the indice of left ray int posHighAngle = 0; // same last in right side //Debug.Log(lows + " " + his); if (his == true && lows == true) { //-- FIX BUG OF SORTING CUANDRANT 1-4 --// float lowestAngle = -1f; //tempVerts[0].angle; // init with first data float highestAngle = tempVerts[0].angle; for (int d = 0; d < tempVerts.Count; d++) { if (tempVerts[d].angle <1f && tempVerts[d].angle> lowestAngle) { lowestAngle = tempVerts[d].angle; posLowAngle = d; } if (tempVerts[d].angle > 2f && tempVerts[d].angle < highestAngle) { highestAngle = tempVerts[d].angle; posHighAngle = d; } } } else { //-- convencional position of ray points // save the indice of left ray posLowAngle = 0; posHighAngle = tempVerts.Count - 1; } tempVerts[posLowAngle].location = 1; // right tempVerts[posHighAngle].location = -1; // left //--Add vertices to the main meshes vertexes--// allVertices.AddRange(tempVerts); //allVertices.Add(tempVerts[0]); //allVertices.Add(tempVerts[tempVerts.Count - 1]); // -- r ==0 --> right ray // -- r ==1 --> left ray for (int r = 0; r < 2; r++) { //-- Cast a ray in same direction continuos mode, start a last point of last ray --// Vector3 fromCast = new Vector3(); bool isEndpoint = false; if (r == 0) { fromCast = transform.TransformPoint(tempVerts[posLowAngle].pos); isEndpoint = tempVerts[posLowAngle].endpoint; } else if (r == 1) { fromCast = transform.TransformPoint(tempVerts[posHighAngle].pos); isEndpoint = tempVerts[posHighAngle].endpoint; } if (isEndpoint == true) { Vector3 dir = (fromCast - transform.position); fromCast += (dir * .01f); float mag = (lightRadius);// - fromCast.magnitude; RaycastHit2D rayCont = Physics2D.Raycast(fromCast, dir, mag, layer); //Debug.DrawLine(fromCast, dir.normalized*mag ,Color.green); Vector3 hitp; if (rayCont) { hitp = rayCont.point; } else { hitp = transform.TransformPoint(dir.normalized * mag); } Debug.DrawLine(fromCast, hitp, Color.green); verts vL = new verts(); vL.pos = transform.InverseTransformPoint(hitp); vL.angle = getVectorAngle(true, vL.pos.x, vL.pos.y); allVertices.Add(vL); } } } } //--Step 3: Generate vectors for light cast--// //---------------------------------------------------------------------// int theta = 0; //float amount = (Mathf.PI * 2) / lightSegments; int amount = 360 / lightSegments; for (int i = 0; i < lightSegments; i++) { theta = amount * (i); if (theta == 360) { theta = 0; } verts v = new verts(); v.pos = new Vector3((Mathf.Sin(theta)), (Mathf.Cos(theta)), 0); // in radians low performance //v.pos = new Vector3((PseudoSinCos.SinArray[theta]), (PseudoSinCos.CosArray[theta]), 0); // in dregrees (previous calculate) v.angle = getVectorAngle(true, v.pos.x, v.pos.y); v.pos *= lightRadius; v.pos += transform.position; RaycastHit2D ray = Physics2D.Raycast(transform.position, v.pos - transform.position, lightRadius, layer); //Debug.DrawRay(transform.position, v.pos - transform.position, Color.white); if (!ray) { //Debug.DrawLine(transform.position, v.pos, Color.white); v.pos = transform.InverseTransformPoint(v.pos); allVertices.Add(v); } } //-- Step 4: Sort each vertice by angle (along sweep ray 0 - 2PI)--// //---------------------------------------------------------------------// if (sortAngles == true) { sortList(allVertices); } //----------------------------------------------------------------------------- //--auxiliar step (change order vertices close to light first in position when has same direction) --// float rangeAngleComparision = 0.00001f; for (int i = 0; i < allVertices.Count - 1; i += 1) { verts uno = allVertices[i]; verts dos = allVertices[i + 1]; // -- Comparo el angulo local de cada vertex y decido si tengo que hacer un exchange-- // if (uno.angle >= dos.angle - rangeAngleComparision && uno.angle <= dos.angle + rangeAngleComparision) { if (dos.location == -1) { // Right Ray if (uno.pos.sqrMagnitude > dos.pos.sqrMagnitude) { allVertices[i] = dos; allVertices[i + 1] = uno; //Debug.Log("changing left"); } } // ALREADY DONE!! if (uno.location == 1) { // Left Ray if (uno.pos.sqrMagnitude < dos.pos.sqrMagnitude) { allVertices[i] = dos; allVertices[i + 1] = uno; //Debug.Log("changing"); } } } } }
void SetLine() { bool sortAngles = false; bool lows = false; bool his = false; allVertices.Clear(); List <verts> tempVerts = new List <verts>(); for (int i = 0; i < allMeshes.Length; i++) { tempVerts.Clear(); PolygonCollider2D mesh = allMeshes[i]; lows = false; his = false; // 障害物のメッシュの頂点からライトまでの計算 if (((1 << mesh.transform.gameObject.layer) & layer) != 0) { for (int j = 0; j < mesh.GetTotalPointCount(); j++) { verts vert = new verts(); Vector3 worldPoint = mesh.transform.TransformPoint(mesh.points[j]); RaycastHit2D ray = Physics2D.Raycast(transform.position, worldPoint - transform.position, lightRadius, layer); if (ray) { vert.pos = ray.point; if ((worldPoint.sqrMagnitude >= ray.point.sqrMagnitude - 0.15f) && worldPoint.sqrMagnitude <= ray.point.sqrMagnitude + 0.15f) { vert.endpoint = true; } } else { vert.pos = worldPoint; vert.endpoint = true; } // 相対位置に変更と角度計算 vert.pos = transform.InverseTransformPoint(vert.pos); vert.angle = getVectorAngle(true, vert.pos.x, vert.pos.y); // 頂点の位置 if (vert.angle < 0f) { lows = true; } if (vert.angle > 2f) { his = true; } // 半径内の頂点を記録する if (vert.pos.sqrMagnitude <= lightRadius * lightRadius) { tempVerts.Add(vert); Debug.DrawLine(transform.position, transform.TransformPoint(vert.pos), Color.white); } if (sortAngles == false) { sortAngles = true; } } } // メッシュ頂点の位置を判断 if (tempVerts.Count > 0) { sortList(tempVerts); // 角度を大きいから小さいに並ぶ int posLowAngle = 0; int posHighAngle = 0; // 頂点がライトの第三、第四象限に存在する場合の調整 if (his && lows) { float lowestAngle = -1f; // 右 float highestAngle = tempVerts[0].angle; // 左 for (int k = 0; k < tempVerts.Count; k++) { if (tempVerts[k].angle <1f && tempVerts[k].angle> lowestAngle) { lowestAngle = tempVerts[k].angle; posLowAngle = k; } if (tempVerts[k].angle > 2f && tempVerts[k].angle < highestAngle) { highestAngle = tempVerts[k].angle; posHighAngle = k; } } } else { posLowAngle = 0; posHighAngle = tempVerts.Count - 1; } tempVerts[posLowAngle].location = 1; // 右 tempVerts[posHighAngle].location = -1; // 左 allVertices.AddRange(tempVerts); // メッシュ二つ頂点に当たったRayの延長 for (int r = 0; r < 2; r++) { Vector3 fromRay = new Vector3(); bool isEndpoint = false; // 0はlow,1はhight if (r == 0) { fromRay = transform.TransformPoint(tempVerts[posLowAngle].pos); isEndpoint = tempVerts[posLowAngle].endpoint; } else { fromRay = transform.TransformPoint(tempVerts[posHighAngle].pos); isEndpoint = tempVerts[posHighAngle].endpoint; } // もし頂点に当たったら if (isEndpoint) { Vector2 from = fromRay; Vector2 dir = (from - (Vector2)transform.position); float endPointRayOffset = 0.001f; // endPointのオフセット from += (dir * endPointRayOffset); RaycastHit2D rayCont = Physics2D.Raycast(from, dir, lightRadius, layer); Vector3 hitPoint; if (rayCont) { hitPoint = rayCont.point; } else { Vector2 newDir = transform.InverseTransformVector(dir); hitPoint = transform.TransformPoint(newDir.normalized * lightRadius); } if ((hitPoint - transform.position).sqrMagnitude > (lightRadius * lightRadius)) { dir = transform.InverseTransformDirection(dir); hitPoint = transform.TransformPoint(dir.normalized * lightRadius); } Debug.DrawLine(from, hitPoint, Color.green); // 相対位置と角度 verts newVert = new verts(); newVert.pos = transform.InverseTransformPoint(hitPoint); newVert.angle = getVectorAngle(true, newVert.pos.x, newVert.pos.y); allVertices.Add(newVert); } } } } // ---------------------------------- // // ライト照射範囲の頂点を生成 // ---------------------------------- // int theta = 0; // ライトメッシュの頂点数 int vertAmout = 360 / lightSegments; for (int i = 0; i < lightSegments; i++) { theta = vertAmout * i; if (theta == 360) { theta = 0; } // ライト照射範囲の頂点情報 verts vert = new verts(); vert.pos = new Vector3(SenArray[theta], CosArray[theta], 0); vert.angle = getVectorAngle(true, vert.pos.x, vert.pos.y); vert.pos *= lightRadius; vert.pos += transform.position; RaycastHit2D ray = Physics2D.Raycast(transform.position, vert.pos - transform.position, lightRadius, layer); if (!ray) { vert.pos = transform.InverseTransformPoint(vert.pos); allVertices.Add(vert); } } // 角度順に再排列 if (sortAngles == true) { sortList(allVertices); } // 二つの頂点が同じ方向の時の調整 float rangeAngleComparision = 0.00001f; for (int i = 0; i < allVertices.Count - 1; i++) { verts before = allVertices[i]; verts after = allVertices[i + 1]; // 調整するかどうかの判定 if (before.angle >= after.angle - rangeAngleComparision && before.angle <= after.angle + rangeAngleComparision) { // 右 if (after.location == -1) { if (before.pos.sqrMagnitude > after.pos.sqrMagnitude) { allVertices[i] = after; allVertices[i + 1] = before; } } // 左 if (before.location == 1) { if (before.pos.sqrMagnitude < after.pos.sqrMagnitude) { allVertices[i] = after; allVertices[i + 1] = before; } } } } }
void setLight () { bool sortAngles = false; //objectsReached.Clear(); // sweep all last objects reached allVertices.Clear();// Since these lists are populated every frame, clear them first to prevent overpopulation //--Step 2: Obtain vertices for each mesh --// //---------------------------------------------------------------------// // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) bool lows = false; // check si hay menores a -0.5 bool his = false; // check si hay mayores a 2.0 float magRange = 0.15f; // -- CLEAR TEMPVERTS --// ver 1.1.0v tempVerts.Clear(); // reset counter vertices; vertexWorking = 0; for (int m = 0; m < allMeshes.Length; m++) { //for (int m = 0; m < 1; m++) { tempVerts.Clear(); PolygonCollider2D mf = allMeshes[m]; // -- DELETE CASTER MANUALLY --// if(mf == null){ // se ha eliminado un caster reloadMeshes = true; return; } // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) lows = false; // check si hay menores a -0.5 his = false; // check si hay mayores a 2.0 if(notifyGameObjectsReached == true) // work only in neccesary cases -- optimization ver 1.1.0-- objReached.Clear(); // Method for check every point in each collider // if is closer from light, any point, then add collider to work. bool mfInWorks = false; for (int i = 0; i < mf.GetTotalPointCount(); i++) { Vector3 worldPoint = mf.transform.TransformPoint(mf.points[i]); if((worldPoint - gameObject.transform.position).sqrMagnitude <= lightRadius* lightRadius){ // -- Here check if first collider point is in Z=0 pos --// for depth position if(flipXYtoXZ){ if(mf.transform.TransformPoint(mf.points[i]).y == gameObject.transform.position.y){ mfInWorks = true; i = mf.GetTotalPointCount(); } }else{ if(mf.transform.TransformPoint(mf.points[i]).z == gameObject.transform.position.z){ mfInWorks = true; i = mf.GetTotalPointCount(); } } } } if(mfInWorks == true) { if(((1 << mf.transform.gameObject.layer) & Layer) != 0){ // Add all vertices that interact vertexWorking += mf.GetTotalPointCount(); for (int i = 0; i < mf.GetTotalPointCount(); i++) { // ...and for ever vertex we have of each mesh filter... verts v = new verts(); Vector2 worldPoint = (Vector2)mf.transform.TransformPoint(mf.points[i]); Vector2 to = worldPoint - (Vector2)transform.position; // Reforma fecha 24/09/2014 (ultimo argumento lighradius X worldPoint.magnitude (expensivo pero preciso)) RaycastHit2D ray = Physics2D.Raycast(transform.position, to, to.magnitude, Layer); if(ray){ v.pos = ray.point; //v.pos = new Vector3(v.pos.x,v.pos.y,transform.position.z); // add depth //Debug.Log(v.pos + "world"); if( worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange) ) v.endpoint = true; if(notifyGameObjectsReached == true){ // work only in neccesary cases -- optimization ver 1.1.0-- if(360 != Mathf.RoundToInt(RangeAngle)){ if (Vector3.Angle(transform.InverseTransformPoint(v.pos), Vector3.up) < RangeAngle*.5f) { // Light angle restriction //-- GO reached --> adding to mail list --// objReached.Add(ray.collider.gameObject.transform.parent.gameObject); } }else{ //-- GO reached --> adding to main list --// objReached.Add(ray.collider.gameObject.transform.parent.gameObject); } } }else{ v.pos = worldPoint; v.endpoint = true; } //--Convert To local space for build mesh (mesh craft only in local vertex) v.pos = new Vector3(v.pos.x,v.pos.y, gameObject.transform.position.z); if(debugLines == true) Debug.DrawLine(transform.position, v.pos, Color.white); v.pos = transform.InverseTransformPoint(v.pos); //--Calculate angle v.angle = getVectorAngle(true,v.pos.x, v.pos.y); // -- bookmark if an angle is lower than 0 or higher than 2f --// //-- helper method for fix bug on shape located in 2 or more quadrants if(v.angle < 0f ) lows = true; if(v.angle > 2f) his = true; //--Add verts to the main array //-- AVOID EXTRA CALCULOUS OF Vector3.angle --// if(360 != Mathf.RoundToInt(RangeAngle)){ if (Vector3.Angle(v.pos, Vector3.up) < RangeAngle*.5f) { // Light angle restriction if((v.pos).sqrMagnitude <= lightRadius*lightRadius){ tempVerts.Add(v); if(debugLines == true) Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white); } } }else{ if((v.pos).sqrMagnitude <= lightRadius*lightRadius){ tempVerts.Add(v); if(debugLines == true) Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white); } } if(sortAngles == false) sortAngles = true; } } // Indentify the endpoints (left and right) if(tempVerts.Count > 0){ sortList(tempVerts); // sort first int posLowAngle = 0; // save the indice of left ray int posHighAngle = 0; // same last in right side //Debug.Log(lows + " " + his); if(his == true && lows == true){ //-- FIX BUG OF SORTING CUANDRANT 1-4 --// if(tempVerts.Count > 1){ float lowestAngle = -1f;//tempVerts[0].angle; // init with first data float highestAngle = tempVerts[0].angle; for(int d=0; d<tempVerts.Count; d++){ if(tempVerts[d].angle < 1f && tempVerts[d].angle > lowestAngle){ lowestAngle = tempVerts[d].angle; posLowAngle = d; } if(tempVerts[d].angle > 2f && tempVerts[d].angle < highestAngle){ highestAngle = tempVerts[d].angle; posHighAngle = d; } } } }else{ //-- convencional position of ray points // save the indice of left ray posLowAngle = 0; posHighAngle = tempVerts.Count-1; } //-- fix error when sort vertex with only 1 tempvert AND rangeAngle < 360 --// // -------- ver 1.0.7 ---------// //--------------------------------------------------------------------------// int endPointLimit = 2; if(tempVerts.Count == 1){ endPointLimit = 1; tempVerts[0].location = 7; // --lucky se7en // --------------------------------------------------------------------------------------------- // // --------------------------------------------------------------------------------------------- // }else{ // -- more than one... --// tempVerts[posLowAngle].location = 1; // right tempVerts[posHighAngle].location = -1; // left } //--Add vertices to the main meshes vertexes--// if(intelliderConvex == true && endPointLimit > 1){ allVertices.Add(tempVerts[posLowAngle]); allVertices.Add(tempVerts[posHighAngle]); }else{ allVertices.AddRange(tempVerts); } // -- r ==0 --> right ray // -- r ==1 --> left ray for(int r = 0; r<endPointLimit; r++){ //-- Cast a ray in same direction continuos mode, start a last point of last ray --// Vector3 fromCast = new Vector3(); bool isEndpoint = false; if(r==0){ fromCast = transform.TransformPoint(tempVerts[posLowAngle].pos); isEndpoint = tempVerts[posLowAngle].endpoint; }else if(r==1){ fromCast = transform.TransformPoint(tempVerts[posHighAngle].pos); isEndpoint = tempVerts[posHighAngle].endpoint; } if(isEndpoint == true){ Vector2 from = (Vector2) fromCast; Vector2 dir = (from - (Vector2)transform.position); from += (dir * .001f); float mag = (lightRadius);// - fromCast.magnitude; //float mag = fromCast.magnitude; RaycastHit2D rayCont = Physics2D.Raycast(from, dir, mag, Layer); Vector2 hitp; if(rayCont){ //-- IMPROVED REACHED OBJECTS --// VERSION 1.1.2 hitp = rayCont.point; //world p /* if(notifyGameObjectsReached == true){ // work only in neccesary cases -- optimization ver 1.1.0-- if((hitp - (Vector2)transform.position ).sqrMagnitude < (lightRadius * lightRadius)){ // Version 1.3.0 if(360 != Mathf.RoundToInt(RangeAngle)){ if (Vector3.Angle(transform.InverseTransformPoint(hitp), Vector3.up) < RangeAngle*.5f) { // Light angle restriction //-- GO reached --> adding to mail list --// //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject); Debug.Log("caca"); } }else{ //-- GO reached --> adding to mail list --// //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject); } } } */ if(debugLines == true) Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.green); }else{ //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2 --// //-- NEW INSTANCE OF DIR VECTOR3 ADDED --// Vector2 newDir = transform.InverseTransformDirection(dir); //local p hitp = (Vector2)transform.TransformPoint( newDir.normalized * mag); //world p if(debugLines == true) Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.blue); } // --- VER 1.0.6 -- // //--- this fix magnitud of end point ray (green) ---// if((hitp - (Vector2)transform.position ).sqrMagnitude > (lightRadius * lightRadius)){ //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2 --// dir = (Vector2)transform.InverseTransformDirection(dir); //local p hitp = (Vector2)transform.TransformPoint( dir.normalized * mag); } Vector3 v3Hitp = new Vector3(hitp.x, hitp.y, transform.position.z); verts vL = new verts(); vL.pos = (Vector3) transform.InverseTransformPoint(v3Hitp); vL.angle = getVectorAngle(true,vL.pos.x, vL.pos.y); allVertices.Add(vL); } } } if(notifyGameObjectsReached == true){ //notify if not null if(OnReachedGameObjects != null){ OnReachedGameObjects(objReached.ToArray()); } } } } //--Step 3: Generate vectors for light cast--// //---------------------------------------------------------------------// int theta = 0; // int amount = 360 / lightSegments; float amount = RangeAngle / lightSegments; for (int i = 0; i <= lightSegments; i++) { theta = Mathf.RoundToInt(amount * i); if(theta >= 360) theta = 0; verts v = new verts(); // Initialize static tables TablaSenoCoseno.initSenCos(); v.pos = new Vector3((TablaSenoCoseno.SenArray[theta]), (TablaSenoCoseno.CosArray[theta]), 0); // in dregrees (previous calculate) Quaternion quat = Quaternion.AngleAxis(RangeAngle*.5f + transform.eulerAngles.z, Vector3.forward); v.pos = quat * v.pos; v.pos *= lightRadius; v.pos += transform.position; Vector3 to = v.pos - transform.position; to.z = gameObject.transform.position.z; RaycastHit2D ray = Physics2D.Raycast(transform.position,to,lightRadius, Layer); //Debug.DrawLine(transform.position, to, Color.blue); if (ray && (to.z == transform.position.z)){ v.pos = transform.InverseTransformPoint(ray.point); v.pos = new Vector3(v.pos.x, v.pos.y, 0); v.angle = getVectorAngle(true,v.pos.x, v.pos.y); allVertices.Add(v); } else { v.pos = transform.InverseTransformPoint(v.pos); v.angle = getVectorAngle(true,v.pos.x, v.pos.y);// store angle without object rotation -> consistency for sorting allVertices.Add(v); } if(debugLines == true) Debug.DrawLine(transform.position, transform.TransformPoint(new Vector3(v.pos.x,v.pos.y, 0)), Color.cyan); } //-- Step 4: Sort each vertice by angle (along sweep ray 0 - 2PI)--// //---------------------------------------------------------------------// //if (sortAngles == true) { sortList(allVertices); //} //----------------------------------------------------------------------------- //--auxiliar step (change order vertices close to light first in position when has same direction) --// float rangeAngleComparision = 0.0001f; for(int i = 0; i< allVertices.Count; i+=1){ verts uno = allVertices[i]; verts dos = allVertices[(i +1) % allVertices.Count]; // -- Comparo el angulo local de cada vertex y decido si tengo que hacer un exchange-- // if(uno.angle >= (dos.angle-rangeAngleComparision) && uno.angle <= (dos.angle + rangeAngleComparision)){ // -- FIX BUG 1.0.7 ( exchange when rangeAngle is less than 360) -- // // ----------------------------------------------------------------- // if(uno.location == 7){ //Debug.Log("7"); if(uno.angle <= allVertices[allVertices.Count/2].angle){ uno.location = 1; }else{ uno.location = -1; } } if(dos.location == 7){ //Debug.Log("7"); if(dos.angle <= allVertices[allVertices.Count/2].angle){ dos.location = 1; }else{ dos.location = -1; } } //--------------------------------------------------------------------------// //--------------------------------------------------------------------------// if(dos.location == -1){ // Right Ray if(uno.pos.sqrMagnitude > dos.pos.sqrMagnitude){ allVertices[i] = dos; allVertices[(i +1) % allVertices.Count] = uno; } } // ALREADY DONE!! if(uno.location == 1){ // Left Ray if(uno.pos.sqrMagnitude < dos.pos.sqrMagnitude){ allVertices[i] = dos; allVertices[(i +1) % allVertices.Count] = uno; } } } } }
void setLight() { bool sortAngles = false; //objectsReached.Clear(); // sweep all last objects reached allVertices.Clear(); // Since these lists are populated every frame, clear them first to prevent overpopulation //--Step 2: Obtain vertices for each mesh --// //---------------------------------------------------------------------// // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) bool lows = false; // check si hay menores a -0.5 bool his = false; // check si hay mayores a 2.0 float magRange = 0.15f; // -- CLEAR TEMPVERTS --// ver 1.1.0v tempVerts.Clear(); // reset counter vertices; vertexWorking = 0; for (int m = 0; m < allMeshes.Length; m++) { //for (int m = 0; m < 1; m++) { tempVerts.Clear(); PolygonCollider2D mf = allMeshes[m]; // -- DELETE CASTER MANUALLY --// if (mf == null) { // se ha eliminado un caster reloadMeshes = true; return; } // las siguientes variables usadas para arregla bug de ordenamiento cuando // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4) lows = false; // check si hay menores a -0.5 his = false; // check si hay mayores a 2.0 if (notifyGameObjectsReached == true) // work only in neccesary cases -- optimization ver 1.1.0-- { objReached.Clear(); } // Method for check every point in each collider // if is closer from light, any point, then add collider to work. bool mfInWorks = false; for (int i = 0; i < mf.GetTotalPointCount(); i++) { Vector3 worldPoint = mf.transform.TransformPoint(mf.points[i]); if ((worldPoint - gameObject.transform.position).sqrMagnitude <= lightRadius * lightRadius) { // -- Here check if first collider point is in Z=0 pos --// for depth position if (flipXYtoXZ) { if (mf.transform.TransformPoint(mf.points[i]).y == gameObject.transform.position.y) { mfInWorks = true; i = mf.GetTotalPointCount(); } } else { if (mf.transform.TransformPoint(mf.points[i]).z == gameObject.transform.position.z) { mfInWorks = true; i = mf.GetTotalPointCount(); } } } } if (mfInWorks == true) { if (((1 << mf.transform.gameObject.layer) & Layer) != 0) { // Add all vertices that interact vertexWorking += mf.GetTotalPointCount(); for (int i = 0; i < mf.GetTotalPointCount(); i++) // ...and for ever vertex we have of each mesh filter... { verts v = new verts(); Vector2 worldPoint = (Vector2)mf.transform.TransformPoint(mf.points[i]); Vector2 to = worldPoint - (Vector2)transform.position; // Reforma fecha 24/09/2014 (ultimo argumento lighradius X worldPoint.magnitude (expensivo pero preciso)) RaycastHit2D ray = Physics2D.Raycast(transform.position, to, to.magnitude, Layer); if (ray) { v.pos = ray.point; //v.pos = new Vector3(v.pos.x,v.pos.y,transform.position.z); // add depth //Debug.Log(v.pos + "world"); if (worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange)) { v.endpoint = true; } if (notifyGameObjectsReached == true) // work only in neccesary cases -- optimization ver 1.1.0-- { if (360 != Mathf.RoundToInt(RangeAngle)) { if (Vector3.Angle(transform.InverseTransformPoint(v.pos), Vector3.up) < RangeAngle * .5f) // Light angle restriction //-- GO reached --> adding to mail list --// { objReached.Add(ray.collider.gameObject.transform.parent.gameObject); } } else { //-- GO reached --> adding to main list --// objReached.Add(ray.collider.gameObject.transform.parent.gameObject); } } } else { v.pos = worldPoint; v.endpoint = true; } //--Convert To local space for build mesh (mesh craft only in local vertex) v.pos = new Vector3(v.pos.x, v.pos.y, gameObject.transform.position.z); if (debugLines == true) { Debug.DrawLine(transform.position, v.pos, Color.white); } v.pos = transform.InverseTransformPoint(v.pos); //--Calculate angle v.angle = getVectorAngle(true, v.pos.x, v.pos.y); // -- bookmark if an angle is lower than 0 or higher than 2f --// //-- helper method for fix bug on shape located in 2 or more quadrants if (v.angle < 0f) { lows = true; } if (v.angle > 2f) { his = true; } //--Add verts to the main array //-- AVOID EXTRA CALCULOUS OF Vector3.angle --// if (360 != Mathf.RoundToInt(RangeAngle)) { if (Vector3.Angle(v.pos, Vector3.up) < RangeAngle * .5f) // Light angle restriction { if ((v.pos).sqrMagnitude <= lightRadius * lightRadius) { tempVerts.Add(v); if (debugLines == true) { Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white); } } } } else { if ((v.pos).sqrMagnitude <= lightRadius * lightRadius) { tempVerts.Add(v); if (debugLines == true) { Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white); } } } if (sortAngles == false) { sortAngles = true; } } } // Indentify the endpoints (left and right) if (tempVerts.Count > 0) { sortList(tempVerts); // sort first int posLowAngle = 0; // save the indice of left ray int posHighAngle = 0; // same last in right side //Debug.Log(lows + " " + his); if (his == true && lows == true) //-- FIX BUG OF SORTING CUANDRANT 1-4 --// { if (tempVerts.Count > 1) { float lowestAngle = -1f; //tempVerts[0].angle; // init with first data float highestAngle = tempVerts[0].angle; for (int d = 0; d < tempVerts.Count; d++) { if (tempVerts[d].angle <1f && tempVerts[d].angle> lowestAngle) { lowestAngle = tempVerts[d].angle; posLowAngle = d; } if (tempVerts[d].angle > 2f && tempVerts[d].angle < highestAngle) { highestAngle = tempVerts[d].angle; posHighAngle = d; } } } } else { //-- convencional position of ray points // save the indice of left ray posLowAngle = 0; posHighAngle = tempVerts.Count - 1; } //-- fix error when sort vertex with only 1 tempvert AND rangeAngle < 360 --// // -------- ver 1.0.7 ---------// //--------------------------------------------------------------------------// int endPointLimit = 2; if (tempVerts.Count == 1) { endPointLimit = 1; tempVerts[0].location = 7; // --lucky se7en // --------------------------------------------------------------------------------------------- // // --------------------------------------------------------------------------------------------- // } else { // -- more than one... --// tempVerts[posLowAngle].location = 1; // right tempVerts[posHighAngle].location = -1; // left } //--Add vertices to the main meshes vertexes--// if (intelliderConvex == true && endPointLimit > 1) { allVertices.Add(tempVerts[posLowAngle]); allVertices.Add(tempVerts[posHighAngle]); } else { allVertices.AddRange(tempVerts); } // -- r ==0 --> right ray // -- r ==1 --> left ray for (int r = 0; r < endPointLimit; r++) { //-- Cast a ray in same direction continuos mode, start a last point of last ray --// Vector3 fromCast = new Vector3(); bool isEndpoint = false; if (r == 0) { fromCast = transform.TransformPoint(tempVerts[posLowAngle].pos); isEndpoint = tempVerts[posLowAngle].endpoint; } else if (r == 1) { fromCast = transform.TransformPoint(tempVerts[posHighAngle].pos); isEndpoint = tempVerts[posHighAngle].endpoint; } if (isEndpoint == true) { Vector2 from = (Vector2)fromCast; Vector2 dir = (from - (Vector2)transform.position); from += (dir * .001f); float mag = (lightRadius); // - fromCast.magnitude; //float mag = fromCast.magnitude; RaycastHit2D rayCont = Physics2D.Raycast(from, dir, mag, Layer); Vector2 hitp; if (rayCont) { //-- IMPROVED REACHED OBJECTS --// VERSION 1.1.2 hitp = rayCont.point; //world p /* * if(notifyGameObjectsReached == true){ // work only in neccesary cases -- optimization ver 1.1.0-- * if((hitp - (Vector2)transform.position ).sqrMagnitude < (lightRadius * lightRadius)){ * // Version 1.3.0 * if(360 != Mathf.RoundToInt(RangeAngle)){ * if (Vector3.Angle(transform.InverseTransformPoint(hitp), Vector3.up) < RangeAngle*.5f) { // Light angle restriction * //-- GO reached --> adding to mail list --// * //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject); * Debug.Log("caca"); * } * }else{ * //-- GO reached --> adding to mail list --// * //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject); * } * } * } */ if (debugLines == true) { Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.green); } } else { //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2 --// //-- NEW INSTANCE OF DIR VECTOR3 ADDED --// Vector2 newDir = transform.InverseTransformDirection(dir); //local p hitp = (Vector2)transform.TransformPoint(newDir.normalized * mag); //world p if (debugLines == true) { Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.blue); } } // --- VER 1.0.6 -- // //--- this fix magnitud of end point ray (green) ---// if ((hitp - (Vector2)transform.position).sqrMagnitude > (lightRadius * lightRadius)) { //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2 --// dir = (Vector2)transform.InverseTransformDirection(dir); //local p hitp = (Vector2)transform.TransformPoint(dir.normalized * mag); } Vector3 v3Hitp = new Vector3(hitp.x, hitp.y, transform.position.z); verts vL = new verts(); vL.pos = (Vector3)transform.InverseTransformPoint(v3Hitp); vL.angle = getVectorAngle(true, vL.pos.x, vL.pos.y); allVertices.Add(vL); } } } if (notifyGameObjectsReached == true) { //notify if not null if (OnReachedGameObjects != null) { OnReachedGameObjects(objReached.ToArray()); } } } } //--Step 3: Generate vectors for light cast--// //---------------------------------------------------------------------// int theta = 0; // int amount = 360 / lightSegments; float amount = RangeAngle / lightSegments; for (int i = 0; i <= lightSegments; i++) { theta = Mathf.RoundToInt(amount * i); if (theta >= 360) { theta = 0; } verts v = new verts(); // Initialize static tables TablaSenoCoseno.initSenCos(); v.pos = new Vector3((TablaSenoCoseno.SenArray[theta]), (TablaSenoCoseno.CosArray[theta]), 0); // in dregrees (previous calculate) Quaternion quat = Quaternion.AngleAxis(RangeAngle * .5f + transform.eulerAngles.z, Vector3.forward); v.pos = quat * v.pos; v.pos *= lightRadius; v.pos += transform.position; Vector3 to = v.pos - transform.position; to.z = gameObject.transform.position.z; RaycastHit2D ray = Physics2D.Raycast(transform.position, to, lightRadius, Layer); //Debug.DrawLine(transform.position, to, Color.blue); if (ray && (to.z == transform.position.z)) { v.pos = transform.InverseTransformPoint(ray.point); v.pos = new Vector3(v.pos.x, v.pos.y, 0); v.angle = getVectorAngle(true, v.pos.x, v.pos.y); allVertices.Add(v); } else { v.pos = transform.InverseTransformPoint(v.pos); v.angle = getVectorAngle(true, v.pos.x, v.pos.y); // store angle without object rotation -> consistency for sorting allVertices.Add(v); } if (debugLines == true) { Debug.DrawLine(transform.position, transform.TransformPoint(new Vector3(v.pos.x, v.pos.y, 0)), Color.cyan); } } //-- Step 4: Sort each vertice by angle (along sweep ray 0 - 2PI)--// //---------------------------------------------------------------------// //if (sortAngles == true) { sortList(allVertices); //} //----------------------------------------------------------------------------- //--auxiliar step (change order vertices close to light first in position when has same direction) --// float rangeAngleComparision = 0.0001f; for (int i = 0; i < allVertices.Count; i += 1) { verts uno = allVertices[i]; verts dos = allVertices[(i + 1) % allVertices.Count]; // -- Comparo el angulo local de cada vertex y decido si tengo que hacer un exchange-- // if (uno.angle >= (dos.angle - rangeAngleComparision) && uno.angle <= (dos.angle + rangeAngleComparision)) { // -- FIX BUG 1.0.7 ( exchange when rangeAngle is less than 360) -- // // ----------------------------------------------------------------- // if (uno.location == 7) { //Debug.Log("7"); if (uno.angle <= allVertices[allVertices.Count / 2].angle) { uno.location = 1; } else { uno.location = -1; } } if (dos.location == 7) { //Debug.Log("7"); if (dos.angle <= allVertices[allVertices.Count / 2].angle) { dos.location = 1; } else { dos.location = -1; } } //--------------------------------------------------------------------------// //--------------------------------------------------------------------------// if (dos.location == -1) // Right Ray { if (uno.pos.sqrMagnitude > dos.pos.sqrMagnitude) { allVertices[i] = dos; allVertices[(i + 1) % allVertices.Count] = uno; } } // ALREADY DONE!! if (uno.location == 1) // Left Ray { if (uno.pos.sqrMagnitude < dos.pos.sqrMagnitude) { allVertices[i] = dos; allVertices[(i + 1) % allVertices.Count] = uno; } } } } }
/// <summary> /// Найти точки, что составляют меша света /// </summary> void SetLight () { bool sortAngles = false; allVertices.Clear(); //layer = 1 << 8; //Шаг 2: Обработать все вершины мешей препятствий bool quad4 = false; bool quad3 = false; float magRange = magnitudeRange; List <verts> tempVerts = new List<verts>(); for (int m = 0; m < allMeshes.Length; m++) { tempVerts.Clear(); Collider2D mf = allMeshes[m]; //Булевы переменные, которые указывают на принадлежность меша к квадрантам quad4 = false;//Есть ли у меша точки, принадлежащие 4-ому квадранту (x>0, y<0) quad3 = false;//Есть ли у меша точки, принадлежащие 3-ему квадранту (x<0, y<0) if (((1 << mf.transform.gameObject.layer) & layer) != 0) { int pointCount = 0; Vector2[] points = null; if (mf is PolygonCollider2D) { PolygonCollider2D pCol = (PolygonCollider2D)mf; pointCount = pCol.GetTotalPointCount(); points = pCol.points; } else if (mf is BoxCollider2D) { pointCount = 4; points = GetBoxColPoints((BoxCollider2D)mf); } else continue; for (int i = 0; i < pointCount; i++) { verts v = new verts(); // Перейти к мировым координатам Vector3 worldPoint = mf.transform.TransformPoint(points[i]); RaycastHit2D ray = Physics2D.Raycast(transform.position, worldPoint - transform.position, (worldPoint - transform.position).magnitude, layer); if(ray) { v.pos = ray.point; if( worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange) ) v.endpoint = true; } else { v.pos = worldPoint; v.endpoint = true; } Debug.DrawLine(transform.position, v.pos, Color.white); //Перейти к локальной системе координат v.pos = transform.InverseTransformPoint(v.pos); //Расчитать углы v.angle = GetVectorAngle(true,v.pos.x, v.pos.y); if(v.angle < 0f ) quad4 = true; if(v.angle > 2f) quad3 = true; //Добавить обработанные вершины в общий список if((v.pos).sqrMagnitude <= lightRadius*lightRadius) { tempVerts.Add(v); } if(sortAngles == false) sortAngles = true; } } // Установить типы конечных точек if(tempVerts.Count > 0){ tempVerts.Sort((item1, item2) => (item2.angle.CompareTo(item1.angle))); int posLowAngle = 0; // save the indice of left ray int posHighAngle = 0; // same last in right side //Debug.Log(lows + " " + his); if(quad3 && quad4) { float lowestAngle = -1f; float highestAngle = tempVerts[0].angle; for(int i=0; i<tempVerts.Count; i++){ if(tempVerts[i].angle < 1f && tempVerts[i].angle > lowestAngle) { lowestAngle = tempVerts[i].angle; posLowAngle = i; } if(tempVerts[i].angle > 2f && tempVerts[i].angle < highestAngle){ highestAngle = tempVerts[i].angle; posHighAngle = i; } } } else { posLowAngle = 0; posHighAngle = tempVerts.Count-1; } tempVerts[posLowAngle].location = 1; // правая точка tempVerts[posHighAngle].location = -1; // левая точка //Запомнить отсортированные точки для главного меша света allVertices.AddRange(tempVerts); //allVertices.Add(tempVerts[0]); //allVertices.Add(tempVerts[tempVerts.Count - 1]); for(int r = 0; r<2; r++) { //найти крайнюю точку меша тени, созданную мешем препятствия под светом источника Vector3 fromCast = transform.TransformPoint(tempVerts[r==0? posLowAngle: posHighAngle].pos); bool isEndpoint = tempVerts[r == 0 ? posLowAngle : posHighAngle].endpoint; if (isEndpoint) { Vector2 from = (Vector2)fromCast; Vector2 dir = from - (Vector2)transform.position; float mag = lightRadius; const float checkPointLastRayOffset= 0.005f; from += (dir * checkPointLastRayOffset); RaycastHit2D rayCont = Physics2D.Raycast(from, dir, mag, layer); Vector3 hitp; if(rayCont) { hitp = rayCont.point; } else { Vector2 newDir = transform.InverseTransformDirection(dir); hitp = (Vector2)transform.TransformPoint( newDir.normalized * mag); } if(((Vector2)hitp - (Vector2)transform.position ).sqrMagnitude > lightRadius * lightRadius) { dir = (Vector2)transform.InverseTransformDirection(dir); //local p hitp = (Vector2)transform.TransformPoint( dir.normalized * mag); } Debug.DrawLine(fromCast, hitp, Color.green); verts vL = new verts(); vL.pos = transform.InverseTransformPoint(hitp); vL.angle = GetVectorAngle(true,vL.pos.x, vL.pos.y); allVertices.Add(vL); } } } } //Шаг 3: Добавить вектора, что обрамляют меш света int theta = 0; //float amount = (Mathf.PI * 2) / lightSegments; int amount = 360 / lightSegments; for (int i = 0; i < lightSegments; i++) { theta =amount * (i); if(theta == 360) theta = 0; verts v = new verts(); //v.pos = new Vector3((Mathf.Sin(theta)), (Mathf.Cos(theta)), 0); // реализация в радианах (медленно, но точно) v.pos = new Vector3((PseudoSinCos.SinArray[theta]), (PseudoSinCos.CosArray[theta]), 0); // реализация в градусах (быстро, но с погрешностями) v.angle = GetVectorAngle(true,v.pos.x, v.pos.y); v.pos *= lightRadius; v.pos += transform.position; RaycastHit2D ray = Physics2D.Raycast(transform.position,v.pos - transform.position,lightRadius, layer); if (!ray) { v.pos = transform.InverseTransformPoint(v.pos); allVertices.Add(v); } } //Шаг 4: отсортировать массив вершин по углам if (sortAngles) { allVertices.Sort((item1, item2) => (item2.angle.CompareTo(item1.angle))); } //Дополнительный шаг изменить порядок вершин с учетом тех из них, что имеют одно и то же направление от источника света float rangeAngleComparision = 0.00001f; for(int i = 0; i< allVertices.Count-1; i++) { verts point1 = allVertices[i]; verts point2 = allVertices[i +1]; if(Mathf.Abs(point1.angle - point2.angle)<=rangeAngleComparision) { if(point2.location == -1)// Крайняя правая точка от меша тени препятствия { if(point1.pos.sqrMagnitude > point2.pos.sqrMagnitude) { allVertices[i] = point2; allVertices[i+1] = point1; } } //Бесполезен ли этот блок кода? может и нет) if(point1.location == 1)// Крайняя левая точка от меша тени препятствия { if(point1.pos.sqrMagnitude < point2.pos.sqrMagnitude) { allVertices[i] = point2; allVertices[i+1] = point1; } } } } }