#c# #unity3d #boolean
#c# #unity3d #логическое
Вопрос:
У меня есть 2 скрипта, playerMachanics и enemyBehavior. У моего вражеского поведения есть логическое значение, которое, когда логическое значение равно true, удаляется от игрока. Вместо этого я получаю сообщение об ошибке: «ссылка на объект не установлена для экземпляра объекта».
Я уверен, что это означает, что скрипт не может найти компонент, но я не могу понять, что не так.
public class enemyBehavior : MonoBehaviour
{
public bool evade = false;
public GameObject Player;
public float movementSpeed = 4;
// Start is called before the first frame update
void Start()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update()
{
transform.LookAt(Player.transform);
transform.position = transform.forward * movementSpeed * Time.deltaTime;
if (evade == true)
{
movementSpeed = -4;
}
}
}
public class playerMechanics : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnCollisionEnter(Collision collision)
{
enemyBehavior evade = gameObject.GetComponent<enemyBehavior>();
if (collision.gameObject.name == "coin")
{
Destroy(collision.gameObject);
enemyBehavior script = GetComponent<enemyBehavior>();
script.evade = script.evade == true;
}
}
}
Я ожидал, что скорость движения будет равна -4, но теперь я просто получаю сообщение об ошибке.
Комментарии:
1.
script.evade = script.evade == true;
ничего не делает. Вы пытаетесь изменить значение на противоположное? Если да, изменитеtrue
наfalse
или просто сделайте:script.evade = !script.evade;
2. Моя основная проблема заключается в ошибке: «ссылка на объект не установлена для экземпляра объекта». Я даже ничего не могу сделать, пока это есть…
3. @RufusL это script.evade = сценарий.уклонение == false;
4. Итак, это означает
script
естьnull
. Из документации : «Возвращает компонент типа type, если к игровому объекту прикреплен один, null, если нет». . Кроме того, похоже, что эта строка не нужна:enemyBehavior evade = gameObject.GetComponent<enemyBehavior>();
5. @RufusL да, эта строка не была нужна. Я удалил его, но я все еще не понимаю, что мне нужно сделать, чтобы исправить уклонение. Я изменил его на: script.evade = !script.evade; но я все еще получаю ошибку
Ответ №1:
Вызов GetComponent сам по себе будет искать компонент, прикрепленный к родительскому объекту скрипта, который, я думаю, в данном случае является игроком. Таким образом, он всегда будет возвращать значение null.
Добавить
Public GameObject enemy;
в класс playerMechanics, а затем перейдите в конструктор и перетащите игровой объект, к которому прикреплен скрипт enemyBehavior. Существует несколько проблем с методом OnCollisionEnter. Что-то вроде этого
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "coin")
{
Destroy(collision.gameObject);
enemyBehavior script = enemy.GetComponent<enemyBehavior>();
script.evade = false;
}
}
должно помочь вам двигаться в правильном направлении.
Ответ №2:
Является ли поведение противника объектом player? Смотрите здесь
enemyBehavior evade = gameObject.GetComponent<enemyBehavior>();
и здесь
enemyBehavior script = GetComponent<enemyBehavior>();
Вам нужно реализовать способ отслеживания того, какой вражеский экземпляр вы захватываете. Сделайте это, создав переменную для хранения вражеского скрипта или используя синглтон для вражеского скрипта (если есть один враг).
Переменная:
public enemyBehaviour enemy;
Синглтон:
(Поведение врага)
public static enemyBehaviour instance = null;
private static readonly object padLock = new object();
void Awake(){
lock(padLock){
if(instance == null)
instance = this;
}
}
(проигрыватель)
enemyBehaviour.instance.evade = false;
Посмотрите синглтоны, если хотите узнать больше.
Ответ №3:
Если я прав, я думаю, что ваша игровая механика работает следующим образом: цель игрока — собирать монеты. Когда они соберут его, враг рядом с ним подойдет и ускользнет от игрока.
Если это так, вам следует использовать это:
public class enemyBehavior : MonoBehaviour
{
public bool evade = false;
public GameObject Player;
public float movementSpeed = 4;
void Start()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
void Update()
{
transform.LookAt(Player.transform);
transform.position = transform.forward * movementSpeed * Time.deltaTime;
if (evade)
{
movementSpeed = -4;
}
}
}
public class playerMechanics : MonoBehaviour
{
[SerializeField] enemyBehvaior enemy;
void OnCollisionEnter(Collision collision)
{
if (collision.collider.name == "coin")
{
Destroy(collision.collider.gameObject);
enemy.evade = true;
}
}
}
В вашем коде вы написали ‘collision.GameObject.’ Это относится к объекту, к которому прикреплен скрипт. Если вы хотите ссылаться на объект, к которому мы обращаемся, используйте ‘collision.collider’.
‘[SerializeField]’ — это атрибут unity, который используется для отображения поля в инспекторе, не делая его общедоступным.
На всякий случай, если вы используете 2D, убедитесь, что метод подписан ‘OnCollisionEnter2D (столкновение Collision2D)’.
Надеюсь, я ответил на ваш вопрос. 🙂