Четверг, 28 Марта 2024, 11:31

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Создание зоны видимости турели C# (Нужно создать зону видимости, форма "сектор круга")
Создание зоны видимости турели C#
dima13230Дата: Вторник, 12 Апреля 2016, 21:43 | Сообщение # 1
частый гость
Сейчас нет на сайте
В общем, мне нужно создать зону видимости в форме "сектора круга".
Для наглядности и тех кто не знает, сектор круга выглядит вот так:


Добавлено (12 апреля 2016, 21:09)
---------------------------------------------
P.S забыл сказать, что всё происходит в 2D среде

Добавлено (12 апреля 2016, 21:30)
---------------------------------------------
Я кажется придумал. Я возьму картинку этого сектора, создам объект, добавлю Polygon Collider, включу режим Is Trigger, выключу Renderer спрайта и всё, остаётся только проверять, стоит ли объект в триггере.

Добавлено (12 апреля 2016, 21:35)
---------------------------------------------
Но как определить сколько объектов входит в триггер и до какого из них меньше расстояние?

Добавлено (12 апреля 2016, 21:43)
---------------------------------------------
У меня всплыл другой вопрос: как определить какое число в массиве самое маленькое?

Сообщение отредактировал dima13230 - Вторник, 12 Апреля 2016, 21:12
MANMANAДата: Среда, 13 Апреля 2016, 00:01 | Сообщение # 2
почти ветеран
Сейчас нет на сайте
https://www.reddit.com/r....n_range ?
http://unitycoder.com/blog/2012/12/09/enemy-visibility-cone/ ?


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
LertmindДата: Среда, 13 Апреля 2016, 03:04 | Сообщение # 3
заслуженный участник
Сейчас нет на сайте
Цитата dima13230 ()
У меня всплыл другой вопрос: как определить какое число в массиве самое маленькое?
Ты обязан использовать Linq, это так весело:
Код
using UnityEngine;
using System.Linq;

public class TestMin : MonoBehaviour
{
    void Start()
    {
        // Создаём массив со случайными числами
        int[] array = new int[10].Select(x => Random.Range(0, 100)).ToArray();
        // Ищем минимальное число
        int minValue = array.Min();
        // Строка для вывода массива
        string arrayStr = array.Select(x => x.ToString()).Aggregate((result, x) => result + ", " + x);
        Debug.Log(arrayStr + " => " + minValue);
    }
}
dima13230Дата: Среда, 13 Апреля 2016, 22:35 | Сообщение # 4
частый гость
Сейчас нет на сайте
Цитата Lertmind ()
Цитата dima13230 ()
У меня всплыл другой вопрос: как определить какое число в массиве самое маленькое?
Ты обязан использовать Linq, это так весело:

Уже smile

Добавлено (13 апреля 2016, 21:56)
---------------------------------------------

Цитата MANMANA ()
http://unitycoder.com/blog/2012/12/09/enemy-visibility-cone/ ?

Спасибо, ща переведу в C#, отпишусь

Добавлено (13 апреля 2016, 22:21)
---------------------------------------------
Так, попробовал переработать под турель, не работает

Добавлено (13 апреля 2016, 22:35)
---------------------------------------------
Короче, может я сделаю круглую зону видимости? Типа у турели например камера во все стороны крутится и обнаружение звука.

URGINSANДата: Четверг, 14 Апреля 2016, 00:24 | Сообщение # 5
почти ветеран
Сейчас нет на сайте
dima13230, чем вариант с триггером не угодил?

Я на драйве
berilДата: Четверг, 14 Апреля 2016, 11:39 | Сообщение # 6
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
https://vimeo.com/channels/115146/page:2
смотри тут, все понятно и просто под себя переделать




Накодил? Убери за собой!
Инвентарь в Unity(UI)
Инвентарь в Unity(GUI)
dima13230Дата: Четверг, 14 Апреля 2016, 14:19 | Сообщение # 7
частый гость
Сейчас нет на сайте
Цитата beril ()
https://vimeo.com/channels/115146/page:2
смотри тут, все понятно и просто под себя переделать

тяжеловато мне будет с медленным инетом видео смотреть...

Добавлено (14 апреля 2016, 13:59)
---------------------------------------------
даже сам сайт не грузится

Добавлено (14 апреля 2016, 14:11)
---------------------------------------------
Итак, минимальное значение числа в массиве я получил, а как по нему найти индекс массива, в котором содержится это число?

Добавлено (14 апреля 2016, 14:19)
---------------------------------------------
всё

VickaДата: Четверг, 14 Апреля 2016, 14:58 | Сообщение # 8
Another ART
Сейчас нет на сайте
dima13230, Ты бы делился своим кодом народу же интересно)

dima13230Дата: Четверг, 14 Апреля 2016, 18:30 | Сообщение # 9
частый гость
Сейчас нет на сайте
Цитата Vicka ()
dima13230, Ты бы делился своим кодом народу же интересно)

Нет проблем :))
Ловите код, но скажите, почему так сильно лагает когда турель наводится?
Код
    public List<Transform> targets;

    public Transform target;
    // скорость вращения
    public float rotationSpeed = 1F;
    //мертвая зона вращения (чтобы турель не дергалась при x=0)
    public float deadZone = 0.1F;
    //направление вращения ( "0" - не вращать, "1" - вправо и "-1" - влево)
    private float rotateDirection = 0;

    public GameObject Bullet;
    public bool IsShooting;

    void Start()
    {
        targets = new List<Transform>();
    }

    void LateUpdate()
    {
        if (targets.Count > 0)
        {
            float[] distances = new float[targets.Count];

            for (int i = 0; i < targets.Count; i++)
            {
                distances[i] = Vector2.Distance(this.transform.position, targets[i].position);
            }
            target = targets[System.Array.IndexOf<float>(distances, distances.Min())];
            if (target)
            {
                if (transform.InverseTransformPoint(target.position).x > deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, -1, 0.2f);
                }
                else if (transform.InverseTransformPoint(target.position).x < -deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                }
                else
                {
                    if (transform.InverseTransformPoint(target.position).y < 0) rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                    else
                    {
                        IsShooting = true;
                        if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
                        {
                            rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
                        }
                        else
                        {
                            rotateDirection = 0;
                        }
                    }
                }
                transform.rotation *= Quaternion.Lerp(new Quaternion(), Quaternion.Euler(0, 0, rotationSpeed * rotateDirection), Time.deltaTime);
            }
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        targets.Add(other.transform);
    }

    void OnTriggerExit2D(Collider2D other)
    {
        targets.Remove(other.transform);
    }


Добавлено (14 апреля 2016, 16:42)
---------------------------------------------
Сейчас буду работать над обнаружением препятствий, чтобы не стреляла и не наводилась на стенки :)))

Добавлено (14 апреля 2016, 18:30)
---------------------------------------------
Код
    public List<Transform> targets = new List<Transform>();
    // Цели, но без тех, что не нужны, т.е без тех, которые не соответствуют тегу или находятся за препятствием
    List<Transform> separatedTargets = new List<Transform>();
    public Transform target;
    // скорость вращения
    public float rotationSpeed = 1F;
    //мертвая зона вращения (чтобы турель не дергалась при x=0)
    public float deadZone = 0.1F;
    //направление вращения ( "0" - не вращать, "1" - вправо и "-1" - влево)
    private float rotateDirection = 0;

    public GameObject Bullet;
    public bool IsShooting;

    void Start()
    {
    }

    void LateUpdate()
    {
        if (targets.Count > 0)
        {
            List<float> distances = new List<float>();
            for (int i = 0; i < targets.Count; i++)
            {
                if (targets[i].tag != "StaticObject" && targets[i].tag != "friendly" && !Physics2D.Linecast(this.transform.position, targets[i].position))
                {
                    separatedTargets.Add(targets[i]);
                    distances.Add(Vector2.Distance(this.transform.position, targets[i].position));
                }
            }

            target = separatedTargets[distances.IndexOf(distances.Min())];
            if (target)
            {
                if (transform.InverseTransformPoint(target.position).x > deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, -1, 0.2f);
                }
                else if (transform.InverseTransformPoint(target.position).x < -deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                }
                else
                {
                    if (transform.InverseTransformPoint(target.position).y < 0) rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                    else
                    {
                        IsShooting = true;
                        if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
                        {
                            rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
                        }
                        else
                        {
                            rotateDirection = 0;
                        }
                    }
                }
                transform.rotation *= Quaternion.Lerp(new Quaternion(), Quaternion.Euler(0, 0, rotationSpeed * rotateDirection), Time.deltaTime);
            }
        }
        else
        {
            targets.Remove(target);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        targets.Add(other.transform);
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (targets.IndexOf(other.transform)> -1)
        {
            targets.Remove(other.transform);
        }
    }


В чём ошибка?


Сообщение отредактировал dima13230 - Четверг, 14 Апреля 2016, 18:47
MANMANAДата: Четверг, 14 Апреля 2016, 20:09 | Сообщение # 10
почти ветеран
Сейчас нет на сайте
при Remove либо лист пустой, либо в листе содержится два и более одинаковых элемента

Код
if (targets.Count > 0)
        {
....
}
else targets.Remove(target);

либо я неправильно со скобочками разобрался, либо вы пытаетесь удалить элемент пустого листа


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
dima13230Дата: Четверг, 14 Апреля 2016, 20:28 | Сообщение # 11
частый гость
Сейчас нет на сайте
Цитата MANMANA ()
при Remove либо лист пустой, либо в листе содержится два и более одинаковых элемента

Код
if (targets.Count > 0)
        {
....
}
else targets.Remove(target);

либо я неправильно со скобочками разобрался, либо вы пытаетесь удалить элемент пустого листа

нет. Ошибка в строке где IndexOf и Min
MANMANAДата: Четверг, 14 Апреля 2016, 21:45 | Сообщение # 12
почти ветеран
Сейчас нет на сайте
Цитата MANMANA ()
два и более одинаковых элемента

Добавлено (14 апреля 2016, 21:42)
---------------------------------------------
полагаю, IEnumerator не может выбрать, индекс какого объекта вам вернуть в этом случае distances.IndexOf(distances.Min()). что меньше 1 или 1, или 1?

Добавлено (14 апреля 2016, 21:45)
---------------------------------------------
Operation is not valid due to the current state of the object - Linq on List


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
dima13230Дата: Четверг, 14 Апреля 2016, 22:08 | Сообщение # 13
частый гость
Сейчас нет на сайте
Не знаю почему, но я добавил layerMask в аргументы Physics2D.LineCast и всё заработало

Добавлено (14 апреля 2016, 21:47)
---------------------------------------------
а массив distances был пуст

Добавлено (14 апреля 2016, 21:48)
---------------------------------------------
теперь нет

Добавлено (14 апреля 2016, 22:04)
---------------------------------------------
Скрипт полностью готов и функционирует:

Код
    public List<Transform> targets = new List<Transform>();
    // Цели, но без тех, что не нужны, т.е без тех, которые не соответствуют тегу или находятся за препятствием
    List<Transform> separatedTargets = new List<Transform>();
    public Transform target;
    // скорость вращения
    public float rotationSpeed = 1F;
    //мертвая зона вращения (чтобы турель не дергалась при x=0)
    public float deadZone = 0.1F;
    //направление вращения ( "0" - не вращать, "1" - вправо и "-1" - влево)
    private float rotateDirection = 0;

    public GameObject Bullet;
    public bool IsShooting;

    public int layerMask = 1 << 8;

    public float ShootPeriod = 0.1f;

    public Transform[] SpawnPointsTransforms;

    public IEnumerator Shoot()
    {
        yield return new WaitForSeconds(ShootPeriod);
        for (int i = 0; i < SpawnPointsTransforms.Length; i++)
        {
            Instantiate(Bullet, SpawnPointsTransforms[i].position, SpawnPointsTransforms[i].rotation);
        }
    }

    void Start()
    {
    }

    void LateUpdate()
    {
        if (IsShooting)
        {
            StartCoroutine(Shoot());
        }
        if (targets.Count > 0)
        {
            List<float> distances = new List<float>();
            for (int i = 0; i < targets.Count; i++)
            {
                if (targets[i].tag != "StaticObject" && targets[i].tag != "TurretFriendly" && targets[i].tag != "TurretIgnore" && !Physics2D.Linecast(this.transform.position, targets[i].position,layerMask))
                {
                    separatedTargets.Add(targets[i]);
                    distances.Add(Vector2.Distance(this.transform.position, targets[i].position));
                }
            }
            Debug.Log(distances.Count);

            target = separatedTargets[distances.IndexOf(distances.Min())];
            if (target)
            {
                if (transform.InverseTransformPoint(target.position).x > deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, -1, 0.2f);
                }
                else if (transform.InverseTransformPoint(target.position).x < -deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                }
                else
                {
                    if (transform.InverseTransformPoint(target.position).y < 0) rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                    else
                    {
                        IsShooting = true;
                        if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
                        {
                            rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
                        }
                        else
                        {
                            rotateDirection = 0;
                        }
                    }
                }
                transform.rotation *= Quaternion.Lerp(new Quaternion(), Quaternion.Euler(0, 0, rotationSpeed * rotateDirection), Time.deltaTime);
            }
        }
        else
        {
            targets.Remove(target);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {

        targets.Add(other.transform);
    }

    void OnTriggerExit2D(Collider2D other)
    {
        targets.Remove(other.transform);
    }

Добавлено (14 апреля 2016, 22:08)
---------------------------------------------
Ещё кое-что придумал, ждите, кину результат.

MANMANAДата: Четверг, 14 Апреля 2016, 22:08 | Сообщение # 14
почти ветеран
Сейчас нет на сайте
Вы же знаете, что такое List, Array, ArrayList и в чем их отличие и что общего?.. :)
лист
Цитата MANMANA ()
либо лист пустой


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
dima13230Дата: Пятница, 15 Апреля 2016, 11:51 | Сообщение # 15
частый гость
Сейчас нет на сайте
ну лист а не массив :))

Добавлено (14 апреля 2016, 22:26)
---------------------------------------------
Есть проблема. Проходит время "темпа стрельбы" и турель начинает стрелять, но не с таким-же темпом а без перерыва

Код
    public List<Transform> targets = new List<Transform>();
    // Цели, но без тех, что не нужны, т.е без тех, которые не соответствуют тегу или находятся за препятствием
    List<Transform> separatedTargets = new List<Transform>();
    public Transform target;
    // скорость вращения
    public float rotationSpeed = 1F;
    //мертвая зона вращения (чтобы турель не дергалась при x=0)
    public float deadZone = 0.1F;
    //направление вращения ( "0" - не вращать, "1" - вправо и "-1" - влево)
    private float rotateDirection = 0;

    public GameObject Bullet;
    public bool IsShooting;

    public int layerMask = 1 << 8;

    public float ShootPeriod = 0.1f;

    public TurretCannon[] Cannons;

    void Start()
    {
    }

    void LateUpdate()
    {
        if (IsShooting)
        {
            for (int i = 0; i < Cannons.Length; i++)
            {
                StartCoroutine(Cannons[i].Shoot());
            }
        }
        if (targets.Count > 0)
        {
            List<float> distances = new List<float>();
            for (int i = 0; i < targets.Count; i++)
            {
                if (targets[i].tag != "StaticObject" && targets[i].tag != "TurretFriendly" && targets[i].tag != "TurretIgnore" && !Physics2D.Linecast(this.transform.position, targets[i].position,layerMask))
                {
                    separatedTargets.Add(targets[i]);
                    distances.Add(Vector2.Distance(this.transform.position, targets[i].position));
                }
            }
            Debug.Log(distances.Count);

            target = separatedTargets[distances.IndexOf(distances.Min())];
            if (target)
            {
                if (transform.InverseTransformPoint(target.position).x > deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, -1, 0.2f);
                }
                else if (transform.InverseTransformPoint(target.position).x < -deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                }
                else
                {
                    if (transform.InverseTransformPoint(target.position).y < 0) rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                    else
                    {
                        IsShooting = true;
                        if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
                        {
                            rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
                        }
                        else
                        {
                            rotateDirection = 0;
                        }
                    }
                }
                transform.rotation *= Quaternion.Lerp(new Quaternion(), Quaternion.Euler(0, 0, rotationSpeed * rotateDirection), Time.deltaTime);
            }
        }
        else
        {
            targets.Remove(target);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {

        targets.Add(other.transform);
    }

    void OnTriggerExit2D(Collider2D other)
    {
        targets.Remove(other.transform);
    }


Код
[System.Serializable]
public class TurretCannon {

    public GameObject Bullet;
    public Transform ShootPoint;
    public float ShootRate;

    public AudioClip ShootSound;
    public float ShootingVolume;

    public IEnumerator Shoot()
    {
        yield return new WaitForSeconds(ShootRate);
        MonoBehaviour.Instantiate(Bullet, ShootPoint.position, ShootPoint.rotation);
        AudioSource.PlayClipAtPoint(ShootSound, ShootPoint.position,ShootingVolume);
    }
}

Добавлено (15 апреля 2016, 11:51)
---------------------------------------------
Исправил, работает всё.

Турель:

Код
public List<Transform> targets = new List<Transform>();
    // Цели, но без тех, что не нужны, т.е без тех, которые не соответствуют тегу или находятся за препятствием
    List<Transform> separatedTargets = new List<Transform>();
    public Transform target;
    // скорость вращения
    public float rotationSpeed = 1F;
    //мертвая зона вращения (чтобы турель не дергалась при x=0)
    public float deadZone = 0.1F;
    //направление вращения ( "0" - не вращать, "1" - вправо и "-1" - влево)
    private float rotateDirection = 0;

    public GameObject Bullet;
    public bool IsShooting;

    public int layerMask = 1 << 8;

    public float Rate = 1;

    public TurretCannon[] Cannons;

    //public bool IsShootingRaty = true;

    void Start()
    {
    }

    public void Shoot()
    {
        for (int i = 0; i < Cannons.Length; i++)
        {
            if (!Cannons[i].Shooted)
            {
                StartCoroutine(Cannons[i].Shoot());
            }
        }
    }
    

    void LateUpdate()
    {
        if (IsShooting)
        {
            Shoot();
        }
        if (targets.Count > 0)
        {
            List<float> distances = new List<float>();
            for (int i = 0; i < targets.Count; i++)
            {
                if (targets[i].tag != "StaticObject" && targets[i].tag != "TurretFriendly" && targets[i].tag != "TurretIgnore" && !Physics2D.Linecast(this.transform.position, targets[i].position,layerMask))
                {
                    separatedTargets.Add(targets[i]);
                    distances.Add(Vector2.Distance(this.transform.position, targets[i].position));
                }
            }
            Debug.Log(distances.Count);

            target = separatedTargets[distances.IndexOf(distances.Min())];
            if (target)
            {
                if (transform.InverseTransformPoint(target.position).x > deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, -1, 0.2f);
                }
                else if (transform.InverseTransformPoint(target.position).x < -deadZone / 2)
                {
                    IsShooting = false;
                    rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                }
                else
                {
                    if (transform.InverseTransformPoint(target.position).y < 0) rotateDirection = Mathf.Lerp(rotateDirection, 1, 0.2f);
                    else
                    {
                        IsShooting = true;
                        if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
                        {
                            rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
                        }
                        else
                        {
                            rotateDirection = 0;
                        }
                    }
                }
                transform.rotation *= Quaternion.Lerp(new Quaternion(), Quaternion.Euler(0, 0, rotationSpeed * rotateDirection), Time.deltaTime);
            }
        }
        else
        {

            IsShooting = false;
            if (rotateDirection > Mathf.Min(rotateDirection, 0) | rotateDirection < Mathf.Max(rotateDirection, 0))
            {
                rotateDirection = Mathf.Lerp(rotateDirection, 0, 0.2f);
            }
            else
            {
                rotateDirection = 0;
            }
            targets.Remove(target);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {

        targets.Add(other.transform);
    }

    void OnTriggerExit2D(Collider2D other)
    {
        targets.Remove(other.transform);
    }

Пушки турели, задаются в меню турели:
Код
[System.Serializable]
public class TurretCannon
{

    public GameObject Bullet;
    public Transform ShootPoint;
    public float ShootRate;

    public AudioClip ShootSound;
    public float ShootingVolume;

    [HideInInspector]
    public bool Shooted = false;

    public IEnumerator Shoot()
    {
        Shooted = true;
        yield return new WaitForSeconds(ShootRate);
        MonoBehaviour.Instantiate(Bullet, ShootPoint.position, ShootPoint.rotation);
        AudioSource.PlayClipAtPoint(ShootSound, ShootPoint.position, ShootingVolume);
        Shooted = false;
    }

}
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Создание зоны видимости турели C# (Нужно создать зону видимости, форма "сектор круга")
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг