Так, я не пропал! Ни на что не забил, и ничё не забил.
Я просто больше играю в игры, чем кодю.
Короче, я всё-таки реализовал новую версию процедурной
генерации визуализации сетки хождения монстра полигонами.
Она сейчас плотно связана с матрицей проходимости,
и с радиусом максимального хождения монстра (например 5*5).
Билды пока не будет, так-как всё это дело снова надо привязать
к клику по монстру, это в процессе.
Столкнулся с массой сложностей, которые пришлось решать на ходу.
Например, из-за того что я конструирую сетку хождения монстра
в цикле через FOR, ячейки создаются по очереди, и чтобы мне
в функции создать возможность проверки на то, стоит ли мне
в нужных квадратах рисовать полигоны, или нет, мне пришлось
два двумерных массива координат, перегонять в одномерные,
т.е. переводить из координатной системы, в номерную,
где номер, это номер ячейки сетки игрового поля.
С переводом координат в номера ячейки матрицы проходимости
особых сложностей не возникло, но вот вообще высчитать
радиус прорисовки вокруг монстра, а после перевести
эти координаты в номера ячеек было той ещё трёхдневной болью.
В генерации этого меша на данный момент задействовано пять массивов,
и девять различных циклов, это довольно сложная система,
и рабочая.
Испытания показали, что например меш размером в 40.000 клеток,
где у нас 80.000 треугольников, генерится довольно долго,
по этому для эпических монстров, которые ходят в любую точку
карты, я такую систему использовать не буду. Но вот меши размерами
например 25 на 25 генерятся моментально, но это вообще весь размер
игрового уровня при битве с монстрами аш пятого уровня угрозы,
даже больше, короче для стандартных битв всё годно,
для управления эпиками сделаю другую систему, об этом
пока и речи не идёт у меня.
В общем всё зер гуд, результат моих мучений здесь, комментов в них мало:
Строим матрицу проходимости:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SetkaPassabilityControl : MonoBehaviour
{
public static int[,] Setka;
public float SetkaScaleXf;
public float SetkaScaleZf;
public int SetkaScaleX;
public int SetkaScaleZ;
public int ChoTam2;
public static int SetkaScaleControl = 0;
void Update()
{
if (SetkaScaleControl == 0)
{
if (GLOBALSUPERSCRIPT.LevelScaleStatus == 1)
{
SetkaScaleXf = GLOBALSUPERSCRIPT.LevelScaleX;
SetkaScaleZf = GLOBALSUPERSCRIPT.LevelScaleZ;
SetkaScaleX = Mathf.RoundToInt(SetkaScaleXf);
SetkaScaleZ = Mathf.RoundToInt(SetkaScaleZf);
SetkaScaleControl = 1;
}
}
if (SetkaScaleControl == 1)
{
Setka = new int[(SetkaScaleX * SetkaScaleZ) - SetkaScaleX + 1, SetkaScaleZ + 1];
Setka[0, (SetkaScaleZ / 2) - 1] = 1; // Непроходимый квадрат
Setka[0, 3] = 1; // Непроходимый квадрат
SetkaScaleControl = 2;
}
ChoTam2 = Setka[SetkaScaleX - 1, (SetkaScaleZ / 2) - 1];
}
}
Генерируем область, в которую может пойти монстр:
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
public class TEST : MonoBehaviour
{
public Mesh SetkaDvij2;
public int[,] MonHodMass;
public int[] MonHodYachMass;
private int SetkaMonHodX = 5;
private int SetkaMonHodZ = 5;
public int PloshMonHodXZ;
public int Xcount = 0;
public int Zcount = 0;
public int UniversalCounter = 0; //Универсальный многоразовый счётчик для разных задачь
public int UniversalCounter2 = 0; //Универсальный многоразовый счётчик для разных задачь
public int UniversalCounter3 = 0; //Универсальный многоразовый счётчик для разных задачь
public int Zcounter = 0;
private int SetkaDvijScaleZ2 = 11; //Размер сетки по оси "Z".
private int SetkaDvijScaleX2 = 11; //размер сетки по оси "X".
private int SetcaDvijPloshad2 = 0; //Площадь сетки.
public int PloshCraft;
public int[] PloshCraftMass;
public int PloshCraftMassCounter = 0;
public int PloshCraftFor = 0;
private int PloX = 0;
private int PloZ = 1;
private int Perebor = 0;
public int ZDvij = 0;
public int XDvij = 0;
public int UDvij = 0;
private int VSPX;
private int VSPZ;
public int TESTE = 0;
public int SPK;
private Vector3[] Vershini1;
private int[] Bermudes1;
private int VK = 0;
private int BR = 0;
private int SDVIG = 0;
private int SDVIG2 = 1;
private int SDVIGX = 0;
private int SDVIGX2 = 0;
private int SDVIGFUCK = 0;
private int RAZDELITEL = 0;
public int ZERO = 0; // Просто ноль, по тому, что мне нужен ноль.
public int MonCorZ;
public int MonCorX;
public int SX;
private float BermudesTimer;
void Start()
{
MonHodMass = new int[(SetkaDvijScaleX2 * SetkaDvijScaleZ2) + 1, SetkaDvijScaleZ2 + 1 + SetkaMonHodZ];
}
void Update()
{
if (TESTE == 0)
{
if (SetkaPassabilityControl.SetkaScaleControl == 3)
{
TESTE = 1;
}
}
//------------------------------------------------------------------------------------------------------------------------------------
if (TESTE == 1)
{
//Расчёт площади сетки.
SetcaDvijPloshad2 = SetkaDvijScaleZ2 * SetkaDvijScaleX2;
PloshCraft = SetcaDvijPloshad2;
Perebor = SetcaDvijPloshad2 - 1;
PloshCraftMass = new int[PloshCraft];
MonHodYachMass = new int[PloshCraft];
for (PloshCraftFor = 0; PloshCraftFor < PloshCraft; PloshCraft--)
{
PloshCraftMass[PloshCraftMassCounter] = SetkaPassabilityControl.Setka[PloX, PloZ];
PloshCraftMassCounter = PloshCraftMassCounter + 1;
PloZ = PloZ + 1;
if (PloZ > SetkaDvijScaleZ2)
{
PloZ = 1;
PloX = PloX + SetkaDvijScaleZ2;
}
}
//--------------\/------------------- В разработке ----------------------------------------------------------------------------------------------
// Ищем координаты монстра, и занимаемся поиском координат клеток в радиусе шагания монстра -----
MonCorZ = 6; //Z координаты монстра
MonCorX = 11; //X координаты монстра
MonCorZ = (MonCorZ - (SetkaMonHodZ / 2)); //Z координата точки отсчёта построения сетки ходьбы
MonCorX = (MonCorX - (SetkaMonHodX / 2)); //X координата точки отсчёта построения сетки ходьбы
MonCorX = MonCorX - 1; //X координаты монстра, еденицу отнимаем, чтобы воспользоваться формулой для расчёта X координаты номера ячейки
PloshCraft = SetcaDvijPloshad2;
PloshCraftMassCounter = 0;
PloshMonHodXZ = SetkaMonHodX * SetkaMonHodZ;
Xcount = MonCorX;
if (Xcount > 0)
{
for (ZERO = 0; ZERO < Xcount; Xcount--)
{
SX = SX + SetkaDvijScaleZ2;
}
}
if (Xcount <= 0)
{
for (ZERO = 0; ZERO > Xcount; Xcount++)
{
SX = SX - SetkaDvijScaleZ2;
}
}
UniversalCounter2 = SetkaMonHodX;
UniversalCounter3 = SetkaMonHodX;
for (ZERO = 0; ZERO < UniversalCounter3; UniversalCounter3--)
{
for (ZERO = 0; ZERO < UniversalCounter2; UniversalCounter2--)
{
if ((SX + Zcounter + MonCorZ) <= PloshCraft && (SX + Zcounter + MonCorZ) >= 0 - SetkaMonHodX && (MonCorZ + UniversalCounter) >= 0 && (MonCorZ + UniversalCounter) <= SetkaDvijScaleZ2)
{
Debug.Log("X" + SX + Zcounter);
Debug.Log("Z" + MonCorZ + UniversalCounter);
MonHodMass[SX + Zcounter, MonCorZ + UniversalCounter] = 3;
}
UniversalCounter = UniversalCounter + 1;
if (UniversalCounter > (SetkaMonHodX - 1))
{
UniversalCounter = 0;
}
}
Zcounter = Zcounter + SetkaDvijScaleZ2;
UniversalCounter2 = SetkaMonHodX;
}
SX = 0;
UniversalCounter = 0;
UniversalCounter2 = 0;
UniversalCounter3 = 0;
PloX = 0;
PloZ = 1;
for (PloshCraftFor = 0; PloshCraftFor < PloshCraft; PloshCraft--)
{
MonHodYachMass[PloshCraftMassCounter] = MonHodMass[PloX, PloZ];
PloshCraftMassCounter = PloshCraftMassCounter + 1;
PloZ = PloZ + 1;
if (PloZ > SetkaDvijScaleZ2)
{
PloZ = 1;
PloX = PloX + SetkaDvijScaleZ2;
}
}
//-----------------------------------------------------------------------------------------------
//-----------------/\---------------- В разработке ----------------------------------------------------------------------------------------------
SDVIGX = SetkaDvijScaleX2;
Vershini1 = new Vector3[(SetcaDvijPloshad2 * 6)];
Bermudes1 = new int[(SetcaDvijPloshad2 * 6)];
SetkaDvij2 = new Mesh();
//Создаём меш.
//Подключаем меш фильтр.
MeshFilter SetkaDvijFilter2 = GetComponent<MeshFilter>();
//Применяем мешфильтр к мешу.
SetkaDvijFilter2.mesh = SetkaDvij2;
SPK = SetkaPassabilityControl.SetkaScaleControl;
TESTE = 2;
}
if (SPK == 3 && TESTE == 2)
{
//Циклы создания сетки исходя из её размера по оси "z" и оси "x" а так же её площади.
for (ZDvij = 0; ZDvij < SetkaDvijScaleZ2; SetkaDvijScaleZ2--)
{
for (XDvij = 0; XDvij < SetkaDvijScaleX2; SetkaDvijScaleX2--)
{
for (UDvij = 0; UDvij < SetcaDvijPloshad2; SetcaDvijPloshad2--)
{
if (MonHodYachMass[Perebor] == 3 && PloshCraftMass[Perebor] == 0)
{
Vershini1[VK] = new Vector3(SetkaDvijScaleX2 - SDVIG2, SetkaDvijScaleZ2 - 1 - SDVIGFUCK, 0);
Vershini1[VK + 1] = new Vector3(SetkaDvijScaleX2 - SDVIG, SetkaDvijScaleZ2 - 1 - SDVIGFUCK, 0);
Vershini1[VK + 2] = new Vector3(SetkaDvijScaleX2 - SDVIG2, SetkaDvijScaleZ2 - SDVIGFUCK, 0);
Vershini1[VK + 3] = new Vector3(SetkaDvijScaleX2 - SDVIG, SetkaDvijScaleZ2 - SDVIGFUCK, 0);
Vershini1[VK + 4] = new Vector3(SetkaDvijScaleX2 - SDVIG, SetkaDvijScaleZ2 - 1 - SDVIGFUCK, 0);
Vershini1[VK + 5] = new Vector3(SetkaDvijScaleX2 - SDVIG2, SetkaDvijScaleZ2 - SDVIGFUCK, 0);
}
Perebor = Perebor - 1;
Debug.Log("VK" + Vershini1[VK]);
Debug.Log("VK + 1" + Vershini1[VK + 1]);
Debug.Log("VK + 2" + Vershini1[VK + 2]);
Debug.Log("VK + 3" + Vershini1[VK + 3]);
Debug.Log("VK + 4" + Vershini1[VK + 4]);
Debug.Log("VK + 5" + Vershini1[VK + 5]);
RAZDELITEL = RAZDELITEL + 1;
Debug.Log("RAZDELITEL -----------" + RAZDELITEL);
VK = VK + 6;
SDVIG = SDVIG + 1;
SDVIG2 = SDVIG2 + 1;
SDVIGX2 = SDVIGX2 + 1;
if (SDVIGX2 == SDVIGX)
{
SDVIGX2 = 0;
SDVIGFUCK = SDVIGFUCK + 1;
}
if (SDVIG == SDVIGX)
{
SDVIG = 0;
}
if (SDVIG2 == SDVIGX + 1)
{
SDVIG2 = 1;
}
//Создаём массив с трианглами.
Bermudes1[BR] = 0 + BR;
Bermudes1[BR + 1] = 2 + BR;
Bermudes1[BR + 2] = 1 + BR;
Bermudes1[BR + 3] = 3 + BR;
Bermudes1[BR + 4] = 5 + BR;
Bermudes1[BR + 5] = 4 + BR;
BR = BR + 6;
Debug.Log("Создали Квад");
if (SetcaDvijPloshad2 <= 1)
{
TESTE = 3;
}
}
}
}
}
if (TESTE == 3 && SetcaDvijPloshad2 == 0)
{
Debug.Log("Создали SetkaDvij");
//Задаём вершины мешу.
SetkaDvij2.vertices = Vershini1;
//Создаём трианглы меша.
SetkaDvij2.triangles = Bermudes1;
TESTE = 4;
}
}
}
Ну и скриншот того, что сейчас генерится вокруг среднего монстра,
он у меня сейчас условно считается выделенным, пока без текстур,
и специально чуть приподнято: