在统一C#中设置时间或时间后触发动作

Set time or trigger action after time in unity C#

请问如何在一段时间后触发动作或功能。在我的例子中,我有一个函数 class 计时器,在下面显示为 FuntiontTimer.cs

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

public class FuncTime
{
private Action action;
private float timer;
private bool isDestroyed;


public FuncTime(Action action, float timer)
{
    this.action = action;
    this.timer = timer;
    isDestroyed = false;
}

public void Update()
{
    if (!isDestroyed) { 
        timer -= Time.deltaTime;
        if (timer < 0)
        {
            action();
            DestroySelf();
        }
    }
}

private void DestroySelf()
{
    isDestroyed = true;
}
}

当我使用下面的 testing.cs 和 MonoBehaviour

进行测试时,代码工作正常
public class Testing : MonoBehaviour
{
private FuncTime funcTimer;

private void Start()
{
    funcTimer = new FuncTime(Action, 3f);
}

private void Update()
{
    funcTimer.Update();
}

private void Action()
{
    Debug.Log("Testing!");
}
}

但是,当我输入下面的代码时,它不起作用。 我会在从我开始的时间起 30f 后激活 cameraShake。

public class CameraShaker : MonoBehaviour
{
public float power = 0.7f;
public float duration = 1.0f;
public Transform camera;
public float slowDownNo;
public bool shaking;

Vector3 startPosition;
float initialDuration;

void Start()
{
    camera = Camera.main.transform;
    startPosition = camera.localPosition;
    initialDuration = duration;
}

// Update is called once per frame
void Update()
{
    if (shaking)
    {
        if(duration > 0)
        {
            camera.localPosition = startPosition + Random.insideUnitSphere * power;
            duration -= Time.deltaTime * slowDownNo;
        } else
        {
            shaking = false; //time can be placed here
            duration = initialDuration;
            camera.localPosition = startPosition;
        }
    }
}
}

一种解决方案是使用协程安排将来要完成的工作。

像这样:

IEnumerator myWaitCoroutine()
{
    yield return new WaitForSeconds(1f);// Wait for one second

    // All your Post-Delay Logic goes here:
    // Run functions
    // Set your Values
    // Or whatever else
}
StartCoroutine(myWaitCoroutine());

花括号 {} 中的所有内容都只是被声明,实际上并没有 运行 直到你调用 StartCoroutine(myWaitCoroutine);

因此,在您的情况下,您可以开始摇动,然后创建一个 stopShakeAfterDelayCoroutine()。类似于:

StartShake();

IEnumerator stopShakeCoroutine()
{
    yield return new WaitForSeconds(shakeDuration);// Wait a bit
    StopShake();
}
StartCoroutine(stopShakeCoroutine());

当然,如果需要,您仍然可以尝试在 Update() 中提前停止摇动。