Минимальный код из BoardScript.cs

public class BoardScript : MonoBehaviour {
    private float angle;
    private static BoardScript instance;

    void Awake() {
        if (instance == null) {
            instance = this;
        }
        else if (instance != this) {
            Destroy(gameObject);
        }
     }

    Start(){
        angle = 0.5f;
    }

    Update(){
        Debug.Log("angle = " + angle); // logged angle never changes.
        Debug.Log("GetAngle() returns " + GetAngle()); // also never changes...
     }

    public SetAngle(float arg) {
        angle = arg;
        Debug.Log("angle set to " + angle);
        // Above always logs new angle as called fron Settings.cs. 
    }

    private float GetAngle() { // only use is for debugging this issue.
        Debug.Log("angle is " + angle); // Does not log newly set angle.
        return angle;
    }
}

Минимальный код Settings.cs

private GameObject theBoard;

public void SetBoardAngule(float arg) {
    theBoard.GetComponent<BoardScript>().SetAngle(arg);
    Debug.Log("Settings - SetAngle to " + arg); // Logs correct angle.
}

Функция обновления записывает «angle = 0.5» независимо от того, что установлено в методе SetAngle (). Это кажется мне очень простым. Что я делаю неправильно?

0
RigidBody 13 Апр 2019 в 02:47

2 ответа

Лучший ответ

Перво-наперво: у вас все хорошо.

Другое дело: во-первых, если вы пришли из мира Java, вам не нужно создавать функции для установщиков геттеров:

public SetAngle(float arg) {
        angle = arg;
        Debug.Log("angle set to " + angle);
        // Above always logs new angle as called fron Settings.cs. 
    }

    private float GetAngle() { // only use is for debugging this issue.
        Debug.Log("angle is " + angle); // Does not log newly set angle.
        return angle;
    }

Можно преобразовать в:

public float Angle
{
    get{return _angle;}
    set{_angle = value;}
}

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

Третий: который также относится ко второму: мы создаем синглтон, чтобы иметь только один экземпляр нашего класса, если это то, что вы хотите, есть множество способов сделать это, но вы должны установить свою переменную соответствующим образом: в настоящее время вы устанавливаете значение on (этот экземпляр), которое может отличаться от (сохраненного экземпляра), и как только это произойдет, вы теряете указатели, и вы должны вызывать его для синглтон-класса:

public float Angle
{
    get{return BoardScript.instance._angle;}
    set{BoardScript.instance._angle = value;}
}

Вместо того:

public float Angle
{
    get{return this._angle;}
    set{this._angle = value;}
}

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

void Awake() {
    if (instance == null) {
        instance = this;
    }
    else if (instance != this) {
        Destroy(gameObject);
    }
 }
1
deadManN 13 Апр 2019 в 13:21

Как отмечают комментаторы, изменение

private static BoardScript instance;

К

public BoardScript instance;
0
RigidBody 13 Апр 2019 в 12:55