Unity 6.3
0 онлайн 2 гостей 3 в системе
Вход

PlayerLoop.SetPlayerLoop

Declaration

public static void SetPlayerLoop(LowLevel.PlayerLoopSystem loop);

Описание

Установить новый пользовательский порядок обновления для всех систем двигателя в Unity.

Используйте SetPlayerLoop для указания пользовательского порядка обновления для цикла проигрывателя. PlayerLoopSystem, предоставленные в качестве параметра loop, становятся новым текущим циклом проигрывателя, возвращаемым GetCurrentPlayerLoop. Новый порядок обновления не вступает в силу до следующей полной итерации цикла проигрывателя, но изменения сразу видны в последующих вызовах GetCurrentPlayerLoop.

Будут запускаться только системы, включенные в новый цикл проигрывателя. Вы можете вставить точки входа пользовательского скрипта в порядок обновления до его установки. Например, это позволяет добавить скрипт, который запускается непосредственно перед физикой, или в других местах, где скрипты не запускаются по умолчанию.

В следующем примере вставляется пользовательская система цикла проигрывателя, которая запускается после системы PreLateUpdate в цикле проигрывателя. Для пользовательской системы updateDelegate назначен метод CustomUpdate, который выводит сообщение в консоль при запуске.

Дополнительные ресурсы: PlayerLoopSystem.

using System.Collections.Generic;
using UnityEngine.LowLevel;
using UnityEngine.PlayerLoop;
using UnityEngine;
using System;

// Insert a custom update at a specified point (after an existing update phase) in the Unity Player Loop.

public class MyCustomUpdate { } // Empty class to use as a type identifier for the custom update

public static class InsertSystem
{
    // Event that MonoBehaviour scripts can subscribe to for custom update logic
    public static event Action AddCustomUpdate;

    //Run this method on runtime initialization
    [RuntimeInitializeOnLoadMethod]
    private static void AppStart()
    {
        // Retrieve the default Player loop system. Get the current loop instead if the default was already modified previously.
        var defaultLoop = PlayerLoop.GetDefaultPlayerLoop();

        // Create a custom update system
        var myCustomUpdate = new PlayerLoopSystem
        {
            subSystemList = null,
            updateDelegate = CustomUpdate,
            type = typeof(MyCustomUpdate)
        };
        // Add the custom update system after the PreLateUpdate phase in the Player Loop
        var loopWithCustomUpdate = InsertSystemAfter<PreLateUpdate>(in defaultLoop, myCustomUpdate);
        PlayerLoop.SetPlayerLoop(loopWithCustomUpdate);
    }

    private static PlayerLoopSystem InsertSystemAfter<T>(in PlayerLoopSystem loopSystem, PlayerLoopSystem newSystem) where T : struct
    {
        // Create a new root PlayerLoopSystem
        PlayerLoopSystem newPlayerLoop = new()
        {
            loopConditionFunction = loopSystem.loopConditionFunction,
            type = loopSystem.type,
            updateDelegate = loopSystem.updateDelegate,
            updateFunction = loopSystem.updateFunction
        };
        // Create a new list to populate with subsystems, including the custom system
        List<PlayerLoopSystem> newSubSystemList = new();

        //Iterate through the subsystems in the existing loop we passed in and add them to the new list
        if (loopSystem.subSystemList != null)
        {
            for (var i = 0; i < loopSystem.subSystemList.Length; i++)
            {
                newSubSystemList.Add(loopSystem.subSystemList[i]);
                // If the previously added subsystem is of the type to add after, add the custom system
                if (loopSystem.subSystemList[i].type == typeof(T))
                {
                    newSubSystemList.Add(newSystem);
                }
            }
        }

        newPlayerLoop.subSystemList = newSubSystemList.ToArray();
        return newPlayerLoop;
    }

    //Custom update function that will be called in the Player Loop
    private static void CustomUpdate()
    {
        // Invoke the custom update event if there are subscribers
        AddCustomUpdate?.Invoke();
        Debug.Log("Custom update inserted in the default Player loop.");
    }
}