forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Общие вопросы (http://forum.boolean.name/forumdisplay.php?f=166)
-   -   Проблемы разработки от EvilOkta (http://forum.boolean.name/showthread.php?t=17911)

pax 18.03.2013 16:54

Ответ: Передача переменной в метод
 
угол между текущим кватернионом и конечным http://docs.unity3d.com/Documentatio...ion.Angle.html

EvilOkta 18.03.2013 21:03

Ответ: Передача переменной в метод
 
спасибо, решил проблему немного не таким способом как вы советовали. Просто после каждого поворота обнулял rotation родителя в исходное положение и прописал 4 возможных поворота - наследование делает все остальное.

Всем спасибо за советы )) скоро будет очередная порция тупых вопросов ))

upd: собственно один из них - как родителем объекта сделать не определенный объект, а его инстанс? дело в том, что скрипт работает на одном объекте, но при нескольких объектах в сцене родитель привязывается лишь к одному. Логикой чую, что нужно делать инстанс родителя для каждого отдельно взятого юнита. Но если делаю объект для привязки префабом (т.е. GameObject) то компилятор говорит что Instance будет типа Object а не GameObject. А он не имеет компонента transform (хотя непонятно почему), если же объявить переменную, где собираюсь хранить ссылку на инстанс, как GameObject, то к нему нельзя применить метод Instantiate (брр...)
тут примеры только на яве http://docs.unity3d.ru/ScriptReferen...rom=GameObject
понимаю, что опять упускаю какую-то базовую концепцию

seaman 18.03.2013 22:24

Ответ: Передача переменной в метод
 
Код:

компилятор говорит что Instance будет типа Object а не GameObject
Ну естественно - в справке четко написано, что Instantiate возвращает Object. А что Вам мешает привести тип?
GameObject go = (GameObject)Instantiate (...);

EvilOkta 20.03.2013 10:32

Ответ: Передача переменной в метод
 
Цитата:

Object. А что Вам мешает привести тип?
GameObject go = (GameObject)Instantiate (...);
а это равносильно команде ниже? или есть отличия?
GameObject go = Instantiate(...) as GameObject;

pax 20.03.2013 10:39

Ответ: Передача переменной в метод
 
Отличия есть. В твоем случае не будет ошибки, если Instantiate(...) возвращала бы не UnityEngine.Object, а вообще произвольный тип объекта. При неверном касте просто вернет null. Директ каст (GameObject)Instantiate (...); выдаст исключение.

EvilOkta 25.03.2013 11:55

Ответ: Передача переменной в метод
 
можно как-нибудь узнать высоту/длину/ширину бокса, в который вписана 3d модель? чтобы использовать для корректирования scale

pax 25.03.2013 12:12

Ответ: Передача переменной в метод
 
Сам меш: http://docs.unity3d.com/Documentatio...sh-bounds.html
Размер AABB: http://docs.unity3d.com/Documentatio...er-bounds.html
Размер AABB колайдера: http://docs.unity3d.com/Documentatio...er-bounds.html

EvilOkta 25.03.2013 14:59

Ответ: Передача переменной в метод
 
то что нужно, спасибо pax!

EvilOkta 31.03.2013 13:57

Ответ: Передача переменной в метод
 
небольшой вопросик: сейчас занимался экспортом модели из 3d max, долго парился с правильной обработкой модели скриптом (в итоге помог reset Xform и полный сброс трансформации в Unity).
Вопрос собственно вот в чем: по какому принципу нужно выставлять настройки в 3d max чтобы в unity объект занимал пространство 1х1х1 юнитов?
Сложность в том, что я моделю в более крупном масштабе, а потом уменьшаю его "на глазок" пока не влезет. Но это слишком топорный способ. Может вы знаете более изящное решение?

И еще странно - при импорте ассета из 3d max в Unity, движок считает меш как компонент дочернего объекта префаба а не самого префаба?

Да, с bounds разобрался - коррекция работает при любых размерах меша.

EvilOkta 26.06.2013 13:14

Ответ: Передача переменной в метод
 
Небольшой вопросик для общего развития - есть ли реализация функционала ступенчатых массивов на базе работы со списками?
Что можно почитать по этой теме?
Интересует для реализации собственного гибкого алгоритма построения взвешенных и направленных графов.
Как думаете с помощью чего проще и оптимальней реализовать: ступенчатых массивов или списков?

seaman 26.06.2013 17:41

Ответ: Передача переменной в метод
 
Думаю этот вопрос лучше задавать тут: http://forum.boolean.name/forumdisplay.php?f=21
ЗЫ: я не изучал вопрос по реализации графов, но вот в Юнити для графов в Меканим написана такая dll: UnityEditor.Graphs.dll
Посмотри - может просто ее можно использовать.

EvilOkta 11.10.2013 23:28

Ответ: Передача переменной в метод
 
ребят, глупый вопрос но все-таки. Делаю метод CheckInBorders:
PHP код:

public class CameraNavigation MonoBehaviour {    
List<
floatBorders = new List<float>(); //список экранных маркеров
    
public enum GetBordersInfo {None,Left,Right,Up,Down}; // присвоение попавшей рамки
    
public GetBordersInfo BordersInfo;
    const 
float ScreenPercent 0.05f;
        
    
void Start () {
    
ScreenWidth Screen.width;
    
ScreenHeight Screen.height;    
    
    
Borders.Add ((float)0f); // 0 - слева начало
    
Borders.Add ((float)ScreenWidth*ScreenPercent); // 1 - слева конец
    
Borders.Add ((float)ScreenWidth*(1-ScreenPercent)); // 2 - справа начало
    
Borders.Add ((float)ScreenWidth); // 3 - справа конец
    
Borders.Add ((float)0f); // 4 - сверху начало
    
Borders.Add ((float)ScreenHeight*ScreenPercent); // 5 - сверху конец
    
Borders.Add ((float)ScreenHeight*(1-ScreenPercent)); // 6 - снизу начало 
    
Borders.Add ((float)ScreenHeight); // 7 - снизу конец

public void CheckInBorders () {
    
float MouseXCord Input.mousePosition.x;
    
float MouseYCord Input.mousePosition.y;
    
    if ((
MouseXCord >= Borders[0])&(MouseXCord <= Borders[1])) GetBordersInfo.Left;
    if ((
MouseXCord >= Borders[2])&(MouseXCord <= Borders[3])) GetBordersInfo.Right;    
    if ((
MouseYCord >= Borders[4])&(MouseYCord <= Borders[5])) GetBordersInfo.Up;
    if ((
MouseYCord >= Borders[6])&(MouseYCord <= Borders[7])) GetBordersInfo.Down;
    if ((
MouseXCord >= Borders[1])&(MouseXCord <= Borders[2])&(MouseYCord >= Borders[5])&(MouseYCord <= Borders[6])) GetBordersInfo.None;
    }


привел выдержки из кода касаемые этого метода

он по идее должен проверить в какую из рамок экрана попал курсор мыши (для навигации камеры)
но компилятор на каждом условии выдает ошибку cs0201
метод вызывается из метода update.
Не могу понять почему так. MouseXCord, MouseYCord инициализируются при каждом вызове метода, типы соблюдаются... в чем может быть косяк?

pax 11.10.2013 23:40

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

seaman 12.10.2013 00:46

Ответ: Передача переменной в метод
 
Цитата:

везде return забыл
Зачем? Если все методы void?
Стоп! А что по мнению вопрошающего делает выражение "GetBordersInfo.Left"? Оно возвращает значение enum. Что делают с этим значением - либо присваивают чему то, либо возвращают из функции. pax решил, что надо вернуть. Что хотели Вы?
Цитата:

тип функции GetBordersInfo
Это ж не функция, а enum.

Ошибка в том, что нет скобки '}' у метода Start

EvilOkta 12.10.2013 06:54

Ответ: Передача переменной в метод
 
про скобку - просто пропустил в цитате.
return не используется, но я понял с вашей помощью в чем косяк, я не правильно обновлял контейнер для enum
PHP код:

if ((MouseXCord >= Borders[0])&(MouseXCord <= Borders[1])) BordersInfo GetBordersInfo.Left;
    if ((
MouseXCord >= Borders[2])&(MouseXCord <= Borders[3])) BordersInfo GetBordersInfo.Right;    
    if ((
MouseYCord >= Borders[4])&(MouseYCord <= Borders[5])) BordersInfo GetBordersInfo.Up;
    if ((
MouseYCord >= Borders[6])&(MouseYCord <= Borders[7])) BordersInfo GetBordersInfo.Down;
    if ((
MouseXCord >= Borders[1])&(MouseXCord <= Borders[2])&(MouseYCord >= Borders[5])&(MouseYCord <= Borders[6])) BordersInfo GetBordersInfo.None

глупо, контейнер объявил но его не обновлял, но ваши подсказки как раз и дали понять )) спасибо

кстати еще один вопрос, есть ли в C# конструкции которые позволяют условия типа ((x > a)&(x < b)) записывать более компактно? Именно попадание переменной в диапазон

pax 12.10.2013 08:59

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 268663)
кстати еще один вопрос, есть ли в C# конструкции которые позволяют условия типа ((x > a)&(x < b)) записывать более компактно? Именно попадание переменной в диапазон

Вроде нет

seaman 12.10.2013 14:30

Ответ: Передача переменной в метод
 
Напиши расширение, если нужно:
Код:

public static class Extension
{
    public static bool InRange(this float val, float min, float max)
    {
        return val > min && val < max;
    }
}

Используем:
if(x.InRange(a, b))

pax 12.10.2013 17:09

Ответ: Передача переменной в метод
 
Это не на много короче, а по сути одно и то же. Плюс ты написал расширение с проверкой, что граничные значения диапазона не учитываются.

Кстати ты используешь побитовый И (&). Для чего? Надо обязательно проверить два условия? Оператор && остановит выполнение если уже не верно левое условие.

EvilOkta 12.10.2013 17:54

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от pax (Сообщение 268677)
Кстати ты используешь побитовый И (&). Для чего? Надо обязательно проверить два условия? Оператор && остановит выполнение если уже не верно левое условие.

кстати да, имеет смысл использовать && я думаю даже доработать условия, по идее курсор мыши не может быть за пределами экрана, поэтому можно оставить только внутренние границы. Сейчас проверю.

EvilOkta 14.10.2013 00:53

Ответ: Передача переменной в метод
 
блин, ребят помогите, опять застрял, четвертый час бьюсь а косяка не могу найти до сих пор.
В чем смысл - делаю навигацию камеры с небольшим движением по инерции после смены направления. Но почему-то весь блок где инерция должна по идее происходить - не происходит. Хотя если вставить отладчики, то видно что эти блоки выполняются.
PHP код:

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

public class 
CameraNavigation MonoBehaviour {
     
    public 
Transform CameraTransform//основа навигации камеры
    
public GameObject CameraTarget//цель камеры
    
public float SpeedSpeedXSpeedYRealSpeedXRealSpeedYSpeedXFromSpeedYFrom;
    public 
int ScreenWidthScreenHeight// размеры экрана
    
public bool inInertia//инерция камеры
        
    
List<floatBorders = new List<float>(); //список экранных маркеров
    
public enum GetBordersInfo {None,Left,Right,Up,Down,UpLeft,UpRight,DownLeft,DownRight}; // присвоение попавшей рамки
    
public GetBordersInfo BordersInfoBordersInfoSave;
    
    const 
float ScreenPercent 0.05f;
    
// Use this for initialization
    
    
    
void Start () {
    
ScreenWidth Screen.width;
    
ScreenHeight Screen.height;    
    
CameraTransform transform;
    
Speed 0.5f;
            
    
inInertia false;    
    
Borders.Add ((float)ScreenWidth*ScreenPercent); // 0 - слева
    
Borders.Add ((float)ScreenWidth*(1-ScreenPercent)); // 1 - справа
    
Borders.Add ((float)ScreenHeight*ScreenPercent); // 2 - сверху
    
Borders.Add ((float)ScreenHeight*(1-ScreenPercent)); // 3 - снизу 
    
    
}
    
    
// Update is called once per frame
    
void Update () {
    
        
СheckInBorders(); // - проверка попадания в рамки
    
CameraTransform.Translate(new Vector3(RealSpeedX,0,RealSpeedY));    
    
    }
        
    public 
void CheckInBorders () {
    
float MouseXCord Input.mousePosition.x;
    
float MouseYCord Input.mousePosition.y;
    
    if (
inInertia == false) {    
        
BordersInfoSave BordersInfo;
        if ((
MouseXCord <= Borders[0])&&(BordersInfo != GetBordersInfo.Left)) BordersInfo GetBordersInfo.Left;
        if ((
MouseXCord >= Borders[1])&&(BordersInfo != GetBordersInfo.Right)) BordersInfo GetBordersInfo.Right;
        if ((
MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.Down)) BordersInfo GetBordersInfo.Down;
        if ((
MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.Up)) BordersInfo GetBordersInfo.Up;
        if ((
MouseXCord <= Borders[0])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpLeft)) BordersInfo GetBordersInfo.UpLeft;
        if ((
MouseXCord >= Borders[1])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpRight)) BordersInfo GetBordersInfo.UpRight;
        if ((
MouseXCord <= Borders[0])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownLeft)) BordersInfo GetBordersInfo.DownLeft;
        if ((
MouseXCord >= Borders[1])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownRight)) BordersInfo GetBordersInfo.DownRight;
        if ((
MouseXCord >= Borders[0])&&(MouseXCord <= Borders[1])&&(MouseYCord >= Borders[2])&&(MouseYCord <= Borders[3])&&(BordersInfo != GetBordersInfo.None)) BordersInfo GetBordersInfo.None;
        }
        
    if (
BordersInfoSave != BordersInfo
        {
SpeedXFrom SpeedX;
        
SpeedYFrom SpeedY;
        
inInertia true;
        
        switch (
BordersInfo) {
        case 
GetBordersInfo.Left:
            
SpeedY Speed;
            
SpeedX 0f;
            break;
        case 
GetBordersInfo.Right:
            
SpeedY = -Speed;
            
SpeedX 0f;
            break;
        case 
GetBordersInfo.Up:
            
SpeedX Speed;
            
SpeedY 0f;
            break;
        case 
GetBordersInfo.Down:
            
SpeedX = -Speed;
            
SpeedY 0f;
            break;
        case 
GetBordersInfo.UpLeft:
            
SpeedX SpeedY Speed;
            break;
        case 
GetBordersInfo.DownLeft:
            
SpeedX = -Speed;
            
SpeedY Speed;
            break;
        case 
GetBordersInfo.UpRight:
            
SpeedX Speed;
            
SpeedY = -Speed;
            break;    
        case 
GetBordersInfo.DownRight:
            
SpeedX SpeedY = -Speed;
            break;
        case 
GetBordersInfo.None:
            
SpeedX SpeedY 0f;
            break;
            }
        
BordersInfoSave BordersInfo;
        }
                    
        if (
inInertia == true) {
            
RealSpeedX Mathf.Lerp(SpeedXFromSpeedXTime.time/2f);
            
RealSpeedY Mathf.Lerp(SpeedYFromSpeedYTime.time/2f);
            if ((
RealSpeedX == SpeedX)&&(RealSpeedY == SpeedY)) inInertia false;
        }
    }
    


По задумке переменная RealSpeedX должна плавно в течение двух секунд изменяться от SpeedXFrom до SpeedX, притом они отслеживаются при изменении направления движения камеры.
Т.е. если курсор был в левой части экрана GetBordersInfo.Left то при перемещении в центральную часть GetBordersInfo.None скорость должна плавно угаснуть с 1 до 0.
Но не выходит, всю голову поломал.

PS: Внимание, много говнокода!

dsd 14.10.2013 01:08

Ответ: Передача переменной в метод
 
RealSpeedX = Mathf.Lerp(SpeedXFrom, SpeedX, Time.time/2f); сдается мне что третье число в формуле должно лежать в диапазоне 0...1, а оно уже через 2 секунды от старта будет всегда больше 1, то есть надо выделить целую часть от такого числа и вычесть из исходного. Но хз как то оче сложно все для такой задачи.

EvilOkta 14.10.2013 01:15

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от dsd (Сообщение 268734)
RealSpeedX = Mathf.Lerp(SpeedXFrom, SpeedX, Time.time/2f); сдается мне что третье число в формуле должно лежать в диапазоне 0...1, а оно уже через 2 секунды от старта будет всегда больше 1

делал по справкам, там как раз рекомендуют Time.time делить на кол-во секунд на протяжении которых делается интерполяция, я пока для пристрела поставил две секунды чтобы отследить правильность реагирования скрипта.
Вроде до второй секунды Time.time/2f и будет давать диапазон 0..1 или я ошибаюсь?

pax 14.10.2013 07:24

Ответ: Передача переменной в метод
 
Как-то так

PHP код:

float _interpolationTime 0// поле класса
...
   if (
BordersInfoSave != BordersInfo
        {
SpeedXFrom SpeedX;
        
SpeedYFrom SpeedY;
        
inInertia true;
        
_interpolationTime 0// при начале инерции обнуляем время начала

...
   
        if (
inInertia == true) {
            
_interpolationTime += Time.deltaTime// прибавляем прошедшее время
            
RealSpeedX Mathf.Lerp(SpeedXFromSpeedX_interpolationTime/2f);
            
RealSpeedY Mathf.Lerp(SpeedYFromSpeedY_interpolationTime/2f); 


EvilOkta 14.10.2013 14:52

Ответ: Передача переменной в метод
 
Спасибо pax! То что нужно. Сразу в голову не пришло что нужно фиксировать начало инерции.

EvilOkta 15.10.2013 21:49

Ответ: Передача переменной в метод
 
как-нибудь можно отследить одновременное нажатие двух клавиш с помощью Input.GetKey? в том плане, что одна кнопка вызывает одно действие, вторая - другое, а две вместе третье

pax 15.10.2013 22:46

Ответ: Передача переменной в метод
 
Ну...
PHP код:

if(Input.GetKey(1) && Input.GetKey(2)){
// две
} else if(Input.GetKey(1){
 
// первая
}else if(Input.GetKey(2){
 
// вторая



EvilOkta 16.10.2013 00:33

Ответ: Передача переменной в метод
 
спасибо, в справке не нашел что можно с помощью & отследить сразу две )

EvilOkta 06.03.2014 12:09

Ответ: Передача переменной в метод
 
Ребят подскажите такой вопрос:
в общем, работаю сейчас над навигацией камеры, сделал скрипт перемещения камеры и вращения, все делал через translate и rotation.
Перемещение работает нормально, меня устраивает по удобству, а вот с вращением беда выглядит убого и по удобству тоже не особо хорошо получилось.
Начал думать и читать справки. Появилась идея сделать вращение (и перемещение до кучи) через Rigidbody, AddForce и AddTorque (в режимах импульса и силы) отслеживая перемещения мыши и генерируя преобразованные векторы направления и вращения. По задумке такую систему можно будет потом безболезнено перенести на андроид для управления жестами.

Собственно вопрос: насколько это правильно? Т.к. знаю что каждый кто разрабатывает игру рано или поздно сталкивается с навигацией камеры, притом на одном из ранних этапов разработки. Какой метод оптимальнее подходит?
Расскажите как вы реализуете работу с камерой, может у вас есть какие-то алгоритмические решения выработанные с опытом.

Mr_F_ 06.03.2014 12:23

Ответ: Передача переменной в метод
 
какая камера нужна то для какого вида?
в любом случае, через ригидбоди это какой-то ужасный изврат.
мауслуки обычные удобнее всего через углы эйлера делать имхо.
в стандартных ассетах юнити уже есть пример мауслука для первого лица, можешь его за основу брать.

EvilOkta 06.03.2014 15:05

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от Mr_F_ (Сообщение 276174)
какая камера нужна то для какого вида?

вид стратегический, над полем боя. Что-то отдаленно похожее как в игре "Проклятые земли"

по поводу ригидбоди задумался т.к. это в теории (понимаю что извратство) позволит сделать навигацию камеры с помощью жестов мыши и соответственно жестом пальцами в тач-варианте (аналог: скроллинг веб-страницы на планшете). Передавать и вращать не физическим движком а используя Transform слишком деревяно выходит. Или все-таки это более оптимальный вариант просто требующий доработки?

Mr_F_ 06.03.2014 17:19

Ответ: Передача переменной в метод
 
я не понимаю как связан физический движок и жесты мыши.

EvilOkta 06.03.2014 17:41

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от Mr_F_ (Сообщение 276181)
я не понимаю как связан физический движок и жесты мыши.

к примеру слайд мышью: в одной точке зажать ЛКМ, в другой отпустить, получится вектор направления который можно приложить к камере заставив ее двигаться в этом направлении с последующим затуханием (drag инерция при использовании rigidbody), то же самое слайд мыши при нажатии ПКМ, только для определения силы вращения (что-то вроде мауслук но с инерцией).
Я просто хочу организовать доводку и нативное управление и переложить расчеты на физ.движок а не на геометрические и физические формулы определения кватерниона вращения, направления движения и величины векторов с которыми перемещение и вращение происходит.

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

Или все что я расписал выше легко реализуется без rigidbody?

pax 06.03.2014 18:19

Ответ: Передача переменной в метод
 
А такое пробовал?
http://docs.unity3d.com/Documentatio...moothDamp.html

EvilOkta 07.03.2014 10:49

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от pax (Сообщение 276194)

Спасибо, попробую. Плюс в справке нашел аналог для вращения - буду изучать

EvilOkta 13.05.2014 12:06

Ответ: Передача переменной в метод
 
Определить координаты мыши на плоскости в пространстве можно только рейкастом или есть какие-то математические варианты, типа проекции экранных координат в мировые?
Если только рейкаст хотел уточнить - запускать луч каждый Update не слишком будет грузить ресурсы компьютера? Или есть какие-то методы оптимизации?

pax 13.05.2014 17:54

Ответ: Передача переменной в метод
 
Тебе нужно:
  1. Camera.ScreenPointToRay
  2. Plane (Plane.Raycast)

EvilOkta 27.05.2014 18:06

Ответ: Передача переменной в метод
 
ох туплю.... как проверить число типа float на целочисленность, т.е. что у его текущего значения нет дробной части?

pax 27.05.2014 18:22

Ответ: Передача переменной в метод
 
if(Mathf.Abs(floatVar - (int)floatVar) < 0.00001f){

}

EvilOkta 10.06.2014 23:44

Ответ: Передача переменной в метод
 
а как из рейкаста удалить взаимодействие со группой объектов кроме определенных? Чтобы информация о столкновении считывалась только с определенных объектов?
Чувствую надо копать в слоях, но подскажите хотя бы принцип
upd. вроде есть способ через Layer Mask пока роюсь в справках

seaman 11.06.2014 15:09

Ответ: Передача переменной в метод
 
Код:

static bool Raycast(Vector3 origin, Vector3 direction, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);
layerMask - маска слоя, которая используется для селективного игнорирования коллайдеров при пускании луча.
Про слои тут:
Layers
Там есть прямо пример селективного пускания лучей.

EvilOkta 16.06.2014 10:19

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от seaman (Сообщение 282488)
Код:

static bool Raycast(Vector3 origin, Vector3 direction, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);
layerMask - маска слоя, которая используется для селективного игнорирования коллайдеров при пускании луча.
Про слои тут:
Layers
Там есть прямо пример селективного пускания лучей.

Спасибо, вроде разобрался но ползая по справкам и форумам не понял немного по слоям:
- можно ли задавать лучу группу слоев а не один (например - поверхность уровня, динамичные объекты, статичные объекты, другие. Или в этом случае пускается например два луча отдельно по каждому слою?
- программно менять слой в рантайме, возможно ли? например объект перемещать из статичных в динамичные и т.д

EvilOkta 05.08.2014 00:04

Ответ: Передача переменной в метод
 
Я снова со своими тупыми вопросами.
Продолжаю делать скрипт камеры. Поставило в тупик следующее:
Код:

public void Camera_SlideCalc () {
SlideVector = Vector3.zero;
CameraTarget.position = Vector3.SmoothDamp(CameraTarget.position,CameraTarget.position+SlideVector,ref velocity,2f);

Код:

private Vector3 velocity = Vector3.zero;
По логике если стартовая точка и конечная совпадает (т.к. прибавляется нулевой вектор) то движения не должно быть, а оно есть. Больше никаких источников возникновения движения нет. Если комментирую строчку со SmoothDamp то движение исчезает.

Всю голову поломал, видимо что-то опять недопонимаю...
может velocity обнулять нужно после вызова функции?

upd:
сократил функцию до вида, проблема осталась:
Код:

public void Camera_SlideCalc () {
CameraTarget.position = Vector3.SmoothDamp(CameraTarget.position,CameraTarget.position,ref velocity,2f);}

такое ощущение, что я не до конца понял принцип работы SmoothDamp. Почему если начало и конец движения равны движение все равно есть?

pax 05.08.2014 07:54

Ответ: Передача переменной в метод
 
Ты двигаешь цель, а камера как движется?

EvilOkta 05.08.2014 12:17

Ответ: Передача переменной в метод
 
камера наследует движение от цели как дочерний объект, пробовал вместо трансформа цели поставить трансформ камеры - то же самое.
Вот код целиком. Функция подобного движения активируется при долгом нажатии на левую кнопку мыши. Все действия в функциях с пометкой Slide

PHP код:

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

public class 
CameraNavigation MonoBehaviour {
     
    public 
Transform CameraTransform//основа навигации камеры
    
public Transform CameraTargetCameraRotateCameraView//цель камеры
    
public Transform Cursor;
    public 
Camera RealCamera;
    private 
float SpeedSpeedXSpeedYRealSpeedXRealSpeedYSpeedXFromSpeedYFrom// эталонная скорость по координатам, реальная скорость, слепки для скорости
    
public int ScreenWidthScreenHeight// размеры экрана
    
public bool inInertia//инерция камеры
    
    
public List<floatBorders = new List<float>(); //список экранных маркеров
    
public enum GetBordersInfo {None,Left,Right,Up,Down,UpLeft,UpRight,DownLeft,DownRight}; // присвоение попавшей рамки
    
private GetBordersInfo BordersInfoBordersInfoSave//контейнер для хранения маркеров и слепка маркеров
    
public float InertiaTimeInertiaTimeScaleSlideTimeSlideTrigger// время инерции и скорость инерции
    
public enum SlideStatus {Idle,Calc,Run}; // стадия слайда
    
public SlideStatus ActiveSlideStatus;
    const 
float ScreenPercent 0.01f// размер рамки
    
public float MouseXCordMouseYCordMouseXMouseY// данные о мыши
    
public Vector3 MoveVectorSlideVectorSlideMem,SlideStart//вектор перемещения, вектор скольжения,вектор слепка, вектор старта скольжения
    
public Vector2 StartSlidePos,SlidePos;
    public 
float RotSpeedZoomDistanceZoomingSlideSpeed// скорость вращения
    
private float SlideSecond;
    private 
Vector3 velocity Vector3.zero;
    public 
Ray Position_on_plane;
    public 
RaycastHit RayInfo;
    public 
Vector3 PointRayCursorPosition;
    
    
void Start () {
    
Screen.showCursor true;
    
ScreenWidth Screen.width;
    
ScreenHeight Screen.height;    // размеры экрана
    
CameraTransform transform// трансформации камеры для перемещения
    
Speed 0.1f// скорость движения камеры
    
RotSpeed 100f;
    
SlideSpeed 10f;
    
InertiaTimeScale 3f;    // скорость движения во время инерции
    
SlideTrigger SlideSecond 0.2f// время включения режима скольжения, частота съема слепка для слайда в секундах
    
inInertia false;    
    
ActiveSlideStatus SlideStatus.Idle;    
    
Borders.Add ((float)ScreenWidth*ScreenPercent); // 0 - слева
    
Borders.Add ((float)ScreenWidth*(1-ScreenPercent)); // 1 - справа
    
Borders.Add ((float)ScreenHeight*ScreenPercent); // 2 - сверху
    
Borders.Add ((float)ScreenHeight*(1-ScreenPercent)); // 3 - снизу 
    
CameraTarget.position = new Vector3(0,0,0); // установка цели камеры
    
CameraView.position = new Vector3 (0,0,-5); // установка расстояния до цели
    
CameraRotate.position CameraTarget.position// выравнивание позиции цели и основы вращения
    
CameraRotate.rotation CameraTarget.rotation// выравнивание вращения цели и основы вращения
    
RotateCamera();    // запуск ограничителя высоты поворота
    
}
    
    
// Update is called once per frame
    
void Update () {
    
MouseX Input.GetAxis("Mouse X"); // отклонение мыши Х
    
MouseY Input.GetAxis("Mouse Y"); // отклонение мыши У
    
Zooming Input.GetAxis("Mouse ScrollWheel");
    
Camera_Navigation();    
    }        
    
    public 
void CheckInBorders () { // проверка попадания в рамки
    
MouseXCord Input.mousePosition.x;
    
MouseYCord Input.mousePosition.y// координаты мыши
                    
    
if (!inInertia) {    // если работает инерция то
        
BordersInfoSave BordersInfo// сделать слепок текущего квадрата экрана
        
if ((MouseXCord <= Borders[0])&&(BordersInfo != GetBordersInfo.Left)) BordersInfo GetBordersInfo.Left// мышь в левой части
        
if ((MouseXCord >= Borders[1])&&(BordersInfo != GetBordersInfo.Right)) BordersInfo GetBordersInfo.Right// мышь в правой части
        
if ((MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.Down)) BordersInfo GetBordersInfo.Down// мышь в нижней части
        
if ((MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.Up)) BordersInfo GetBordersInfo.Up// мышь в верхней части
        
if ((MouseXCord <= Borders[0])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpLeft)) BordersInfo GetBordersInfo.UpLeft// Лево-вверх
        
if ((MouseXCord >= Borders[1])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpRight)) BordersInfo GetBordersInfo.UpRight// Право-вверх
        
if ((MouseXCord <= Borders[0])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownLeft)) BordersInfo GetBordersInfo.DownLeft// Лево-Вниз
        
if ((MouseXCord >= Borders[1])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownRight)) BordersInfo GetBordersInfo.DownRight// Право-Вниз
        
if ((MouseXCord >= Borders[0])&&(MouseXCord <= Borders[1])&&(MouseYCord >= Borders[2])&&(MouseYCord <= Borders[3])&&(BordersInfo != GetBordersInfo.None)) BordersInfo GetBordersInfo.None// Курсор в центральной части
        
}
        
    if (
BordersInfoSave != BordersInfo) { // при смене квадрата
        
SpeedXFrom SpeedX
        
SpeedYFrom SpeedY// начальное значение скорости
        
inInertia true// включить инерцию
        
InertiaTime 0f// запустить таймер инерции    
        
ChangeSpeed (); // расчитать конечную скорость
        
BordersInfoSave BordersInfo// сохранить текущий квадрат
        
}
                    
    if (
inInertia
        { 
// если инерция включена
            
InertiaTime += Time.deltaTime// отчет времени
            
RealSpeedX Mathf.Lerp(SpeedXFromSpeedXInertiaTime*InertiaTimeScale); // плавное изменение скорости Х
            
RealSpeedY Mathf.Lerp(SpeedYFromSpeedYInertiaTime*InertiaTimeScale);// плавное изменение скорости У
            
if ((RealSpeedX == SpeedX)&&(RealSpeedY == SpeedY)) inInertia false// если скорость достигнута - отключить инерцию
        
}
    }
    
    public 
void ChangeSpeed () { // изменение скорости
    
        
switch (BordersInfo) { // куда перешел курсор мыши
        
case GetBordersInfo.Left
            
SpeedX = -Speed;
            
SpeedY 0f// значения скорости
            
break;
        case 
GetBordersInfo.Right:
            
SpeedX Speed;
            
SpeedY 0f// значения скорости
            
break;
        case 
GetBordersInfo.Up:
            
SpeedY Speed;
            
SpeedX 0f// значения скорости
            
break;
        case 
GetBordersInfo.Down:
            
SpeedY = -Speed;
            
SpeedX 0f// значения скорости
            
break;
        case 
GetBordersInfo.UpLeft:
            
SpeedX = -Speed;
            
SpeedY Speed// значения скорости
            
break;
        case 
GetBordersInfo.DownLeft:
            
SpeedX SpeedY = -Speed// значения скорости
            
break;
        case 
GetBordersInfo.UpRight:
            
SpeedX SpeedY Speed// значения скорости
            
break;    
        case 
GetBordersInfo.DownRight:
            
SpeedX Speed;
            
SpeedY = -Speed// значения скорости
            
break;
        case 
GetBordersInfo.None:
            
SpeedX SpeedY 0f// значения скорости
            
break;
            }    
    }
    
    public 
void CheckKeyBoardRule () { // управление с клавиатуры
    
if (BordersInfo == GetBordersInfo.None)    {
        if (
Input.GetKey(KeyCode.LeftArrow)) BordersInfo GetBordersInfo.Left;    
        if (
Input.GetKey(KeyCode.RightArrow)) BordersInfo GetBordersInfo.Right;    
        if (
Input.GetKey(KeyCode.UpArrow)) BordersInfo GetBordersInfo.Up;    
        if (
Input.GetKey(KeyCode.DownArrow)) BordersInfo GetBordersInfo.Down;
        if (
Input.GetKey(KeyCode.LeftArrow)&&Input.GetKey(KeyCode.UpArrow)) BordersInfo GetBordersInfo.UpLeft;    
        if (
Input.GetKey(KeyCode.LeftArrow)&&Input.GetKey(KeyCode.DownArrow)) BordersInfo GetBordersInfo.DownLeft;    
        if (
Input.GetKey(KeyCode.RightArrow)&&Input.GetKey(KeyCode.UpArrow)) BordersInfo GetBordersInfo.UpRight;    
        if (
Input.GetKey(KeyCode.RightArrow)&&Input.GetKey(KeyCode.DownArrow)) BordersInfo GetBordersInfo.DownRight;    
        
ChangeSpeed (); // изменить скорость
        
}
        }
    
    public 
void RotateCamera() {
    if (
Input.GetMouseButton(1)) 
        { 
// если нажата правая кнопка мыши
            
CameraRotate.Rotate (-MouseY*RotSpeed*Time.deltaTime,0f,0f);     // вращать по Х
            
if (MouseYCord>ScreenHeight/2fCameraTransform.Rotate (0f,-MouseX*RotSpeed*Time.deltaTime,0f); // вращать по У в верхней половине экрана
            
else CameraTransform.Rotate (0f,MouseX*RotSpeed*Time.deltaTime,0f); // вращать по У в нижней половине экрана        
        
}
    
CameraRotate.eulerAngles = new Vector3 (Mathf.Clamp(CameraRotate.rotation.eulerAngles.x,30f,80f),CameraRotate.eulerAngles.y,CameraRotate.eulerAngles.z); // ограничители
    
}
    
    public 
void ChangeMove (GetBordersInfo InBorders) {
    switch (
InBorders) {
        case (
GetBordersInfo.Left):
            
CameraTransform.Translate(0f,0f,MouseY*Time.deltaTime*2f);    
        break;    
        case (
GetBordersInfo.Right):
            
CameraTransform.Translate(0f,0f,MouseY*Time.deltaTime*2f);    
        break;
        case (
GetBordersInfo.Up):
            
CameraTransform.Translate(MouseX*Time.deltaTime*2f,0f,0f);    
        break;        
        case (
GetBordersInfo.Down):
            
CameraTransform.Translate(MouseX*Time.deltaTime*2f,0f,0f);    
        break;        
        }
    }
    
    public 
void Camera_zoom () {
        
ZoomDistance Mathf.Clamp(Vector3.Distance(CameraView.transform.position,CameraRotate.transform.position),2f,10f);    
        if ((
ZoomDistance<10f)&(ZoomDistance>2f)) CameraView.Translate (Vector3.forward*Zooming);
        if ((
Zooming<0f)&(ZoomDistance==2f)) CameraView.Translate (Vector3.forward*Zooming);
        if ((
Zooming>0f)&(ZoomDistance==10f)) CameraView.Translate (Vector3.forward*Zooming);
    }
    
    public 
void Camera_SlideCalc () {
    
    
//SlideVector = Vector3.zero;
    
    
CameraTransform.position Vector3.SmoothDamp(CameraTransform.position,CameraTransform.position,ref velocity,2f);    
            
    if (
Input.GetMouseButtonUp(0)) 
        {
            
ActiveSlideStatus SlideStatus.Run;
            
SlideTime 0f;
            
SlideTrigger SlideSecond;
        }    
    }    
    
    public 
void Camera_Navigation() {
    
CheckInBorders(); // - проверка попадания в рамки
    
CheckKeyBoardRule (); // - управление c клавиатуры
        
if (BordersInfo == GetBordersInfo.NoneRotateCamera(); // вращение только в центральной области игры
    
MoveVector = new Vector3(RealSpeedX,0,RealSpeedY); //вектор перемещения
    
CameraTransform.Translate (MoveVector); //перемещаем камеру в соответствии со скоростями
    
ChangeMove(BordersInfo); // расчет скоростей
    
Camera_zoom(); // Зум        
    
Camera_SetPosition_on_plane ();
        if (
Input.GetMouseButton(0)&(ActiveSlideStatus==SlideStatus.Idle)) SlideTime += Time.deltaTime// если слайда нет, то включить слайд через 0.2 сек
        
if (SlideTime SlideTrigger// готовимся сделать слайд
            
{
                
SlideStart Cursor.position// слепок текущего положения
                
SlideTime 0f// обнулить таймер
                
ActiveSlideStatus SlideStatus.Calc;    // начать расчет слайда
            
}
        if (
ActiveSlideStatus==SlideStatus.CalcCamera_SlideCalc();    // расчет слайда
        
if (ActiveSlideStatus==SlideStatus.RunCamera_SlideRun();
    
    }
    
    public 
void Camera_SlideRun() {
    
    
ActiveSlideStatus SlideStatus.Idle;    
    }
    
    public 
void Camera_SetPosition_on_plane () {
    
Position_on_plane RealCamera.ScreenPointToRay(new Vector3(MouseXCord,MouseYCord,0f)); // пусить луч в координаты мыши
    
if (Physics.Raycast(Position_on_planeout RayInfoMathf.Infinity)) // если пересечение то 
        
{
            
PointRay RayInfo.point;    // получаем информацию о столкновении
            
CursorPosition = new Vector3(Mathf.Round(PointRay.x),0f,Mathf.Round(PointRay.z)); //позиция курсора на плоскости
        
}    
    
Cursor.position Vector3.SmoothDamp(Cursor.position,CursorPosition,ref velocity,0.1f);    // плавно переместить курсор в точку назначения
    
}    



pax 05.08.2014 14:04

Ответ: Передача переменной в метод
 
У тебя там кажется влияет
PHP код:

Speed 0.1f// скорость движения камеры 

Пртестировать не могу, не понял зачем столько полей у скрипта

EvilOkta 05.08.2014 14:35

Ответ: Передача переменной в метод
 
разобрался, оказывается конфликтовали две velocity из разных частей кода. Я использовал один и тот же контейнер для хранения - видимо это и давало искажение.

EvilOkta 26.03.2015 00:20

Ответ: Передача переменной в метод
 
Вопрос на логику кода, читал сегодня справки, думал над реализацией.
В общем висит у меня на камере метод, отвечающий за тряску камеры.

Хочу разобраться как лучше реализовать следующую логику:
Метод тряски могут вызывать разные игровые объекты и события (взрывы, падения, повреждение и т.п) из собственных скриптов.
Самый простой способ как я понял это отправка сообщений на активацию скрипта из других с помощью getComponent.

Появился вопрос следующий, в методе есть возможность задавать длительность тряски с помощью переменной. Как реализовать установку длительности тряски из тех скриптов которые будут вызывать этот метод?

Через getComponent смысл понятен, просто сначала посылать в скрипт значение продолжительности тряски и затем активировать его.

Рассматриваю вариант с подпиской метода на события, но мне кажется это слишком запутывает задачу (или нет - подскажите?) тогда событие, которое активирует метод должно задать ему длительность. Как это реализовать? Сориентируйте как должен выглядеть скрипт чтобы в него можно было передавать длительность (shakeOver) из других скриптов, которые вызывают событие.

Интересует изменение метода ShakeIsDo (), как его доработать? Надеюсь правильно объяснил вопрос.
Не пинайте в справки, я просто опять упускаю какую-то базовую концепцию ООП. Отправлять в метод/функцию объект для его модификации и возврата с помощью return я разобрался, а тут требуется void но с заданным параметром, которым управляют другие объекты, совершенно разного типа.

PHP код:

public class CameraShake MonoBehaviour {
    
public 
Transform CameraTransform;
public 
bool isShakeshakeRun;
public 
float shakeAmountshakeOvershakeTimeshakeTimeStop;
public 
Vector3 OriginalPos,ShakePos,ShakeVector;    
    
    
void Start () {
    
isShake false;
    
shakeRun false;
    
shakeAmount 0.1f;
    
shakeOver 0.1f;
    }
    
 
void Update() {
      
    if ((
Input.GetKey(KeyCode.Space))) {
        
isShake true;
        
shakeTime 0f;
        
OriginalPos CameraTransform.position;
        
shakeRun true;
        }    
        
    if ((
Input.GetKey(KeyCode.B))) {
            
isShake false;
            
shakeTime 0f;
        
CameraTransform.position OriginalPos;
        }
        
    if (
shakeRunShakeIsDo();     
        
}
    public 
void ShakeIsDo () 
        {
        
ShakePos CameraTransform.position;    
        
ShakeVector Random.insideUnitSphere shakeAmount;
        
ShakeVector = new Vector3(0f,ShakeVector.y,0f);
        
CameraTransform.position = new Vector3(ShakePos.x,ShakePos.y+ShakeVector.y,ShakePos.z);    
    if (((
ShakePos.y-OriginalPos.y)>shakeOver)||((ShakePos.y-OriginalPos.y)<-shakeOver)) CameraTransform.position = new Vector3(ShakePos.x,OriginalPos.y,ShakePos.z);
        
shakeTime += Time.deltaTime;
        if (
shakeTime >= shakeOvershakeRun false;
        }


в коде есть дублирующие переменные isShake и ShakeRun не обращайте внимание, вырезал части - немного другой подход был сначала.

Жека 26.03.2015 06:46

Ответ: Передача переменной в метод
 
Можно сделать через getComponent, ведь ты по сути получаешь этим способом экземпляр класса и можешь вызывать любой метод.
Делаешь public метод ShakeStart с нужными параметрами, как минимум с параметром shakeOver
PHP код:

public void ShakeStart(float shakeOver) {
    
this.shakeOver shakeOver;
    
shakeTime 0f;
    
OriginalPos CameraTransform.position;
    
isShake true;


далее из других скриптов получаешь экземпляр и вызываешь метод
PHP код:

CameraShake shaker camera.GetComponent<CameraShake>();
shaker.ShakeStart(2.5f); 

Если время тряски фиксировано для разных случаев, то можно сделать константы (static readonly) в классе CameraShake и использовать их, например
PHP код:

shaker.ShakeStart(CameraShake.DELAY_FOR_EXPLOSION); 

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

Жека 26.03.2015 10:25

Ответ: Передача переменной в метод
 
Ещё: чтобы каждый раз не доставать экземпляр скрипта через
CameraShake shaker = camera.GetComponent<CameraShake>();
можно сделать статическую переменную в классе CameraShake и статический метод тряски, и обращаться напрямую через имя класса:
PHP код:

private static CameraShake Instance;
void Awake() {
    
Instance this;
}
private 
void ShakeStartLocal(float shakeOver) { 
    
this.shakeOver shakeOver
    
shakeTime 0f
    
OriginalPos CameraTransform.position
    
isShake true
}  
public static 
void ShakeStart(float shakeOver) { 
    
Instance.ShakeStartLocal(shakeOver);
}

............

CameraShaker.ShakeStart(0.5f); 


EvilOkta 07.04.2015 22:19

Ответ: Передача переменной в метод
 
Жека огромное спасибо, все доходчиво! На основе советов сделал целый класс который передается в функцию с разными наборами параметров для тряски, не только длительность но и другие
)).

Сейчас встал в ступор снова. Задача, рейкастом выделить объекты на плоскости. Написал код, рейкаст исправно отрисовывает курсор в месте пересечения, но ни в какую не ловит объекты, которые на нем расположены. В чем беда? Layer стоит у объектов Default

PHP код:

using UnityEngine;
using System.Collections;

public class 
SelectUnit MonoBehaviour {

    public 
Transform Cursor;
    public 
Camera RealCamera;
    public 
float MouseXCordMouseYCord;
    private 
Vector3 velocityCur Vector3.zero;
    public 
Ray Position_on_plane;
    public 
RaycastHit RayInfo;
    public 
Vector3 PointRayCursorPosition;
    public 
GameObject Unit_was_Hit;
    
    
void Start () {
    
    }
    
    
void Update () {
    
MouseXCord Input.mousePosition.x;
    
MouseYCord Input.mousePosition.y;
    
SetPosition_on_plane ();
    
Analize_Hit_Unit ();
    }
    
    public 
void SetPosition_on_plane () {
    
Position_on_plane RealCamera.ScreenPointToRay(new Vector3(MouseXCord,MouseYCord,0f)); // пусить луч в координаты мыши
    
if (Physics.Raycast(Position_on_planeout RayInfoMathf.Infinity)) // если пересечение то 
        
{
            
PointRay RayInfo.point;    // получаем информацию о столкновении
            
CursorPosition = new Vector3(Mathf.Round(PointRay.x),0f,Mathf.Round(PointRay.z)); //позиция курсора на плоскости
        
}    
    
Cursor.position Vector3.SmoothDamp(Cursor.position,CursorPosition,ref velocityCur,0.1f);    // плавно переместить курсор в точку назначения
    
}    
    
    public 
void Analize_Hit_Unit () {
    if (
RayInfo.transform!=nullUnit_was_Hit = (GameObject)RayInfo.collider.gameObject// вот тут происходит поиск объекта
        
}


Пробовал информацию доставать и из коллайдера и из трансформа, результат такой же.

Nex 07.04.2015 23:59

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 294895)
Жека огромное спасибо, все доходчиво! На основе советов сделал целый класс который передается в функцию с разными наборами параметров для тряски, не только длительность но и другие
)).

Сейчас встал в ступор снова. Задача, рейкастом выделить объекты на плоскости. Написал код, рейкаст исправно отрисовывает курсор в месте пересечения, но ни в какую не ловит объекты, которые на нем расположены. В чем беда? Layer стоит у объектов Default

PHP код:

... 

Пробовал информацию доставать и из коллайдера и из трансформа, результат такой же.

У меня показывает с каким объектом пересечение. Проверь если ли коллайдер у выделяемых объектов и не стоит ли на них "IsTrigger".

EvilOkta 08.04.2015 09:41

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от Nex (Сообщение 294898)
У меня показывает с каким объектом пересечение. Проверь если ли коллайдер у выделяемых объектов и не стоит ли на них "IsTrigger".

спасибо )) нашел проблему! Оказалось size у коллайдеров почему-то сбросился на 0, вот рейкаст их и не видел. Сейчас все заработало! Спасибо!))

EvilOkta 08.04.2015 22:14

Ответ: Передача переменной в метод
 
Есть какая-нибудь альтернатива использовать GameObject.FindGameObjectsWithTag для заполнения списка List<>, а не массива []? Делаю через промежуточный массив, но понимаю что тем самым удваиваю нагрузку на память.
PHP код:

public List<GameObjectUnitList = new List<GameObject>(); 
    public 
GameObject[] UnitsInScene;
        
    
void Start () {
    
UnitsInScene GameObject.FindGameObjectsWithTag("Unit Player");
    for (
int i=0i<=UnitsInScene.Lengthi++) {UnitList.Add (UnitsInScene[i]);}
    } 

Код работает как надо, но ищу вариант составления списка юнитов сразу в List (ибо массив динамический и методы нужны). Есть такие способы?

Nex 08.04.2015 22:56

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 294914)
Есть какая-нибудь альтернатива использовать GameObject.FindGameObjectsWithTag для заполнения списка List<>, а не массива []?

Возможно так
Код:

UnitList.AddRange(GameObject.FindGameObjectsWithTag("Unit Player"));

EvilOkta 09.04.2015 13:57

Ответ: Передача переменной в метод
 
Ребят, посоветуйте книги/статьи/материалы которые можно почитать по системам событий, делегатам, подпискам и синглтонам. Вчера уперся в стену в скрипте, понял что без понимания этих механизмов дальше в разработке не продвинусь, так как сложность взаимодействия скриптов друг с другом растет в геометрической прогрессии, а getcomponent на каждый чих скрипта делать накладно )))
Хочу разобраться в простейшем примере, уже поставил задачу. Смысл такой - есть список объектов. Нужно создать событие (выделение конкретного объекта мышкой), на которое подпишутся все остальные объекты и проделают у себя манипуляции со своими скриптами.
Читал пару статей на хабре, но не могу в голове уложить алгоритм - где объявлять издателя, где производить подписку, какая роль статических классов и методов во всем этом.
В общем что посоветуете? MDSN уже почитал - для восприятия сложно.

Igor 09.04.2015 22:45

Ответ: Передача переменной в метод
 
http://gameprogrammingpatterns.com/contents.html
Можно каждую главу отдельно от других читать, написано довольно хорошо и понятно (на мой взгляд). Ещё по паттернам читал книгу "банды четырёх", но не впечатлился.

EvilOkta 14.04.2015 18:38

Ответ: Передача переменной в метод
 
такой вопрос, принципиально важно где объявлять делегат - в теле класса или вне его? Задача чтобы делегатами могли пользоваться все объекты. Проблем с видимостью не будет?
Еще момент, если одно и то же событие объявляется в скрипте, который висит на нескольких объектах - ничего страшного? или лучше создать отдельный класс где описывать события?

Andvrok 14.04.2015 18:46

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 294982)
такой вопрос, принципиально важно где объявлять делегат и событие - в теле класса или вне его? Задача чтобы делегатами и событиями могли пользоваться все объекты. Проблем с видимостью не будет?

Евенты в классе объявляй (иначе и не получится), делегаты вне, чтобы обращатся просто по имени а не еще и класс указывать.

EvilOkta 14.04.2015 19:14

Ответ: Передача переменной в метод
 
а как выделить эвенты в отдельный класс? чтобы доступ к ним получать с разных объектов? Сделал класс
PHP код:

public class Event_List MonoBehaviour {
public 
event On_SelectUnit_Event Event_Select_Unit;    


повесил его на объект, у которого через getcomponent получил этот эвент, но при попытке его запустить в коде
PHP код:

Event_Select_Unit(); 

появляется ошибка, что нельзя брать эвент другого класса.
делегат объявил отдельно вне класса вот так:
PHP код:

public delegate void On_SelectUnit_Event(); 

error CS0428: Cannot convert method group `GetComponent' to non-delegate type `Event_List'. Consider using parentheses to invoke the method
error CS0070: The event `Event_List.Event_Select_Unit' can only appear on the left hand side of += or -= when used outside of the type `Event_List'

пните в нужном направлении.. ))

Andvrok 14.04.2015 19:44

Ответ: Передача переменной в метод
 
У меня такое ощущение, что ты не совсем понимаешь, как евенты работают, и что это вообще. Плюс ошибки, которые ты скинул, вполне ясно говорят, в чём трабла. Логично, что ты не можешь получить евент геткомпонентом. Логично, что ты не можешь его вызвать. Это не так работает. Тебе точно евенты нужны?

http://habrahabr.ru/post/213809/
http://habrahabr.ru/post/245219/

EvilOkta 14.04.2015 20:38

Ответ: Передача переменной в метод
 
мне важно понимать как они работают, так как логически в голове алгоритмы под них выстраиваются. Я осознаю что мое понимание делегатов и событий весьма поверхностно.

Переделал код таким образом:
PHP код:

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

public 
delegate void On_SelectUnit_Event();
public class 
Delegate_for_Event MonoBehaviour {
    public 
int i;
    public List<
GameObjectUnitList = new List<GameObject>(); // список юнитов
    
public MoveGamer UnitDelegate;
    public 
event On_SelectUnit_Event Event_Select_Unit;
        
    
void Awake()    {
        
UnitList.AddRange(GameObject.FindGameObjectsWithTag("Unit Player"));
        for (
int i=0i<UnitList.Counti++) {
            
UnitDelegate UnitList[i].GetComponent<MoveGamer>();
            
Event_Select_Unit += UnitDelegate.Deselect_If_Not_Active;
        }
    }
    public 
void Event_Select_Unit_Start() {
    
Event_Select_Unit();    
    }


Объявлен делегат, создано событие, осуществлена подписка объектов на него.

В этом коде (другой скрипт) осуществляется вызов события:
PHP код:

public void OnMouseDown() {
    if (
Mark_Unit)    {
        
Event_Aggregator.Event_Select_Unit_Start();
    }
}
    public 
void Deselect_If_Not_Active () {
        
Debug.Log(this.name);
    } 

код работает, подписчики исправно реагируют на событие, событие отвязано от объектов (в одном отдельном скрипте).
Теперь я правильно понял логику применения событий и делегатов? Хотя бы на базовом уровне?))

Andvrok 14.04.2015 20:46

Ответ: Передача переменной в метод
 
В общем да. Главное сразу приучи себя или делать проверку на null или делегат объявлять с пустышкой (по первой ссылке в комментах есть варианты, как это делать), или потом офигеешь искать, откуда эксцепшены валятся.

EvilOkta 06.05.2015 11:28

Ответ: Передача переменной в метод
 
Снова вопрос для размышлений. Думаю над реализацией поршневого механизма, но интересует какой подход выбрать. В чем суть:

Зеленым показан объект, который нужно толкнуть поршнем. Поршень обозначен серым и синим. Синяя часть анимирована. Постарался изобразить начало и конец анимации.
Теперь вопрос: как мне привязать перемещение объекта к анимации таким образом, чтобы стенка поршня не проходила через объект и двигалась вместе с объектом? Просто пока не понятно как с помощью анимации одного объекта синхронизировать перемещение другого. или только на глаз подгонкой скорости анимации?
Сам объект у меня перемещается с помощью собственной анимации, как раз была идея как-то это совместить с анимацией поршня, чтобы смотрелось адекватно.

PS. Можно тему переименовать в что-то типа "Проблемы разработки от EvilOkta"? А то название темы уже не актуально )

PPS. предвидя вопросы, сразу отвечу - нет, не майнкрафт )) даже близко ))

Nex 06.05.2015 13:47

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 295621)
Снова вопрос для размышлений. Думаю над реализацией поршневого механизма, но интересует какой подход выбрать. В чем суть:

Зеленым показан объект, который нужно толкнуть поршнем. Поршень обозначен серым и синим. Синяя часть анимирована. Постарался изобразить начало и конец анимации.
Теперь вопрос: как мне привязать перемещение объекта к анимации таким образом, чтобы стенка поршня не проходила через объект и двигалась вместе с объектом? Просто пока не понятно как с помощью анимации одного объекта синхронизировать перемещение другого. или только на глаз подгонкой скорости анимации?
Сам объект у меня перемещается с помощью собственной анимации, как раз была идея как-то это совместить с анимацией поршня, чтобы смотрелось адекватно.

PS. Можно тему переименовать в что-то типа "Проблемы разработки от EvilOkta"? А то название темы уже не актуально )

PPS. предвидя вопросы, сразу отвечу - нет, не майнкрафт )) даже близко ))

Используй Bounds - http://docs.unity3d.com/ScriptReference/Bounds.html
Проверяй есть ли пересечение через "объект.bounds.Contains" и дальше двигай как тебе надо. :) Можно даже без коллайдеров использовать. Проблема будет только с тем, что надо учитывать повороты объектов.

Я этот момент учел при помощи такого говнокода:
Код:

                _Point[0] = new Vector3(_colliderTr.bounds.center.x + _colliderTr.bounds.size.x/2, _transform.position.y, _colliderTr.bounds.center.z + _colliderTr.bounds.size.z/2);
                _Point[1] = new Vector3(_colliderTr.bounds.center.x - _colliderTr.bounds.size.x/2, _transform.position.y, _colliderTr.bounds.center.z + _colliderTr.bounds.size.z/2);
                _Point[2] = new Vector3(_colliderTr.bounds.center.x - _colliderTr.bounds.size.x/2, _transform.position.y, _colliderTr.bounds.center.z - _colliderTr.bounds.size.z/2);
                _Point[3] = new Vector3(_colliderTr.bounds.center.x + _colliderTr.bounds.size.x/2, _transform.position.y, _colliderTr.bounds.center.z - _colliderTr.bounds.size.z/2);
                       
                if( _collider.bounds.Contains(_Point[0])&&_collider.bounds.Contains(_Point[1])&&_collider.bounds.Contains(_Point[2])&&_collider.bounds.Contains(_Point[3]) ){
                        //есть пересечение
                }else{
                        //нет пересечения
                }

Провека пересечения MeshRender и BoxCollider.
_collider был BoxCollider объекта на котором висит скрипт.
_colliderTr был MeshRenderer проверяемого объекта.


Часовой пояс GMT +4, время: 16:40.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot