Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > Unity > Уроки

Ответ
 
Опции темы
Старый 27.04.2012, 10:04   #1
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,505
Написано 2,960 полезных сообщений
(для 5,247 пользователей)
Как скрипты общаются

Мне часто задают вопрос о том, как обратиться из какого-либо скрипта к переменной другого скрипта, или как вызвать метод (функцию) другого скрипта. В этой маленькой статейке я бы хотел описать способы, которые можно для этого использовать.

Публичные переменные и доступ к компонентам

Допустим есть у нас такой скрипт
using UnityEngine;

// скрипт, к переменной которого мы хотим получить доступ
public class ScriptWithVariable
{
   
// переменная, к которой мы хотим получить доступ
   
public int myPublicVariable;

Далее мы хотим из другого скрипта на том же объекте менять эту переменную. Есть несколько способов это сделать:
  • Назначить ссылку на скрипт ScriptWithVariable в редакторе через публичную переменную
  • Получить ссылку на скрипт ScriptWithVariable в начале работы скрипта
  • Получать скрипт перед изменением

Первый вариант подразумевает, что вы создадите публичную

using UnityEngine;

public class 
VariableChanger
{
   
// переменная, которая отобразится в редакторе Unity 
   // и на которую надо перетащить скрипт ScriptWithVariable с того же или иного объекта сцены
   
public ScriptWithVariable scriptWithVariable;

   public 
void Update()
   {
     
// изменение нужной нам переменной
     
scriptWithVariable.myPublicVariable++;
   }


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

using UnityEngine;

public class 
VariableChanger
{
   
// переменная, которая отобразится в редакторе Unity 
   // и на которую надо перетащить скрипт ScriptWithVariable с того же или иного объекта сцены
   
public ScriptWithVariable scriptWithVariable;

   
// добавляем код поиска
   
public void Awake()
   {
      
scriptWithVariable GetComponent<ScriptWithVariable>();
   }

   public 
void Update()
   {
     
// изменение нужной нам переменной
     
scriptWithVariable.myPublicVariable++;
   }


Третий вариант самый не оптимальный для использования в каждом кадре (Update вызывается каждый кадр). Но зато эффективен для разового использования т.к. нет необходимости в создании переменной-ссылки на нужный нам скрипт.

using UnityEngine;

public class 
VariableChanger
{
   public 
void Start()
   {
      
// изменение нужной нам переменной
      
GetComponent<ScriptWithVariable>().myPublicVariable 100500;
   }


Вызов методов других скриптов

Все что описано про публичные переменные относится и к вызову методов.
Имеем скрипт:

using UnityEngine;

// скрипт, метод которого мы хотим вызвать
public class ScriptWithVariable
{
   public 
int myPublicVariable;

   
// метод который надо вызвать
   
public void ChangeVariable()
   {
      
myPublicVariable++;
   }


Ну и собственно пример вызова:

using UnityEngine;

public class 
VariableChanger
{
   public 
void Start()
   {
      
// изменение нужной нам переменной путем вызова метода скрипта
      
GetComponent<ScriptWithVariable>().ChangeVariable();
   }


Сообщения

Вызвать метод скрипта объекта можно так же послав сообщение этому объекту (не скрипту). Но данный способ медленнее описанного выше.

using UnityEngine;

public class 
VariableChanger
{
   public 
void Start()
   {
      
// изменение нужной нам переменной путем вызова сообщения
      
SendMessage("ChangeVariable");
   }

Данный способ вызовет метод ChangeVariable на всех скриптах текущего объекта, в которых он объявлен с тем же именем.


Ну вот и все что хотел рассказать. Данная статья так же есть на wiki
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
Andvrok (25.01.2013), Dzirt (28.04.2012), EvilOkta (25.02.2013), Lowlet (03.05.2012), Черный крыс (30.07.2012)
Старый 30.07.2012, 20:19   #2
Черный крыс
 
Сообщений: n/a
Ответ: Как скрипты общаются

Спасибо pax! В очередной раз отлично прояснил ситуацию.

Попутный вопрос в догонку насчет функции\метода SendMessage()... А как обьекту послать помимо сообщения еще и контекст сообщения ?

В БМаксе - все просто - SendMessage:Object(message:Object, context:Object)

Конечно, можно контекст "впихнуть" в саму мессагу, но хотелось бы как в БлицМаксе =)
 
Ответить с цитированием
Старый 30.07.2012, 20:47   #3
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,505
Написано 2,960 полезных сообщений
(для 5,247 пользователей)
Ответ: Как скрипты общаются

функция SendMessage принимает вторым параметром object, т.е. что угодно. Следовательно можно написать например такой класс
public class MessageData
{
     public 
GameObject context;

и посылать сообщение например так:

SendMessage("LogContext", new MessageData{context this.gameObject}); 
принимающая функция изменилась бы так:

public void LogContext(MessageData messageData)
   {
      
Debug.Log(messageData.context);
   } 
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Черный крыс (30.07.2012)
Старый 23.01.2013, 17:51   #4
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

Всем привет!
А подскажите как быть, если переменную нужно взять из скрипта другой сцены, т.е. есть сцена со скриптом там переменная bool, мы можем ее менять на true и false, и такоеже значение она должна иметь в другой сцене. Зарание спасибо.
(Offline)
 
Ответить с цитированием
Старый 23.01.2013, 18:18   #5
seaman
Знающий
 
Регистрация: 08.01.2013
Адрес: Мурманск
Сообщений: 276
Написано 100 полезных сообщений
(для 174 пользователей)
Ответ: Как скрипты общаются

В скрипте, переменная которого нужна в другой сцене нужно в Start использовать Object.DontDestroyOnLoad . ТОгда объект на котором этот скрипт не удалится при загрузке следующего уровня и скрипт будет доступен.
(Offline)
 
Ответить с цитированием
Старый 23.01.2013, 19:23   #6
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

Большое спасибо!
А сам объект отобразится в новой сцене? Он то мне не нужен. И если не тяжело, можно ссылку на мануал с этой функцией. Я так понял ее так вот писать:

void Start() {Object.DontDestroyOnLoad;}

а потом вызывать одним из описаных методов?
(Offline)
 
Ответить с цитированием
Старый 23.01.2013, 19:54   #7
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

ссылку не нужно, уже нашел....
(Offline)
 
Ответить с цитированием
Старый 24.01.2013, 12:37   #8
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

Извените, а немогли бы краткий пример написать, а то чета не могу понять, а в справке всего один пример?
(Offline)
 
Ответить с цитированием
Старый 24.01.2013, 12:48   #9
Lestar
Бывалый
 
Аватар для Lestar
 
Регистрация: 24.05.2011
Адрес: Украина,Харьков
Сообщений: 890
Написано 359 полезных сообщений
(для 880 пользователей)
Ответ: Как скрипты общаются

Переменные, к которым вы обращаетесь в разных сценах лучше хранить на каком нибуть донт дестрой обьекте. У вас этот обьект будет просто перемещаться между сценами и к переменным всегда будет доступ.
__________________
Нам суждено построить мосты и храмы,которых никогда не существовало и не могло существовать в природе.
(Offline)
 
Ответить с цитированием
Старый 24.01.2013, 12:54   #10
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

Пробавал как-так, ScriptName это имя скрипта на объекте

void Start() {
ScriptName other;
other = gameObject.GetComponent("ScriptName") as ScriptName;
other.DontDestroyOnLoad()
}
(Offline)
 
Ответить с цитированием
Старый 24.01.2013, 13:15   #11
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,505
Написано 2,960 полезных сообщений
(для 5,247 пользователей)
Ответ: Как скрипты общаются

DontDestroyOnLoad(other
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 25.01.2013, 16:12   #12
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

Всем спасибо, разобрался, теперь тока одна проблема : когда в сцене меняю значение bool переменной, все работает как нужно, перехожу в след. сцену моя переменная с правильным значением тоже(радости нет предела), все работает как нужно, возвращаюсь в исходную сцену и (радость кончилась) значение переменной осталось исходным. Че с этими клонами объектов то делать, я так понял скрипт берет значение переменной с оригинала, а не с клона скрипта.Объекта.
(Offline)
 
Ответить с цитированием
Старый 25.01.2013, 16:41   #13
Lestar
Бывалый
 
Аватар для Lestar
 
Регистрация: 24.05.2011
Адрес: Украина,Харьков
Сообщений: 890
Написано 359 полезных сообщений
(для 880 пользователей)
Ответ: Как скрипты общаются

Сделать проверку на существование обьекта. Обьект не просто вставить в сцену, а инстансить его в старте и при этом проверять существование клонов.
__________________
Нам суждено построить мосты и храмы,которых никогда не существовало и не могло существовать в природе.
(Offline)
 
Ответить с цитированием
Старый 25.01.2013, 17:32   #14
artsiom.kuzmin.86
AnyKey`щик
 
Регистрация: 23.01.2013
Адрес: Беларусь, Борисов
Сообщений: 8
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Как скрипты общаются

У меня в сцене1 два объекта, однин со скриптом действия, в нем тогглам меняется значение бул переменной. Второй со скриптом в котором я нахожу первый объект и беру зна.чение переменной, пока все хорошо, значения меняются синхронно в переменных обоих скриптов. Второй скрипт сделал донтдистракт. Переходим во вторую сцену : изночально в ней был только один объект со скриптом который находит появившийся донтдистракт объект и берет значение переменной(значение переменной из первой сцены, после изменения, а не дефолтное) и корректно выполняет свое предназначение(поко все хорошо), но перейдя из сцены2 в 1, мы имеем уже два донтдистройт объекта и значение переменной берецца из первого, а если снова перейти в сцену 2, то там тоже появился еще один донтдистройт объект, но значение переменной осталось такоеже, как при первом переходе.
Так вот как этого избежать? Чтобы донтдистракт объект был как-бы один, а не копировался, и перемесчался из сцены в сцену?
(Offline)
 
Ответить с цитированием
Старый 25.01.2013, 17:51   #15
Lestar
Бывалый
 
Аватар для Lestar
 
Регистрация: 24.05.2011
Адрес: Украина,Харьков
Сообщений: 890
Написано 359 полезных сообщений
(для 880 пользователей)
Ответ: Как скрипты общаются

Написал же выше.
Сообщение от Lestar Посмотреть сообщение
Обьект не просто вставить в сцену, а инстансить его в старте и при этом проверять существование клонов.
public GameObject Main;
Gameobject main;

void Start()
{
 if(main==null) main = (GameObject)Instantiate(Main);
}
Создайте префаб, повесьте на него ваш скрипт, засуньте в паблик поле Main. Вызывайте инстанс обьекта в вашей первой сцене.
__________________
Нам суждено построить мосты и храмы,которых никогда не существовало и не могло существовать в природе.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 06:00.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com