无法进行冷却,无法解决问题,并且无法正常工作

问题描述 投票:-2回答:1

所以我正在制作一个VR游戏,我想做的是,只要按下操纵杆上的触发器,“剑”就会被激活并可以保持激活状态1秒钟,此后的冷却时间为1秒钟。也无法激活它,然后重置。我以为这很简单,但我无法一辈子让它正常工作。

这里是代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;

public class Sword : MonoBehaviour
{
    public SteamVR_Action_Boolean ActivateSword;
    public SteamVR_Input_Sources handType;
    private bool IsSwordActivated = false;
    private bool canSwordGetActivated = true;
    private bool cooldownStart = false;
    public Material activatedSword;
    public Material defaultSword;
    public float timeStamp;
    public float timer = 0;
    public float cooldown = 2;

    void Start()
    {
        ActivateSword.AddOnStateDownListener(TriggerDown, handType);
        ActivateSword.AddOnStateUpListener(TriggerUp, handType);
        timeStamp = Time.time;
    }

    public void TriggerUp(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
    {

            Debug.Log("Trigger is up");
            IsSwordActivated = false;
            this.GetComponent<MeshRenderer>().material = defaultSword;

    }
    public void TriggerDown(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
    {
        if (canSwordGetActivated == true)
        {
            Debug.Log("Trigger is down");
            IsSwordActivated = true;
            cooldownStart = true;
            this.GetComponent<MeshRenderer>().material = activatedSword;
        }


    }



    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            if (IsSwordActivated == true)
            {
                Destroy(collision.gameObject);
            }
        }

    }
    private void Update()
    {
        //if (timeStamp <= Time.time)
        //{
        //    if (IsSwordActivated == true)
        //    {
        //        timeStamp += 2;
        //        canSwordGetActivated = false;
        //        Debug.Log("test");
        //    }
        //}
        if (cooldownStart == true)
        {
            timer += Time.deltaTime;
            cooldown -= Time.deltaTime;
            if (timer >= 1f)
            {
                this.GetComponent<MeshRenderer>().material = defaultSword;
                IsSwordActivated = false;
                timer = 0;
            }
            if (timer == 0)
            {
                canSwordGetActivated = false;
            }
            if (cooldown <= 1f)
            {
                canSwordGetActivated = false;
            }
            if (cooldown <= 0)
            {
                cooldown = 2f;
                canSwordGetActivated = true;
                cooldownStart = false;
            }

        }

    }
}


c# unity3d virtual-reality
1个回答
1
投票

您不应使用Update,而应使用Coroutine。特别是“冷却”应独立于“计时器”运行。

// Not needed
//private bool cooldownStart = false;
//public float timer = 0;

// reference this already via the Inspector if possible
[SerializeField] private MeshRenderer _meshRenderer;

[SerializeField] private float cooldownTime = 1;
[SerializeField] private float maxEnabledTime = 1;

// Otherwise get it only ONCE on runtime
private void Awake()
{
    if(!_meshRenderer) _meshRenderer = GetComponent<MeshRenderer>();
}

public void TriggerUp(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
{
    Debug.Log("Trigger is up");

    // stop the timeout
    StopAllCoroutines();

    // disable sword and start cooldown
    StartCoroutine(SwordCooldown());
}

public void TriggerDown(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
{
    if(IsSwordActivated) return;
    if (!canSwordGetActivated) return;

    Debug.Log("Trigger is down");

    // start timeout
    StartCoroutine(SwordEnabledTimer());
}

///<summary>
/// Disables sword and Runs cooldown before sword can be enabled again
///<summary>
private IEnumerator SwordCooldown()
{
    canSwordGetActivated = false;

    IsSwordActivated = false;
    _meshRenderer.material = defaultSword;

    yield return new WaitForSeconds(cooldownTime);

    canSwordGetActivated = true;
}

///<summary>
/// Disables the sword and jumps to cooldown after it was enabled for too long
///<summary>
private IEnumerator SwordEnabledTimer()
{
    canSwordGetActivated = false;

    yield return new WaitForSeconds(maxEnabledTime);

    StartCoroutine(SwordCooldown());
}

请参见WaitForSeconds

© www.soinside.com 2019 - 2024. All rights reserved.