在 OnTriggerStay() 中的特定操作之前延迟
Delay before a specific action in OnTriggerStay()
我正在 Unity 中制作 3d 射击游戏。我想让玩家钉上 windows 和门,这样他就有了掩护。 windows 等墙上的洞和门上已经有不活动的木板。我想让玩家在 window 附近时按住按钮以将棋盘设置为活动状态。因此,如果需要钉下三块板才能完全关闭 window,玩家必须靠近 window 并按住一个按钮,例如 10 秒才能放置一块板。第二板和第三板也一样。然而,这个过程可以被打断,window 只能钉上一两块木板。 Windows 具有检测玩家存在的隐形触发器。
这是 windows 附带的代码:
using System.Collections.Generic;
using UnityEngine;
public class ActivateBoards : MonoBehaviour
{
public float delay = 10f;
public List<GameObject> boards;
private int currentAmount = 0;
private int totalAmount;
private float elapsed = 0f;
// Start is called before the first frame update
void Start()
{
totalAmount = boards.Count;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerStay(Collider other)
{
if (other.gameObject.CompareTag("Player") && Input.GetButtonDown("Fire1") && currentAmount != totalAmount)
{
elapsed += Time.deltaTime;
if (elapsed >= delay)
{
boards[currentAmount].SetActive(true);
currentAmount++;
elapsed = 0;
}
}
}
}
我尝试使用协同程序,但这是行不通的,因为玩家可以在 yield return new WaitForSeconds()
命令的中间释放按钮。另外,我想附上一个 UI 图像,它可以起到进度条的作用,并随着时间的推移而填满。在 Unity 中我真的不太适应时间——上面的代码根本不起作用。我想 Time.deltaTime
只适用于 Update()
方法?我需要 OnTriggerStay()
的功能来检测播放器和 Update()
的功能来计算时间。我怎样才能实现它?
我在目前正在制作的一款游戏中遇到了类似的问题。我解决它的方法实际上是创建一个进度条,该进度条在正常播放期间隐藏(禁用),然后在需要时恢复。我如何实现进度条是通过使用滑块并禁用它的可交互部分。然后通过从代码中更改滑块的值,我能够实现进度条的效果。如果您想自己尝试使用它,我为其编写的代码在下面。
using UnityEngine;
using UnityEngine.UI;
public class InterationMeter_Controller : MonoBehaviour
{
GameManager GameManager;
Slider Slider;
// Start is called before the first frame update
void Start()
{
//Ref to GameManager, (Tagged "GameController")
GameManager = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameManager>();
Slider = gameObject.GetComponent<Slider>();
}
// Update is called once per frame
void Update()
{
Slider.value -= Time.deltaTime; //Counts down in rl seconds
if (Slider.value <= 0)
{
GameManager.UIManager.gameObject.SendMessage("OnInteractionMeterFinish"); //Call the UIManager to let it know the timer is done
}
}
}
基本上前提是当我想触发某种基于计时器的交互时。我调用我的 UI 管理器并通过设置滑块的值告诉它 运行 进度条 x 秒。然后我的 UI 管理器中有一个接收器方法,如果进度条完成则调用该方法。如果我需要在中途停止进度条,我可以告诉 UI 管理器隐藏停止调用 Update 方法的进度条。这有效地重置了计时器,因为我在再次在屏幕上调用它之前重置了时间。
我认为您可以通过让 OnTriggerStay() 允许按下各种交互按钮来使用它。然后,您可以调用您的 UI 管理器版本来启动此计时器,当您需要停止计时器时,只需再次调用它即可。
我想说的是你的主要问题是你使用的是 GetButtonDown
这只是正确的 每个按钮按下一个 帧。
您应该使用 GetButton
,即 true
每一帧 只要按钮保持按下状态!
private void OnTriggerStay(Collider other)
{
if (!other.gameObject.CompareTag("Player") return;
// instead of totalAmount you could directly use the boards.Length (or .Count for a List)
// I would also rather check for < instead of !=
if(Input.GetButton("Fire1") && currentAmount < boards.Length)
{
elapsed += Time.deltaTime;
if (elapsed >= delay)
{
boards[currentAmount].SetActive(true);
currentAmount++;
elapsed = 0;
}
}
else if (Input.GetButtonUp("Fire1"))
{
// Button was released
elapsed = 0;
}
}
// I would then also reset if player leaves the collider
private void OnTriggerExit (Collider other)
{
if (!other.gameObject.CompareTag("Player") return;
elapsed = 0;
}
我正在 Unity 中制作 3d 射击游戏。我想让玩家钉上 windows 和门,这样他就有了掩护。 windows 等墙上的洞和门上已经有不活动的木板。我想让玩家在 window 附近时按住按钮以将棋盘设置为活动状态。因此,如果需要钉下三块板才能完全关闭 window,玩家必须靠近 window 并按住一个按钮,例如 10 秒才能放置一块板。第二板和第三板也一样。然而,这个过程可以被打断,window 只能钉上一两块木板。 Windows 具有检测玩家存在的隐形触发器。
这是 windows 附带的代码:
using System.Collections.Generic;
using UnityEngine;
public class ActivateBoards : MonoBehaviour
{
public float delay = 10f;
public List<GameObject> boards;
private int currentAmount = 0;
private int totalAmount;
private float elapsed = 0f;
// Start is called before the first frame update
void Start()
{
totalAmount = boards.Count;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerStay(Collider other)
{
if (other.gameObject.CompareTag("Player") && Input.GetButtonDown("Fire1") && currentAmount != totalAmount)
{
elapsed += Time.deltaTime;
if (elapsed >= delay)
{
boards[currentAmount].SetActive(true);
currentAmount++;
elapsed = 0;
}
}
}
}
我尝试使用协同程序,但这是行不通的,因为玩家可以在 yield return new WaitForSeconds()
命令的中间释放按钮。另外,我想附上一个 UI 图像,它可以起到进度条的作用,并随着时间的推移而填满。在 Unity 中我真的不太适应时间——上面的代码根本不起作用。我想 Time.deltaTime
只适用于 Update()
方法?我需要 OnTriggerStay()
的功能来检测播放器和 Update()
的功能来计算时间。我怎样才能实现它?
我在目前正在制作的一款游戏中遇到了类似的问题。我解决它的方法实际上是创建一个进度条,该进度条在正常播放期间隐藏(禁用),然后在需要时恢复。我如何实现进度条是通过使用滑块并禁用它的可交互部分。然后通过从代码中更改滑块的值,我能够实现进度条的效果。如果您想自己尝试使用它,我为其编写的代码在下面。
using UnityEngine;
using UnityEngine.UI;
public class InterationMeter_Controller : MonoBehaviour
{
GameManager GameManager;
Slider Slider;
// Start is called before the first frame update
void Start()
{
//Ref to GameManager, (Tagged "GameController")
GameManager = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameManager>();
Slider = gameObject.GetComponent<Slider>();
}
// Update is called once per frame
void Update()
{
Slider.value -= Time.deltaTime; //Counts down in rl seconds
if (Slider.value <= 0)
{
GameManager.UIManager.gameObject.SendMessage("OnInteractionMeterFinish"); //Call the UIManager to let it know the timer is done
}
}
}
基本上前提是当我想触发某种基于计时器的交互时。我调用我的 UI 管理器并通过设置滑块的值告诉它 运行 进度条 x 秒。然后我的 UI 管理器中有一个接收器方法,如果进度条完成则调用该方法。如果我需要在中途停止进度条,我可以告诉 UI 管理器隐藏停止调用 Update 方法的进度条。这有效地重置了计时器,因为我在再次在屏幕上调用它之前重置了时间。
我认为您可以通过让 OnTriggerStay() 允许按下各种交互按钮来使用它。然后,您可以调用您的 UI 管理器版本来启动此计时器,当您需要停止计时器时,只需再次调用它即可。
我想说的是你的主要问题是你使用的是 GetButtonDown
这只是正确的 每个按钮按下一个 帧。
您应该使用 GetButton
,即 true
每一帧 只要按钮保持按下状态!
private void OnTriggerStay(Collider other)
{
if (!other.gameObject.CompareTag("Player") return;
// instead of totalAmount you could directly use the boards.Length (or .Count for a List)
// I would also rather check for < instead of !=
if(Input.GetButton("Fire1") && currentAmount < boards.Length)
{
elapsed += Time.deltaTime;
if (elapsed >= delay)
{
boards[currentAmount].SetActive(true);
currentAmount++;
elapsed = 0;
}
}
else if (Input.GetButtonUp("Fire1"))
{
// Button was released
elapsed = 0;
}
}
// I would then also reset if player leaves the collider
private void OnTriggerExit (Collider other)
{
if (!other.gameObject.CompareTag("Player") return;
elapsed = 0;
}