动态实例化5个表的5个计时器(UNITY 3D)

时间:2018-07-16 03:32:26

标签: c# unity3d

我有一个问题。我确实有5个表对象,并且需要5个计时器,所以每个表1个计时器

我创建了一个名为Table.cs

的脚本

Table.cs

public UILabel info_timer = null;

我有我的主脚本,叫它Main.cs

Main.cs

const float gap = 20.0f;
Table[] script_table;
bool start_timer = false;
int t_no;
public static string Ctimer = "";

void Update()
{

     int i = returnTableNo(t_no);

     if (i != -1 && script_tables != null && script_tables[i] != null)
     {
           gap -= Time.deltaTime();

           if(gap <= 0.0f)
           {
                script_table[i].info_timer =  Ctimer = "[808080]0[-]";
           }
           else
           {
                script_table[i].info_timer.text = gap.ToString("F0");
           }
      }
 }

 //someone will call this to make start_timer to true;
 void ActivateTimer(){
     t.tableno = t_no;
     start_timer = true;
 }

//this line of code is for the table no == table no
int returnTableNo(int table_no)
{
   //table is equavalent to 5 for now
    for (int i = 0; i < table.Count; i++)
    {
        if (t.table_no == table_no)
        {
            return i;
        }
    }
    return -1;
}

现在,我对如何将每个计时器放在我拥有的每个表上感到非常困惑。因为我遇到的情况就是这样,例如

表1仅在运行,只有表1定时器将是唯一一个将启动定时器的定时器,但是发生的是即使我的某些表未运行,所有表定时器也在运行。

在调用他的命令时它们正在运行

GCommand.start_:

这是一张画,以便您可以直观地看到我要做什么。

Sample Image

谢谢能帮助我的人。

2 个答案:

答案 0 :(得分:3)

您可以在两个(通常)位置之一中保留计时器功能。第一个在您的Main.cs中,第二个在您的Table.cs中。每种方法都有优点和缺点。我的喜好是将Table.cs修改为基本上允许使用任何一种样式,但是下面的示例倾向于在每个Table内进行所有处理。

使用Table.cs封装功能示例:

// If Table.cs is derived from MonoBehaviour, the Update() method can be
// used to drive the timer. But adds the inherit overhead of being a MonoBehaviour.
public class Table : MonoBehaviour
{
  public UILabel info_timer = null;

  const float gap = 20.0f;

  private float timer;
  public bool isActive { get; private set; } = false;

  public void ActivateTimer( bool activate = true)
  {
    // If activate is true, then reset this timer to the default.
    if ( activate )
      timer = gap;
    isActive = activate;
  }

  // Use Update to drive the timer from each components Update call? Ignored if this class does not derive from MonoBehaviour.
  public void Update()
  {
    UpdateTimer(Time.deltaTime);
  }

  // Use an explicit update method to drive the timer.
  public void UpdateTimer( float deltaTime)
  {
    // We can even check to see if the table is active or the timer has already timed out.
    if ( !isActive ) return;

    timer -= deltaTime;

    if ( timer <= 0.0f )
    {
      script_table[i].info_timer =  Ctimer = "[808080]0[-]";
      isActive = false;
    }
    else
      script_table[i].info_timer.text = gap.ToString("F0");
  }
}

使用Main.cs驱动所有表的所有更新,而不是表更新方法:

public class Main : MonoBehaviour
{
  const float gap = 20.0f;
  Table[] script_table;
  bool start_timer = false;
  int t_no;
  public static string Ctimer = "";

  public void Update()
  {
    for ( int i = 0; i < script_table.Length; i++ )
      script_table[i].UpdateTimer(Time.deltaTime);
  }

  // This method can now be used to Activate or De-Activate a timer.
  public void ActivateTimer ( int tableNumber, bool activate = true )
  {
    script_table[tableNumber ].ActivateTimer( activate );
  }
}

答案 1 :(得分:1)

我为一个创建了Clock类和ClockManager类(单个)。这样,我可以创建计时器实例,然后将其自动添加到ClockManager中的列表中。它使用MonoBehavior Update(MonoBehavior更新)(所有功能都使用一个!对于性能而言也更好。)为所有Timer调用“ tick”,每个Timer都有自己的触发间隔。可以是0.0秒(意味着每次更新),每0.1秒,每2.0秒等等。当它们被触发时,它们将调用给定的System.Action,它们将间隔值或该间隔值的整数(如果多个间隔具有一个更新周期内就达到了)。

用法很简单:

Clock idleClock = new Clock (this, DoIdleCheck, 0.5f);
// Parameters: 1. Reference to the object for automatic destruction.
// 2. The target method to invoke. 3. Interval.

有太多代码无法复制粘贴到这里,因为它与我的其他代码交织在一起。但是通过这种方式,您可以将任意数量的计时器用于所需的任何对象,并根据需要暂停或启动它们。当然,您也可以通过简单的方式来实现它。