イベント関数
ゲームオブジェクトの作成および削除

タイムとフレームレートの管理

Update 関数を使用すると、定期的にスクリプトからの入力やその他のイベントをモニターして、適切な処置を取ることができます。たとえば、“forward” キーが押された場合、キャラクターを動かすかもしれません。このような時系列のアクションを取り扱う場合、ゲームのフレームレートおよびアップデート関数を呼び出す間隔の時間はどちらも一定ではないという重要なことを覚えておいてください。

これの一例として、1つのフレームごとに、前方に徐々にオブジェクトを動かす作業を検討してください。最初は、各フレームで一定の距離にオブジェクトを移したように見えるかもしれません。

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerFrame;
    
    void Update() {
        transform.Translate(0, 0, distancePerFrame);
    }
}


//JS script example
var distancePerFrame: float;

function Update() {
    transform.Translate(0, 0, distancePerFrame);
}

しかし、フレーム時間が一定でないとすると、オブジェクトは不規則な速度で移動しているように見えます。フレーム時間が 10 ミリ秒なら、オブジェクトは distancePerFrame によって100分の1秒前進します。しかし、フレーム時間が 25 ミリ秒に増加した場合(CPU 負荷のため)、それは1秒につき40回前進することになり、より少ない距離をカバーするだけです。その解決方法は、Time.deltaTime プロパティーから読み取ったフレーム時間によって移動の大きさをスケーリングすることです。

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerSecond;
    
    void Update() {
        transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
    }
}


//JS script example
var distancePerSecond: float;

function Update() {
    transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
}

移動は現在、distancePerSecond ではなく distancePerFrame として与えられていることに注意してください。フレームレートが変化すると、移動ステップの大きさはそれに応じて変わりますので、オブジェクトの速度は一定になります。

固定タイムステップ

メインフレームアップデートとは異なり、Unity のフィジクスシステム does は、固定タイムステップに働きます。それはシミュレーションの正確さと一貫性にとって重要です。フィジクスのアップデート開始時に、Unity は最後のフィジクスの更新が終わったときの固定タイムステップ値を加算して“alarm”を設定しておきます。フィジクスシステムは、アラームが消えるまで計算を実行します。

あなたは Time Manager から固定タイムステップのサイズを変更することができます。スクリプトが使用する Time.fixedDeltaTime プロパティーからそれを読むことができます。タイムステップのための低い値は、より頻繁にフィジクスのアップデートがかかることに注意してください。より正確なシミュレーションは、より大きな CPU 負荷のコストがかかります。フィジクスエンジンに高い要求をしない限り、デフォルトの固定タイムステップを変更する必要はありません。

最大許容タイムステップ

固定タイムステップは、リアルタイムで物理シミュレーションの正確さを保持します。しかし、ゲームでフィジクスを多用する場合、場合によっては問題を引き起こす可能性があり、ゲームプレイ時のフレームレートも低くなってしまいます(ゲームのオブジェクト数が多いため)。主なフレーム・アップデート処理は、通常のフィジクスアップデートの間に“詰め込む”必要があります。実行する処理がたくさんある場合は、いくつかのフィジクスアップデートは、ひとつのフレームの間に行うことができます。フレームが始まるとき、オブジェクトの位置や他の特性がフレームの開始時に凍結され、頻繁に更新されるフィジクスの同期から抜け出すことができます。

利用できるだけの CPU パワーはありますが、Unity には効果的にフレーム処理に追いつくようにフィジクスの時間を遅くするオプションがあります。Maximum Allowed TimestepTime Managerの中にある)設定は、Unity が処理するフィジクスの消費する時間の量に制限を置き、FixedUpdate が与えられたフレームアップデートの間にコールします。フレームアップデートが Maximum Allowed Timestep 処理よりも長くかかる場合は、フィジクスエンジンは、“stop time”し、フレーム処理が追いつけるようにします。フレームアップデートが完了したら、フィジクスは、それが止められた時がなかったかのように再開されます。この結果はリジッドボディが通常そうであるように、わずかに遅くなり、完全にリアルタイムで動きません。しかし、正常に動いてきたかのように、フィジクス“クロック”はまだそれらを追跡します。フィジクスの時間の遅延は通常は目立たず、ゲームプレイのパフォーマンスに対して許容できるトレードオフです。

タイムスケール

“bullet-time”などのような特殊効果のために、アニメーションやスクリプトの応答の低下が起きたとき、ゲームの時間の経過を遅くすると便利な場合が時々あります。さらに、あなたは時々ゲームを中断したときのように、完全にゲーム時間を凍結したいかもしれません。Unity は、ゲーム時間がリアルタイムと比較してどのように進行するかについて制御する t​​ime Scale プロパティーを持っています。スケールが1.0に設定されている場合、ゲームの時間は実際のリアルタイムに一致します。0.5の値がゲームプレイを半分の速度まで遅くする一方、2.0の値は Unity で二倍の速さで時間を経過させることができます(つまり、アクションは、高速化されます)。0 の値は時間を完全に“停止”させます。タイムスケールで遅い実行を実際に行いませんが、Time.deltaTimeTime.fixedDeltaTime を経由して Update と FixedUpdate 関数に報告される時間ステップを変更することに注意してください。Update 関数は、ゲーム時間が遅くなるとき通常より頻繁に呼び出される可能性が高いですが、deltaTime ステップを伝えることでおのおののフレームは、簡単に減少されます。ゲームが中断されるとき、たとえば、正常なインタラクションで GUI を示すことができるように、他のスクリプトの機能はタイムスケールに影響を受けません。

Time Manager は、グローバルにタイムスケールを設定できるようにするプロパティーを持っていますが、一般的に、Time.timeScale プロパティーを使用するスクリプトから値を設定すると、より便利です。

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void Pause() {
        Time.timeScale = 0;
    }
    
    void Resume() {
        Time.timeScale = 1;
    }
}

//JS script example
function Pause() {
    Time.timeScale = 0;
}

function Resume() {
    Time.timeScale = 1;
}

キャプチャーフレームレート

タイムマネジメントの非常に特別なケースは、あなたがゲームプレイをビデオとして記録したいケースです。スクリーンイメージを保存する作業は、かなりの時間がかかるため、通常のゲームプレイ中にこれを行おうとすると、ゲームの通常のフレームレートが大幅に削減されてしまいます。これではゲームの真の性能を反映していない動画になってしまいます。

幸いなことに、Unity はこの問題を回避することができるCapture Framerateプロパティーを提供しています。プロパティーの値が 0 以外の値に設定されている場合、ゲームタイムは遅くなります。そして、フレームアップデートは、正確な一定の間隔で発行されます。フレーム間の間隔は、1/(Time.captureFramerate) に等しく、5.0に値が設定されて場合、更新が1/5秒ごとに発生します。フレームレートを効果的に減らす要求では、スクリーンショットを保存する Update 関数や、他の操作を実行する時間が与えられます。

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    // Capture frames as a screenshot sequence. Images are
    // stored as PNG files in a folder - these can be combined into
    // a movie using image utility software (eg, QuickTime Pro).
    // The folder to contain our screenshots.
    // If the folder exists we will append numbers to create an empty folder.
    string folder = "ScreenshotFolder";
    int frameRate = 25;
        
    void Start () {
        // Set the playback framerate (real time will not relate to game time after this).
        Time.captureFramerate = frameRate;
        
        // Create the folder
        System.IO.Directory.CreateDirectory(folder);
    }
    
    void Update () {
        // Append filename to folder name (format is '0005 shot.png"')
        string name = string.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );
        
        // Capture the screenshot to the specified file.
        Application.CaptureScreenshot(name);
    }
}

//JS script example

// Capture frames as a screenshot sequence. Images are
// stored as PNG files in a folder - these can be combined into
// a movie using image utility software (eg, QuickTime Pro).
// The folder to contain our screenshots.
// If the folder exists we will append numbers to create an empty folder.
var folder = "ScreenshotFolder";
var frameRate = 25;


function Start () {
    // Set the playback framerate (real time will not relate to game time after this).
    Time.captureFramerate = frameRate;

    // Create the folder
    System.IO.Directory.CreateDirectory(folder);
}

function Update () {
    // Append filename to folder name (format is '0005 shot.png"')
    var name = String.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );

    // Capture the screenshot to the specified file.
    Application.CaptureScreenshot(name);
}

一般的にこの技術を使用してビデオを記録するのは非常によさそうですが、遅くなってくると、ゲームをプレイすることが劇的に難しくなってきます。あなたは、テストプレーヤーの仕事を過度に難しくすることなく十分なレコーディング時間を可能にするために Time.captureFramerate 値を試してみる必要があるかもしれません。

イベント関数
ゲームオブジェクトの作成および削除