Не знаю, как получить доступ к переменной скрипта из другого скрипта (другой игровой объект) - PullRequest
0 голосов
/ 08 апреля 2020

Итак, я сейчас работаю над небольшим быстрым набором. У меня есть скрипт, прикрепленный к циферблату, который ждет измерения скорости, затем преобразует его в нужный угол и отображает его. Теперь я хочу получить измерение скорости с самолета и передать его на циферблат. Но я не могу понять это. Вот код набора:

static float minAngle = 70.64f;
    static float maxAngle = -269.69f;
    static RotateSpeedDial thisSpeedo;

    void Start () {
        thisSpeedo = this;
    }

    public static void ShowSpeed(float speed, float min, float max) {
        float ang = Mathf.Lerp(minAngle, maxAngle, Mathf.InverseLerp(min, max, speed));
        thisSpeedo.transform.eulerAngles = new Vector3(0,0,ang);
    }

А вот часть кода самолета, которая дает скорость:

public Rigidbody rb;
public GameObject ScriptHolder = GameObject.Find("SpeedDial");
        public RotateSpeedDial = ScriptHolder.GetComponent<RotateSpeedDial>();

public void Update()
        {
            rb = this.GetComponent<Rigidbody>();
            RotateSpeedDial.ShowSpeed(rb.velocity.magnitude,0,100);
        }

1 Ответ

0 голосов
/ 08 апреля 2020

RotateSpeedDial.ShowSpeed равно static, поэтому вам вообще не нужно получать ссылку на него через GetComponent.

Просто используйте его как

// Reference this via the Inspector and you don't need GetComponent at all
public Rigidbody rb;

// As a fallback get it ONCE on runtime
private void Awake()
{
    if(!rb) rb = GetComponent<Rigidbody>();
}

public void Update()
{
    RotateSpeedDial.ShowSpeed(rb.velocity.magnitude, 0, 100);
}

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

И Find, и GetComponent нельзя использовать в определении поля в классе. Также ScriptHolder нельзя использовать для инициализации поля в классе, так как оно присваивается самой среде выполнения, а не значением c. Вам нужен какой-то метод, например, Awake или Start.

Поэтому у вас будет, например,

// Reference all these via the Inspector using drag&drop
public Rigidbody rb;
// If you drag this in via the Inspector you wouldn't need the "ScriptHolder"
// at all.
public RotateSpeedDial rotateSpeedDial;
public GameObject ScriptHolder;

// Or as a fallback get them all on runtime ONCE like

// I use a little rule of thub: Get and initialize your own stuff at Awake
private void Awake()
{
    if(!rb) rb = GetComponent<Rigidbody>();
}

// Get other objects stuff on Start 
// This way you can almost always be sure that the other stuff 
// is already initialized when you access it
private void Start()
{
    if(!rotateSpeedDial)
    {
        if(! ScriptHolder) ScriptHolder = GameObject.Find("SpeedDial");

        rotateSpeedDial = ScriptHolder.GetComponent<RotateSpeedDial>();
    }

    // Or simply use
    if(!rotateSpeedDial) rotateSpeedDial = FindObjectOfType<RotateSpeedDial>();
}

public void Update()
{
    rotateSpeedDial.ShowSpeed(rb.velocity.magnitude, 0, 100);
}

, и тогда вы вообще не будете использовать static в RotateSpeedDial:

float minAngle = 70.64f;
float maxAngle = -269.69f;

public void ShowSpeed(float speed, float min, float max) 
{
    var ang = Mathf.Lerp(minAngle, maxAngle, Mathf.InverseLerp(min, max, speed));
    transform.eulerAngles = Vector3.forward * ang;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...