Home>

For example, suppose you have a game where an enemy aircraft moves to the right and fires bullets every 5ms.
I think that it will be as follows when writing the process ...

using UnityEngine;
public class Enemy: MonoBehaviour
{
    public GameObject bullet;
    float t;
    void Update ()
    {
      transform.position + = Vector3.right;
      t + = Time.deltaTime;
      if (t>= 0.05f)
      {
          Instantiate (bullet);
          t = 0;
      }
    }
}

If this game was running at 60fps, Update is called every 16ms, so you can't shoot bullets every 5ms, taking into account movement between enemy frames.
Is there a good solution to this problem?

  • Answer # 1

    If you useFixedUpdateinstead of

    Update, it will be executed at the same time every time regardless of the frame rate.
    You can set how many seconds the FixedUpdate will be executed inFixed Timestepin the Unity top menu "Edit>Project Settings>Time", so if you reduce this value, it will run in less than Update Is possible.

    Is it possible to create a loop by usingCoroutine?
    (may not be verified or may be delayed)
    → Verified. The method of using WaitForSeconds in Coroutine was useless (because it is called in the next frame after the specified time has passed).
    yield return null;is also waiting for one frame, so it seems that Coroutine will not measure time less than one frame.

    In any case, the screen drawing update is an update standard, so it will be "shot within the undrawn (= invisible)".


    (Added 2018/08/27)
    I noticed RTera's answer to the following question
    Unity-Screen transition does not work after stopping for a certain time (142729) | StackOverflow

    If you create a for loop in an ordinary self-made method that is not Update and measure the time withTime.realtimeSinceStartup, it seems to be able to rotate every 0.0002 seconds (maybe depending on the environment).
    …… I have a feeling that the fever on the terminal will be dangerous.

  • Answer # 2

    Resolved with System.Timers.timer.
    However, since Unity can only call Unity functions in the main thread, PimDeWitte's UnityMainThreadDispatcher was used.

    https://github.com/PimDeWitte/UnityMainThreadDispatcher

    First, place an empty GameObject with UnityMainThreadDispatcher.cs in the Scene.
    (It will automatically become DontDestroyOnLoad.)

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Timers;
    public class Enemy: MonoBehaviour
    {
        public GameObject bullet;
        float t;/// milliseconds
        void Start ()
        {
            Timer timer = new Timer (t);
            // Timer itself runs in a separate thread
            timer.Elapsed + = (sender, e) =>
            {
                UnityMainThreadDispatcher.Instance (). Enqueue (() =>
                {
                    Instantiate (bullet);
                });
            };
             timer.Start ();
        }
    }

  • Answer # 3

    3 shots per frame.

    The limitations of hardware are impossible to do with software
    In the first place, the specification itself must be reconsidered.

    I heard that you can get 32bit color on the # RGB565 panel. . (Toyme