Exemple #1
0
	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");
					}
				}
				
				
				
			}


		}



	}
Exemple #2
0
    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");
                    }
                }
            }
        }
    }
Exemple #3
0
    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;

					}
				}
				
				
				
			}


		}



	}
Exemple #5
0
    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;
					}
				}
			}
		}
	}