Тема: I.D.S. MONSTERS
Показать сообщение отдельно
Старый 05.03.2020, 21:23   #56
Crystal
Терабайт исходников
 
Аватар для Crystal
 
Регистрация: 05.07.2007
Сообщений: 5,196
Написано 1,721 полезных сообщений
(для 5,374 пользователей)
Ответ: I.D.S. MONSTERS

Сегодня можно было плотно по программировать,
или посмотреть две новые серии ходячих мертвецов.
В общем серии оказались полным говном ))

Однако, сделал выделение монстров кликом мыши.
Пришлось подзапариться с тем, как сделать чтобы
выделялся только один, а также подзапариться
с удаленем сетки уже выделенного монстра.
Альфа вариант успешно функционирует )

В общем как сделать, чтобы не все префабы выделились
при щелчке по одному из них, а только нужный?
Проверить его координаты!

Берём координаты префаба монстра, пускаем луч,
сравниваем позицию префаба по осям X и Z с
точкой падения луча. Если координаты префаба больше
или равны координатам пика, то из координат префаба
вычитаем координаты пика, ну и записываем результат
по обеим осям в соответствующие переменные.
Так-как у нас размер сетки 1 на 1, то проверяем
числа в данных переменных, если они меньше чем 1.01,
значит префаб находится в клетке куда мы луч пускали,
префабу по этим координатам сетку мы и создадим.

Участок кода отвечающий за определение пикнутого лучом монстра:

                Pickposition = TipaMonster.transform.position;


                if (Pickposition.x >= PickRay.point.x)
                {
                    mx = Pickposition.x - PickRay.point.x;
                }
                else
                {

                    mx = PickRay.point.x - Pickposition.x;
                }

                if (Pickposition.z >= PickRay.point.z)
                {
                    mz = Pickposition.z - PickRay.point.z;
                }
                else
                {

                    mz = PickRay.point.z - Pickposition.z;
                }

      if (mx < 1.01 && mz < 1.01)
                {

А насчёт удаления сетки, когда мы куда-то в другое место пикнули,
то удалять пришлось меш из мешфильтра, а не весь гейм обджект,
я сначала пытался гейм обджект удалять, и новый из префаба вызывать,
но то была проблемная хрень, удалить меш из мешфильтра умное решение.

Удаляем так:

            if (SetkaDestroyer == 1 && SetkaDvijCreator == 3)
            {
                SetkaDvijCreator = 0;
                SetkaDestroyer = 0;

            }

            if (SetkaDestroyer == 1)
            {
                SetkaDvijCreator = 3;
                Destroy(GetComponent<MeshFilter>().mesh);

                SetkaDvijScaleZ = 5;
                SetkaDvijScaleX = 5;
            }
Если нужна билда, выложу по запросу, но думается мне что никому нах не надо )))

Вот весь код на случай если кто ну очень любопытный.
Предупреждаю, может втсречаться мусор, и неправильные комментарии,
так-как я увлекаюсь самокопипастой, и ваще комментить уже впадлу стало.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetkaDvijControl : MonoBehaviour
{

    //Сетка движения юнита.
    //-------------------------------------------------------------------------------------------------------------------------------------------
    public int SetkaDvijCreator = 0;
    public Camera Camera; //Камера конечно
    public GameObject SetkaMobile;
    public GameObject TipaMonster;
    public Object SetkaDvij;
    public int SetkaDestroyer = 0;
    public float SetkaScaleZ = 10;
    public float SetkaScaleX = 10;
    public float SetkaDvijScaleZ = 5; //Размер сетки по оси "Z".
    public float SetkaDvijScaleX = 5; //размер сетки по оси "X".
    public Vector3 RaycastPickCoordinates; //Конечные координаты падения луча в рейкасте на коллайдер
    public string RaycastObjNow; // Текстовая переменная, содержит имя объекта коллайдер которого попал под луч

    public float SetcaDvijPloshad; //Площадь сетки.

    //Статичные переменные для отсчёта в циклах создания клеток сетки.
    public int ZDvij = 0;
    public int XDvij = 0;
    public int UDvij = 0;

    public Vector3 Pickposition;
    public float MonsterHoditX;
    public float MonsterHoditZ;
    public float vx = 0f;
    public float vz = 0f;

    public float mx;
    public float mz;
    public float mDx;
    public float mDz;

    void Update()
    {



        //Сам луч, начинается от позиции камеры и направлен в сторону мыши
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        //Структура луча, нужна для получения информации из Raycast
        RaycastHit PickRay;

        //Пускаем луч
        Physics.Raycast(ray, out PickRay);

        //Если нажата ЛКМ
        if (Input.GetMouseButtonDown(0))
        {



            if (SetkaDestroyer == 1 && SetkaDvijCreator == 3)
            {
                SetkaDvijCreator = 0;
                SetkaDestroyer = 0;

            }

            if (SetkaDestroyer == 1)
            {
                SetkaDvijCreator = 3;
                Destroy(GetComponent<MeshFilter>().mesh);

                SetkaDvijScaleZ = 5;
                SetkaDvijScaleX = 5;
            }

            //Если запустили луч
            if (Physics.Raycast(ray, out PickRay))
            {
                //Получаем координаты пика на коллайдере
                RaycastPickCoordinates = new Vector3(PickRay.point.x, PickRay.point.y, PickRay.point.z);
             


                //Пишем в RaycastObjNow и дебаггер конкретно во что воткнулся луч
                RaycastObjNow = PickRay.collider.name;
             

                //Если луч попал в плейн
                if (RaycastObjNow == "Capsule")
                {
                    //Обнуляем RaycastObjNow
                    RaycastObjNow = "NiHuYa";
                 

                }


                Pickposition = TipaMonster.transform.position;


                if (Pickposition.x >= PickRay.point.x)
                {
                    mx = Pickposition.x - PickRay.point.x;
                }
                else
                {

                    mx = PickRay.point.x - Pickposition.x;
                }

                if (Pickposition.z >= PickRay.point.z)
                {
                    mz = Pickposition.z - PickRay.point.z;
                }
                else
                {

                    mz = PickRay.point.z - Pickposition.z;
                }




                if (mx < 1.01 && mz < 1.01)
                {


                    if (SetkaDvijCreator == 0)
                    {

                        SetkaDvijCreator = 1;
                        SetkaDestroyer = 1;

                        Pickposition = TipaMonster.transform.position;


                        MonsterHoditX = SetkaDvijScaleX / 2f;
                        MonsterHoditZ = SetkaDvijScaleZ / 2f;


                        SetkaMobile.transform.position = new Vector3(Pickposition.x - MonsterHoditX, 0, Pickposition.z - MonsterHoditZ);


                        //Регулируем размер сетки выделения и её позицию относительно краёв поля

                        // Если сетка выползла за левый край игрового поля, подрезаем егё на количество выползающих клеток, и на столько же сдвигаем
                        if (Pickposition.x - MonsterHoditX < 0)

                        {
                            vx = Pickposition.x - MonsterHoditX;
                            SetkaDvijScaleX = SetkaDvijScaleX + vx;
                            SetkaMobile.transform.position = new Vector3(Pickposition.x - MonsterHoditX - vx, 0, Pickposition.z - MonsterHoditZ);
                        }

                        // Если сетка выползла за правый край игрового поля, подрезаем её на количество выползших клеток
                        if (Pickposition.x + MonsterHoditX > SetkaScaleX)

                        {
                            vx = (Pickposition.x + MonsterHoditX) - SetkaScaleX;
                            SetkaDvijScaleX = SetkaDvijScaleX - vx;
                        }


                        // Если сетка выползла за нижний край игрового поля, подрезаем её на количество выползающих клеток, и на столько же сдвигаем

                        if (Pickposition.z - MonsterHoditZ < 0)

                        {
                            vz = Pickposition.z - MonsterHoditZ;
                            SetkaDvijScaleZ = SetkaDvijScaleZ + vz;
                            SetkaMobile.transform.position = new Vector3(Pickposition.x - MonsterHoditX, 0, Pickposition.z - MonsterHoditZ - vz);
                        }

                        // Если сетка выползла за верхний край игрового поля, подрезаем её на количество выползших клеток
                        if (Pickposition.z + MonsterHoditZ > SetkaScaleZ)

                        {
                            vz = (Pickposition.z + MonsterHoditZ) - SetkaScaleZ;
                            SetkaDvijScaleZ = SetkaDvijScaleZ - vz;
                        }

                        // Выравниваем сетку, когда её координаты вылезают за 0 по обеим осям

                        if (Pickposition.x - MonsterHoditX < 0 && Pickposition.z - MonsterHoditZ < 0)
                        {
                            SetkaMobile.transform.position = new Vector3(Pickposition.x - MonsterHoditX - vx, 0, Pickposition.z - MonsterHoditZ - vz);

                        }


                        //------------------------------------------------------------------------------------------------------------------------------------


                        Mesh SetkaDvij = new Mesh();
                        //Подключаем меш фильтр.
                        MeshFilter SetkaDvijFilter = GetComponent<MeshFilter>();
                        //Применяем мешфильтр к мешу.
                        SetkaDvijFilter.mesh = SetkaDvij;
                        
                        Debug.Log("Создали SetkaDvij");




                        //Расчёт площади сетки.
                        SetcaDvijPloshad = SetkaDvijScaleZ * SetkaDvijScaleX;

                        //Создаём меш.



                        //Циклы создания сетки исходя из её размера по оси "z" и оси "x" а так же её площади.
                        for (ZDvij = 0; ZDvij < SetkaDvijScaleZ; SetkaDvijScaleZ--)
                        {



                            for (XDvij = 0; XDvij < SetkaDvijScaleX; SetkaDvijScaleX--)

                            {



                                for (UDvij = 0; UDvij < SetcaDvijPloshad; SetcaDvijPloshad--)
                                {








                                    //Создаём вектор вершин с массивом из четырёх штук.
                                    Vector3[] Vershini2 = new Vector3[4]
                                    {
                               //Пишем в массив координаты вершин опираясь на размер сетки по её осям.
                                new Vector3(0,0,0), new Vector3(SetkaDvijScaleX,0,0), new Vector3(0,SetkaDvijScaleZ,0), new Vector3(SetkaDvijScaleX,SetkaDvijScaleZ,0)
                                    };


                                    //Создаём массив с трианглами.
                                    int[] Bermudes2 = new int[6];
                                    Bermudes2[0] = 0;
                                    Bermudes2[1] = 2;
                                    Bermudes2[2] = 1;
                                    Bermudes2[3] = 2;
                                    Bermudes2[4] = 3;
                                    Bermudes2[5] = 1;

                                    Vector2[] TextureCoordinates2 = new Vector2[4]
                                    {

                              new Vector2(0,0) , new Vector2(SetkaDvijScaleX,0) , new Vector2(0,SetkaDvijScaleZ) , new Vector2(SetkaDvijScaleX, SetkaDvijScaleZ)

                                    };



                                    //Задаём вершины мешу.
                                    SetkaDvij.vertices = Vershini2;
                                    //Создаём трианглы меша.
                                    SetkaDvij.triangles = Bermudes2;
                                    SetkaDvij.uv = TextureCoordinates2;

                                    SetkaDvij.RecalculateBounds();
                                    SetkaDvij.RecalculateNormals();
                                    SetkaDvij.RecalculateTangents();

                                }
                            }
                        }





                    }

                        else
                    {


                        SetkaDvijScaleZ = 5;
                        SetkaDvijScaleX = 5;
                      


                    }

                   
                   

                    
                }
            }









    


        }

    }
}


Смотреть мой форумный блог полезно тому, кто соберётся например своих героев меча и магии на юнити написать,
я иду к этой механике, только она будет сложнее. Так что, не пропускайте )

Ах да, монстры из префабов вызываются сейчас так:

 void Start()
    {
        Instantiate(TipaMonster, new Vector3(1.5f, 0, 2.5f), Quaternion.identity);
        Instantiate(TipaMonster, new Vector3(5.5f, 0, 5.5f), Quaternion.identity);
        Instantiate(TipaMonster, new Vector3(9.5f, 0, 9.5f), Quaternion.identity);
    }
__________________
Проект "Deathbring World - Rangers" и его финансовая поддержка:
https://boosty.to/deathbringrangers

Я на - TWITCH
Канал на YouTube
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Crystal за это полезное сообщение:
ABTOMAT (06.03.2020), Arton (06.03.2020)