Создание зоны видимости турели 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, это так весело: Уже Добавлено (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; }
}
|
|
| |
|