首页 > 解决方案 > unity)second invokerepeating 不想触发

问题描述

我有两个需要触发的 invokeRepeating 。我有两个布尔值来决定需要触发哪个 invokeRepeating 。当两个 bool 中的至少一个设置为 true 时,需要触发第一个 invokeRepeating,而当两个 bool 设置为 false 时,总是需要触发第二个 invokeRepeating。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class movingCharacter : MonoBehaviour {
public Rigidbody rb;
public float movingSpeed = 200;
public int maxSpeed = 3000;
public bool forwardBackMoving, sideMoving;
// Start is called before the first frame update
void Start()
{
    rb = GetComponent<Rigidbody>();
    forwardBackMoving = true;
    sideMoving = true;
    if ((forwardBackMoving == true || sideMoving == true)&&movingSpeed<maxSpeed)
    {
        InvokeRepeating("increaseSpeed", 5.0f, 5.0f);
    }
    else if(forwardBackMoving==false&&sideMoving==false)
    {
        CancelInvoke();
        InvokeRepeating("decreaseSpeed", 1.0f, 5.0f);
    }
}
public void keyUpEvent()
{
    if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S))
    {
        forwardBackMoving = false;
    }else if (Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D))
    {
        sideMoving = false;
    }
}

public void increaseSpeed() {
    movingSpeed = movingSpeed * 1.1f;
    Debug.Log("Increased");
}
public void decreaseSpeed()
{
    movingSpeed = movingSpeed * 0.9f;
    Debug.Log("Decreased");
}
// Update is called once per 

public void FixedUpdate()
{
    if (Input.GetKeyDown(KeyCode.W))
    {
        rb.AddForce(transform.forward * movingSpeed);
        forwardBackMoving = true;
    }
    if (Input.GetKeyDown(KeyCode.A))
    {
        rb.AddForce(transform.right * -movingSpeed);
        sideMoving = true;
    }
    if (Input.GetKeyDown(KeyCode.S))
    {
        rb.AddForce(transform.forward * -movingSpeed);
         forwardBackMoving= true;
    }
    if (Input.GetKeyDown(KeyCode.D))
    {
        rb.AddForce(transform.right * movingSpeed);
        sideMoving = true;
    }
    keyUpEvent();
    Debug.Log(Time.deltaTime);
   /* if ((forwardBackMoving == true || sideMoving == true) && movingSpeed < maxSpeed)
    {
        //while(Time.fixedDeltaTime)
    }
    else if (forwardBackMoving == false && sideMoving == false)
    {

        //InvokeRepeating("decreaseSpeed", 1.0f, 5.0f);
    }*/
}

 }

在此代码中,即使布尔值更改为 false,第二个 invokeRepeating 也永远不会触发。

标签: c#unity3d

解决方案


好吧,你有一个if-else if块,所以一次只能执行两个块中的一个。

如前所述,这个组件Start只调用一次,那么应该如何到达另一个块呢?

您想要做的是CancelInvokeInvokeRepeating 每次其中一个值发生变化时。我实际上会为此使用属性

public class movingCharacter : MonoBehaviour 
{
    [Header("References")]
    public Rigidbody rb;

    [Header("Settings")]
    public float movingSpeed = 200;
    public int maxSpeed = 3000;

    [Header("Debug")]
    [SerializeField] private bool _forwardBackMoving;
    [SerializeField] private bool _sideMoving;

    // Now make properties. When setting a new value run your checks
    public bool forwardBackMoving
    {
        get => _forwardBackMoving;
        set
        {
            // do nothing if the value hasn't changed
            if(_forwardBackMoving == value) return;

            // otherwise apply the new value and run the check
            _forwardBackMoving = value; 
            CheckMovement();
        }
    }

    // The same fot he other flag
    public bool sideMoving
    {
        get => _sideMoving;
        set
        {
            // do nothing if the value hasn't changed
            if(_sideMoving == value) return;

            // otherwise apply the new value and run the check
            _sideMoving = value;
            CheckMovement();
        }
    }

    private void CheckMovement()
    {
        if ((forwardBackMoving || sideMoving) && movingSpeed < maxSpeed)
        {
            CancelInvoke();
            InvokeRepeating(nameof(increaseSpeed), 5.0f, 5.0f);
        }
        else if(!forwardBackMoving && !sideMoving)
        {
            CancelInvoke();
            InvokeRepeating(nameof(decreaseSpeed), 1.0f, 5.0f);
        }
    }

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        forwardBackMoving = true;
        sideMoving = true;
    }

    private void keyUpEvent()
    {
        if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S))
        {
            forwardBackMoving = false;
        }
        else if (Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D))
        {
            sideMoving = false;
        }
    }

    private void increaseSpeed() 
    {
        movingSpeed = movingSpeed * 1.1f;
        Debug.Log("Increased");
    }

    private void decreaseSpeed()
    {
        movingSpeed = movingSpeed * 0.9f;
        Debug.Log("Decreased");
    }

    // You should get Input only in the Update method!
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            rb.AddForce(transform.forward * movingSpeed);
            forwardBackMoving = true;
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            rb.AddForce(transform.right * -movingSpeed);
            sideMoving = true;
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            rb.AddForce(transform.forward * -movingSpeed);
             forwardBackMoving= true;
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            rb.AddForce(transform.right * movingSpeed);
            sideMoving = true;
        }
        keyUpEvent();
        // Avoid Debug.Log on a per frame basis! It is quite expensive!
        Debug.Log(Time.deltaTime);
    }
}

推荐阅读