c# - How to manage multiple timers to control various elements of Unity game?
问题描述
My end goal is to have a tile game with Home tile and surrounding tiles- character moves to highlighted square and back to home square at the speed in which the game is presented. I am trying to design a game with few speed modes. Two Instances being-
- HomeTile highlighted then Tile 3 (highlighted for x seconds) then HomeTile then Tile 8 (highlighted for x seconds) then HomeTile.... so on. The x seconds can be increased or decreased by a UI slider. Points are given as the charachter enters the correct highlighted tile.
- HomeTile highlighted then Tile 3 (highlighted for x seconds) & character needs to be on this tile for y seconds to get point then HomeTile highlighted then Tile 8 (highlighted for x seconds) and character stays for y seconds for point then HomeTile... and so on... Again speed is controlled by UI slider.
y= 80% of x seconds.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.IO;
using System;
using System.Collections.Generic;
public class MultiDirection_short : MonoBehaviour
{
public Slider speedSlider;
public int scoreValue;
public static bool onTargetFlag = false; // flag to indicate character on target
public static bool failedTargetReachFlag = false; // flag to indicate character did not reach the target
public int currentRowNumber;
public int randomNumber;
private Double elapsedTime;
public static float timeLefts;
public float timeBeforeChange;
private static TimeSpan time1, time2, homeTime, dwellTime, requiredDwellTime;
private DateTime time12, startTime, dwellTimeStart;
private bool homeSquareLit = true; // To indicate if the home Tile is on.
private bool targetTile = false; //to indicate if any of the target tiles are on.
void Start()
{
startTime = DateTime.Now; // time declared at the start of the program. This is valid for first iteration.
}
void Update()
{
timeBeforeChange = Scaler.speedPres;
time2 = new TimeSpan(0, 0, (int)timeBeforeChange);
Debug.Log("TimeBeforeChange: " + (int)timeBeforeChange);
homeTime = new TimeSpan(0, 0, 1);
Debug.Log("t2/2=" + time2.Seconds / 2);
elapsedTime = (timeLefts % 60) - DateTime.Now.Second;
time12 = DateTime.Now; // the current time
TimeSpan time1 = time12 - startTime;
Debug.Log("Time1: " + time1);
if (gameManager.Instance.Play)
{
if (!gameManager.Instance.Paused)
{
Scaler.speedPres = speedSlider.value; // to ensure the values dont change randomly before the play button is pressed.
}
}
if (gameManager.Instance.Paused)
{
Scaler.speedPres = speedSlider.value; // to ensure the values dont change randomly before the play button is pressed.
randomNumber = 0;
//highlight the home square and make everything else white
HomeTile.GetComponent<Renderer>().material.color = Color.grey;
FrontLeftTile.GetComponent<Renderer>().material.color = Color.white;
FrontRightTile.GetComponent<Renderer>().material.color = Color.white;
}
if ((time1 > homeTime) && (homeSquareLit)) // TARGET SQUARE lit
{
randomNumber = UnityEngine.Random.Range(1, 10);
//Defining the conditions in which the squares light up- EACH CASE per square
switch ((randomNumber))
{
case 1:
FrontLeftTile.GetComponent<Renderer>().material.color = Color.blue;//1
HomeTile.GetComponent<Renderer>().material.color = Color.white;//0
FrontRightTile.GetComponent<Renderer>().material.color = Color.white;//4
break;
case 2:
FrontRightTile.GetComponent<Renderer>().material.color = Color.red;//2
HomeTile.GetComponent<Renderer>().material.color = Color.white;//0
FrontLeftTile.GetComponent<Renderer>().material.color = Color.white;//3
break;
default:
targetTile = false;
homeSquareLit = false;
break;
}
startTime = time12;
Debug.Log("startTime: " + startTime);
}
if ((time1 > time2) && (!homeSquareLit)) // HOME SQUARE BLOCK
{
Debug.Log("inside home square block, randNum_ now: " + randomNumber);
switch ((randomNumber))
{
case 1:
HomeTile.GetComponent<Renderer>().material.color = Color.blue;
FrontLeftTile.GetComponent<Renderer>().material.color = Color.white;//3
FrontRightTile.GetComponent<Renderer>().material.color = Color.white;//4
break;
case 2:
HomeTile.GetComponent<Renderer>().material.color = Color.red;
FrontLeftTile.GetComponent<Renderer>().material.color = Color.white;//3
FrontRightTile.GetComponent<Renderer>().material.color = Color.white;//4
default:
break;
}
startTime = time12;
}
}
void OnTriggerEnter(Collider other)
{
dwellTimeStart = DateTime.Now;
requiredDwellTime = new TimeSpan(0, 0, 1);
DateTime requiredDwellTime = 1.5f;
if ((dwellTimeStart.Second > requiredDwellTime.Seconds)) // TARGET SQUARE lit
{//trigger or change color of tile as above.
}
So for the First Scenario- This code works fine as is.. However when I reduce the time on the slider below 2 seconds then the the half equals 0 as int. Then the game stops working with the if statements... Or if statements are removed then it works so fast that it looks like its flickering between the targets.
Am I supposed to use a different timer? AM i mistakenly taking update time?
解决方案
public static float timeLefts;
public float timeBeforeChange;
private static TimeSpan time1, time2, homeTime, dwellTime, requiredDwellTime;
private DateTime time12, startTime, dwellTimeStart;
天哪。您有 10 个计时器值要在单个 class中跟踪。这不是要走的路。
你有两个选择:
- 您可以实例化并保存其时间值并根据需要执行任何任务的自定义对象,您将这些对象存储在您每帧更新的列表中。
- Coroutines,您说“将此函数作为协程执行”,在该函数内部,您可以执行诸如
yield return new WaitForSeconds(5)
使该函数的执行暂停 5 秒(或多长时间)之类的事情。
推荐阅读
- mongodb - 通过数组内部文档的 id 更新数组中的文档,但是如果该 id 的文档在数组中不存在,则在 mongodb 中创建一个具有该 ID 的文档
- python - 无法从 pipenv virtualenv 导入 pyspark,因为它找不到 py4j
- python - 如何从 Instagram 中提取数据?
- django - drf-yasg 如何在外面显示 api 描述?
- json - 怎么修
在 WSO2 中 - sql - 带光标的 SSRS 订阅
- sql - sql查询将列表项与其总数进行比较
- xslt - XSLT / 链接元素到组
- android - 如何通过appium启动服务而不是活动?
- java - java.lang.RuntimeException:java.security.NoSuchAlgorithmException:找不到为 SecureRandom(提供者:IBMJCE)配置的类