Unity: ссылка Null Reference on Upgrade нажимает [дублировать]

Для подобной задачи я действительно наслаждался этим gist , который предоставляет полипол для scrollIntoViewIfNeeded () .

Все необходимые Кунг-фу должны были ответить находится внутри этого блока:

var parent = this.parentNode,
    parentComputedStyle = window.getComputedStyle(parent, null),
    parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
    parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
    overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
    overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
    overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
    overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
    alignWithTop = overTop && !overBottom;

this относится к элементу, который вы хотите знать, если он есть overTop или overBottom - просто должен получить дрейф ...

5
задан Alex 23 May 2016 в 19:41
поделиться

2 ответа

public class Rule : MonoBehaviour{}
Rule rule2 = new Rule();

Вы не можете использовать ключевое слово new для создания нового экземпляра, если вы наследуете его из MonoBehaviour.

Вы должны получить исключение, говорит :

Вы пытаетесь создать MonoBehaviour, используя ключевое слово 'new'. Это запрещено. MonoBehaviours можно добавлять только с помощью AddComponent (). Кроме того, ваш скрипт может наследовать от ScriptableObject или вообще никакого базового класса

. Ваш код работал бы, если у вас public class Rule {}, но у вас есть public class Rule : MonoBehaviour {}.

Создание нового экземпляра класса, полученного из MonoBehaviour:

Пример класса:

public class Rule : MonoBehaviour
{
    public Rule(int i)
    {

    }
}

Если вы наследуете MonoBehaviour, вы должны либо используйте GameObject.AddComponent или Instantiate для создания нового экземпляра.

Rule rule2 = null;
void Start()
{
  rule2 = gameObject.AddComponent<Rule>();
}

ИЛИ

public Rule rulePrefab;
Rule rule2;
void Start()
{
    rule2 = Instantiate(rulePrefab) as Rule;
}

Если скрипт Rule уже существуют и прикреплены к GameObject, вам не нужно создавать / добавлять / создавать новые экземпляры этого сценария. Просто используйте функцию GetComponent, чтобы получить экземпляр скрипта из GameObject, к которому он присоединен.

Rule rule2;
void Start()
{
    rule2 = GameObject.Find("NameObjectScriptIsAttachedTo").GetComponent<Rule>();
}

Вы заметите, что вы не можете использовать параметр в конструкторе, когда вы выводите свой скрипт из MonoBehaviour .



Создание нового экземпляра класса, который НЕ выводится из MonoBehaviour:

Пример класса: (Обратите внимание, что он не является результатом " MonoBehaviour "

public class Rule
{
    public Rule(int i)
    {

    }
}

Если вы не наследуете от MonoBehaviour, вы должны использовать ключевое слово new для создания нового экземпляра. Теперь вы можете использовать параметр в конструкторе, если вы хотите.

Rule rule2 = null;

void Start()
{
    rule2 = new Rule(3);
}

EDIT:

В последней версии Unity создается новый экземпляр скрипта, который наследует от MonoBehaviour с помощью new может не дать вам ошибку и не может быть null слишком , но все функции обратного вызова не будут выполняться . К ним относятся функции Awake, Start, Update и другие. , вы все равно должны сделать это правильно, как указано в начале этого ответа.

15
ответ дан Programmer 26 August 2018 в 01:10
поделиться

Просто следите за тем, как я это сделал и почему:

  1. Я больше не наследую класс Rule из MonoBehaviour, чтобы избежать отслеживания создания и удаления объектов gameObjects, которая оказалась болью.
  2. Поскольку метод Invoke не существует в родовых классах, я заменил его отражением, как описано здесь здесь
2
ответ дан Community 26 August 2018 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: