如何从另一个脚本C#更改布尔值

时间:2019-04-23 20:16:28

标签: c# unity3d boolean

我有2个脚本,playerMachanics和敌人行为。我的敌人行为具有一个布尔值,当布尔值为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;
        }
    }
}

我希望MovementSpeed可以达到-4,但现在我只是遇到一个错误。

3 个答案:

答案 0 :(得分:0)

单独调用getComponent会查找附加到脚本父对象的组件,在这种情况下,我认为这是播放器。因此它将始终返回null。

添加

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

应该使您朝正确的方向前进。

答案 1 :(得分:0)

敌人是玩家的行为对象吗?看到这里

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

在这里

enemyBehavior script = GetComponent<enemyBehavior>();

您需要实现一种方法来跟踪您要抓住的敌人实例。为此,可以通过创建一个变量来保存敌方脚本,或者在敌方脚本上使用单例(如果有一个敌人)。 变量:

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;

如果想了解更多信息,请查找单例。

答案 2 :(得分:0)

如果我是对的,我认为您的游戏机制是这样的:玩家的目标是收集硬币。当他们收集一个时,附近的敌人将来躲避玩家。

如果是这种情况,则应使用此方法:

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]'是一个统一的attribute,用于使字段在检查器中显示而不公开。

请注意,如果您使用的是2D,请确保该方法已签名“ OnCollisionEnter2D(Collision2D碰撞)”。

我希望我回答了你的问题。 :)