У меня есть объект с полем скорость (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
Замечание: если нейдется объект с таким именем или их будет много - то это может привести к плачевнм последствием. Также нужно помнить, что операция 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
Комментариев нет:
Отправить комментарий