Помогите исправить код!

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Помогите исправить код!

Сообщение zoss 25 янв 2013, 21:40

Вобщем делаю выделение юнитов. Юниты то выделются то нет(в основном нет).

делаю так:

с помощью selectRect.Contains(camera.WorldToScreenPoint(UM.Unitses[i].transform.position)) определяю есть ли в выбраном прямоугольнике обьекты из массива UM.Unitses и заношу их в другой массив.

вот полный код:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UnitControl : MonoBehaviour
{
        Vector3 poin1, point2;
        //int layerMaskDefault=1<<0;
        float height, width;
        public Rect selectRect,allRect;
        public Texture2D selectTextur;
        public bool DragMouse;
        public GameObject Selectr;
        UnitManager UM;

        void Start(){
                UM=gameObject.GetComponent<UnitManager>();
        }
        void Update(){
        //      allRect=new Rect(0,0,Screen.width,Screen.height);
               
                for(int t=0; 1000>t;t++)
                {
                //Debug.Log("PAROVOZIK TIR TIR TIR");
                GameObject mad=GameObject.FindGameObjectWithTag("Unit");
                if(mad){
                mad.gameObject.tag="UnitMaked";
                UM.Unitses.Add(mad);                   
                }
                else{
                                break;
                        }
                }
               
                if (Input.GetMouseButtonDown(0)){
                        poin1=Input.mousePosition;
                        Clear();
                }
                if (Input.GetMouseButton(0)){
                        point2=Input.mousePosition;
                        DragMouse=true;
                }
                if (Input.GetMouseButtonUp(0)){
                        DragMouse=false;
                        Select();
                }
        }

        void OnGUI(){
                if (DragMouse){
                        width=-poin1.x+point2.x;
                        height=(Screen.height-point2.y)-(Screen.height-poin1.y);
                        selectRect=new Rect(poin1.x,Screen.height-poin1.y,width,height);
                        GUI.DrawTexture(selectRect,selectTextur,ScaleMode.StretchToFill,true);

                }

        }

        void Select(){
               
               
               
               
                width=-poin1.x+point2.x;
                height=(Screen.height-point2.y)-(Screen.height-poin1.y);
                if (width<0){
                        width-=width+width;
                }
                if (height<0){
                        height-=height+height;
                }
                if(point2.x<poin1.x){
                        var x1=poin1.x;
                        var x2=point2.x;
                        poin1.x=x2;
                        point2.x=x1;
                }
                if(point2.y<poin1.y){
                        var y1=poin1.y;
                        var y2=point2.y;
                        poin1.y=y2;
                        point2.y=y1;
                }
                selectRect=new Rect(poin1.x,Screen.height-poin1.y,width,height);
                for(int i=0; UM.Unitses.Count>i;i++){
                       
                        if(selectRect.Contains(camera.WorldToScreenPoint(UM.Unitses[i].transform.position))){
                                Debug.Log("PAROVOZIK TIR TIR TIR");
                        UM.Unitses[i].gameObject.tag="UnitSelected";
                        //Instantiate(Selectr, UM.Unitses[i].transform.position, Quaternion.identity);
                        UM.UnitsesSelected.Add(UM.Unitses[i]);
                        }else{
                                Clear();
                        }
                }
               
                }
               
                void Clear(){
                for(int i=0; UM.UnitsesSelected.Count>i;i++){
                       
                        UM.UnitsesSelected[i].gameObject.tag="UnitMaked";
                        //Instantiate(Selectr, UM.Unitses[i].transform.position, Quaternion.identity);
                        //UM.UnitsesSelected.Add(UM.Unitses[i]);
                        }
               
                        UM.UnitsesSelected.Clear();
                }
}
 



Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UnitManager : MonoBehaviour {
       
        public List<GameObject> Unitses=new List<GameObject>();//Список для хранения всех юнитов
        public List<GameObject> UnitsesSelected=new List<GameObject>();//Список для хранения выделеных юнитов
}

 



И вообще правильно ли управлять юнитами с помощью тегов?
zoss
UNец
 
Сообщения: 35
Зарегистрирован: 30 сен 2012, 11:24

Re: Помогите исправить код!

Сообщение extravert 25 янв 2013, 23:20

попробуйте дописать ниже
Синтаксис:
Используется csharp
void OnDrawGizmos() {
Gizmos.DrawWireCube(new Vector3(selectRect.x, selectRect.y), new Vector3(selectRect.x+selectRect.width,selectRect.y+selectRect.height, 2));
}


проблему это конечно не решит, но покажет вам линиями положение selectRect. Соответственно будет видно правильно ли производятся вычисления по ректанглу.
Если захотите рисовать линии вне OnDrawGizmos - используйте Debug.DrawLine()
Если хотите чтобы Gizmos показывался в редакторе - используйте [ExecuteInEditMode] прямо перед объявлением класса
Аватара пользователя
extravert
UNIверсал
 
Сообщения: 465
Зарегистрирован: 24 дек 2012, 11:54

Re: Помогите исправить код!

Сообщение BornFoRdeatH 25 янв 2013, 23:58

А что это у вас такое?

Синтаксис:
Используется csharp
for(int t=0; 1000>t;t++)
                {
                //Debug.Log("PAROVOZIK TIR TIR TIR");
                GameObject mad=GameObject.FindGameObjectWithTag("Unit");
                if(mad){
                mad.gameObject.tag="UnitMaked";
                UM.Unitses.Add(mad);                    
                }
 


Вы каждый апдейт тысячу раз выполняете поиск объектов с тегом юнит, и что вы делаете с массивом обьектов, непонятно?

Загляните хоть в справку
http://docs.unity3d.com/Documentation/S ... thTag.html
Не бойся, если ты один, бойся, если ты ноль.
BornFoRdeatH
Адепт
 
Сообщения: 2377
Зарегистрирован: 22 окт 2011, 23:41
Откуда: Украина
Skype: bornfordeath

Re: Помогите исправить код!

Сообщение zoss 26 янв 2013, 10:47

BornFoRdeatH писал(а):А что это у вас такое?

Синтаксис:
Используется csharp
for(int t=0; 1000>t;t++)
                {
                //Debug.Log("PAROVOZIK TIR TIR TIR");
                GameObject mad=GameObject.FindGameObjectWithTag("Unit");
                if(mad){
                mad.gameObject.tag="UnitMaked";
                UM.Unitses.Add(mad);                    
                }
 


Вы каждый апдейт тысячу раз выполняете поиск объектов с тегом юнит, и что вы делаете с массивом обьектов, непонятно?


Я сначала заполняю массив юниты, потом проверяю есть ли они в прямоугольнике выделения и меняю им тег. Вы не до конца смотрели, там если условие не выполняется то происходит break, у меня стоит три юнита и он дальше трёх не заполняет.
zoss
UNец
 
Сообщения: 35
Зарегистрирован: 30 сен 2012, 11:24

Re: Помогите исправить код!

Сообщение extravert 26 янв 2013, 13:24

А почему бы просто не сделать так?
1. Объявляем в классе статик поле коллекции. Например
Синтаксис:
Используется csharp
public class Unit : MonoBehaviour {
public static List<Unit> AllUnits = new List<Unit>();
}

2. В методах Awake() и Destroy() класса Unit пишем:
Синтаксис:
Используется csharp
private void Awake() {
AllUnits.Add(this);
}
private void Destroy() {
AllUnits.Remove(this); //насчет команды удаляющей содержимое из коллекции не скажу точно но вроде так
}
 

3. Где нам нужно обращаемся к элементам например так:
Синтаксис:
Используется csharp
var a = Units.AllUnits.First(x => x.MyValue == 0); //Выберет первого юнита который имеет значение MyValue равное 0
 


И не нужно никаких сумасшедших лишних выборок, каждый круг проверяя весь список объектов на принадлежность
Аватара пользователя
extravert
UNIверсал
 
Сообщения: 465
Зарегистрирован: 24 дек 2012, 11:54

Re: Помогите исправить код!

Сообщение zoss 26 янв 2013, 13:32

extravert писал(а):попробуйте дописать ниже
Синтаксис:
Используется csharp
void OnDrawGizmos() {
Gizmos.DrawWireCube(new Vector3(selectRect.x, selectRect.y), new Vector3(selectRect.x+selectRect.width,selectRect.y+selectRect.height, 2));
}


проблему это конечно не решит, но покажет вам линиями положение selectRect. Соответственно будет видно правильно ли производятся вычисления по ректанглу.
Если захотите рисовать линии вне OnDrawGizmos - используйте Debug.DrawLine()
Если хотите чтобы Gizmos показывался в редакторе - используйте [ExecuteInEditMode] прямо перед объявлением класса


OnDrawGizmos рисует в совсем другом месте! хотя в OnGUI я использую теже координаты и он рисует нормально!

Вроде разобрался, там в коде была ошибка:

вместо

if(point2.y<poin1.y){
var y1=poin1.y;
var y2=point2.y;
poin1.y=y2;
point2.y=y1;
}

должно быть

if(point2.y>poin1.y){
var y1=poin1.y;
var y2=point2.y;
poin1.y=y2;
point2.y=y1;
}

Выделение стало лучше, но всёравно половину раз не выделят! Может есть другой способ?


extravert , спасибо! сейчас попробую, но проблема не в этом, а в том что прямоугольник косячно выделяет юнитов!
zoss
UNец
 
Сообщения: 35
Зарегистрирован: 30 сен 2012, 11:24

Re: Помогите исправить код!

Сообщение extravert 26 янв 2013, 14:21

Почитай внимательно про Gizmos, я привел пример использования координат по x/y, а тебе возможно нужно по x/z. Он точно покажет то что ты ищешь
Аватара пользователя
extravert
UNIверсал
 
Сообщения: 465
Зарегистрирован: 24 дек 2012, 11:54

Re: Помогите исправить код!

Сообщение gturk 26 янв 2013, 17:12

а может быть дело в том что не все юниты пересекают плоскость selectRect, если так, то можно заменить Rect на Bounds
Аватара пользователя
gturk
UNITрон
 
Сообщения: 239
Зарегистрирован: 01 апр 2012, 18:49


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 15