Страницы

Поиск по вопросам

четверг, 8 ноября 2018 г.

Как передать значение переменной из одного скрипта в другой?

У меня есть объект с полем скорость (speed). Я хочу, чтобы другие объекты могли использовать её значение, то есть, по факту, иметь доступ к переменной скрипта (по разным причинам это может понадобиться).
Как я могу получить доступ к переменной объекта, чтоб все изменения, которые в нем произошли, можно было получить из другого объекта?

Вопрос переведен с https://stackoverflow.com/q/13891892/6104996


Ответ

Есть несколько способов сделать это.
Если вы хотите получить значение speed из компонента, который прикреплен к объекту с именем, предположим MyObject
public class SpeedController : MonoBehaviour public float speed; // Для ограничения только на чтение и запретить запись - можно использовать "Свойство"
то в другом компоненте вы можете сделать следующее:
// Найти объект по имени GameObject go = GameObject.Find("MyObject"); // взять его компонент где лежит скорость SpeedController speedController = go.GetComponent(); // взять переменную скорости float courrentSpeed = speedController.speed;
Замечание: если нейдется объект с таким именем или их будет много - то это может привести к плачевнм последствием. Также нужно помнить, что операция Find довольно медленная. И, например, в Update лучшее её не использовать. Лучше найти объект при старте и только потом уже использовать.

Самый при самый неудобный способ (да и, в принципе, неправильный, но действующий) - это объявить переменную speed типа SpeedController в каждом классе. Перетащить в это поле объект в эдиторе. Тогда сможете наблюдать за состоянием переменной в любой момент. Но способ ужасный и не рекомендуемый

Еще способ создать синглтон, который будет содержать вашу переменную speed
public class MyGlobalSpeedController { private static MyGlobalSpeedController instance = null; public static MyGlobalSpeedController SharedInstance { get { if (instance == null) { instance = new MyGlobalSpeedController (); } return instance; } } public float speed; }
Тогда все классы смогут иметь доступ через него:
float currentSpeed = MyGlobalSpeedController.SharedInstance.speed

Еще можно объявить переменную статической и тогда она не будет привязана к объекту, а будет принадлежать классу
public class SpeedController : MonoBehaviour public static float speed;
доступ к ней прост:
var speedVal = SpeedController.speed; Debug.Log(speedVal);
Раз вы пытаетесь сделать так, чтоб она была доступна всем остальным объектам, то, предполагаю, что объект с такой переменной у вас на сцене - один. Иначе этот способ становится бесполезным

Также можно использовать систему сообщений в Unity
Например Component.SendMessage. Он имеет 4 перегруженных метода
public function SendMessage(methodName: string, value: object = null, options: SendMessageOptions = SendMessageOptions.RequireReceiver): void; public function SendMessage(methodName: string, value: object = null, options: SendMessageOptions = SendMessageOptions.RequireReceiver): void; public function SendMessage(methodName: string, value: object = null, options: SendMessageOptions = SendMessageOptions.RequireReceiver): void; public function SendMessage(methodName: string, options: SendMessageOptions): void;
он вызывает метод с именем methodName в каждом MonoBehaviour на этом объекте, например:
go.SendMessage("GetFallingSpeed");
вызовет метод GetFallingSpeed на объекте go. А данный метод (GetFallingSpeed) возможно как раз и будет управлять параметром speed
Не забудьте, что вам нужно получить доступ к go каким-либо образом, т.е. через Find или другим удобным способом.

Ответ переведен с дополнением с https://stackoverflow.com/a/13892844/6104996

Комментариев нет:

Отправить комментарий