Как изменить логическое значение из другого скрипта C # - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть 2 скрипта, плеер, механика и вражеское поведение. У моего врага Behavior есть логическое значение, которое, когда логическое значение истинно, удаляется от игрока. Вместо этого я получаю сообщение об ошибке: «ссылка на объект не установлена ​​на экземпляр объекта».

Я уверен, что это означает, что скрипт не может найти компонент, но я не могу понять, что не так.

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;
        }
    }
}

Я ожидал, что motionSpeed ​​достигнет -4, но сейчас я просто получаю сообщение об ошибке.

Ответы [ 3 ]

0 голосов
/ 24 апреля 2019

Поведение врага на объекте игрока? Смотри здесь

enemyBehavior evade = gameObject.GetComponent<enemyBehavior>();

и здесь

enemyBehavior script = GetComponent<enemyBehavior>();

Вам необходимо реализовать способ отслеживания того, какой вражеский экземпляр вы захватываете. Сделайте это, сделав переменную для удержания вражеского сценария, или используя синглтон для вражеского сценария (если есть один враг). Variable:

public enemyBehaviour enemy;

Singleton: (EnemyBehaviour)

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;

Ищите синглтоны, если хотите узнать больше.

0 голосов
/ 24 апреля 2019

Если я прав, я думаю, что ваша игровая механика работает так: цель игрока - собирать монеты. Когда они соберут один, враг рядом с ним придет и уклонится от игрока.

Если это так, вы должны использовать это:

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]' - это атрибут единства , который используется для отображения поля в инспекторе без его публикации.

Просто наперед, если вы используете 2D, убедитесь, что метод подписан 'OnCollisionEnter2D (Collision2D collision)'.

Надеюсь, я ответил на ваш вопрос. :)

0 голосов
/ 23 апреля 2019

Вызов getComponent сам по себе будет искать компонент, прикрепленный к родительскому объекту скрипта, который, я думаю, является игроком в этом случае.Так что он всегда будет возвращать ноль.

Добавьте

Public GameObject enemy;

в класс playerMechanics, а затем перейдите в конструктор и перетащите игровой объект, к которому прикреплен скрипт врага поведения.Есть несколько проблем с методом onCollisionEnter.Нечто подобное

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.name == "coin")
    {
        Destroy(collision.gameObject);
        enemyBehavior script = enemy.GetComponent<enemyBehavior>();
        script.evade = false;
    }
}

должно заставить вас двигаться в правильном направлении.

...