Приветствую начал изучать по книги unity и при создании первого прототипа столкнулся с проблемой, которую не знаю как решить, если кто объяснит буду очень благодарен. Сам код выглядит так
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Basket : MonoBehaviour { [Header("Set Dynamically")] public Text scoreGT; void Start() { GameObject scoreGO = GameObject.Find("ScoreCounter"); scoreGT = scoreGO.GetComponent<Text>(); scoreGT.text = "0"; } void Update() { Vector3 mousePos2D = Input.mousePosition; mousePos2D.z = -Camera.main.transform.position.z; Vector3 mousePos3D = Camera.main.ScreenToWorldPoint(mousePos2D); Vector3 pos = this.transform.position; pos.x = mousePos3D.x; this.transform.position = pos; } void OnCollisionEnter(Collision coll) { GameObject collidedWith = coll.gameObject; if (collidedWith.tag == "Apple") { Destroy(collidedWith); int score = int.Parse(scoreGT.text); score += 100; scoreGT.text = score.ToString(); } } }
ошибка которую выдает так
NullReferenceException: Object reference not set to an instance of an object
Basket.Start () (at Assets/Basket.cs:17)
Как я понимаю, я не могу записать в scoreGt.text так как она ни на что не ссылается, хотя вроде как выше все написано правильно и должна уходить в ScoreCounter который у меня есть в иерархии. И я не понимаю в чем ошибка, за помощь спасибо.
misha51
> который у меня есть в иерархии
а где в иерархии?
обычно, чтобы find-ами не обмазываться, делают без них:
[Header("Set Dynamically")] public Text scoreGT; void Start( ) { if ( scoreGT != null) { scoreGT = scoreGO.GetComponent<Text>( ); scoreGT.text = "0"; } }
а scoreGT соединяют в редакторе. Потери в runtime равны нулю.
skalogryz
У меня получается есть 2 текста, один это счет, а второй это лучший результат. нужно записать именно в scorecounter, а сам проект пока выглядит так.
1) По проблеме
На скриншоте TextMeshPro, в коде попытка GetComponent<Text>()
Т.е. он не может его взять и в итоге scoreGT = null
собcтвенно нужно тип scoreGT менять под TextMeshPro
2) По предыдущему совету про работу в инспекторе
В инспекторе притянуть нужные тексты к нужным полям лучше чем искать объекты, хоть один текст, хоть 100
3) Совет по отладке
Есть строчка с ошибкой (что-то равно null), собственно можно перед этой строчкой с помощью Debug.Log проверить все подозрительные объекты и понять кто из них null
4) Общие советы
scoreGT я бы заменил на scoreGTText, scoreGT - это были бы очки внутри игровой логики
Объекты по имени лучше не искать, лучше по типу
Если поле используется только внутри класса то его лучше сделать private
попробуй так:
public TextMeshPro scoreGT; void Start() { GameObject scoreGO = GameObject.Find( "ScoreCounter"); scoreGT = scoreGO.GetComponent<TextMeshPro>( ); scoreGT.text = "0"; }
Miroils
Да через обычный текст получилось, через mesh посмотрел уроки, как доделаю попробую изменить и сделать через него. За советы спасибо, только вот 2 не совсем понял, это что и для чего.
skalogryz
> GameObject scoreGO = GameObject.Find("ScoreCounter");
Я хрен его знает, сколько раз еще в bestpractices нужно указать, что искать объекты через Find по имени по имени одно из самых спорных решений, чтобы люди наконец-то перестали это делать.
Плохая практика это однозначно по скорости по фигу оно в start