Рендеринг системы частиц за другим GameObject - PullRequest
0 голосов
/ 09 мая 2018

Во-первых, я хочу, чтобы вы поняли мой английский.

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

using UnityEngine;
using System.Collections;

public class CameraOrthoController : MonoBehaviour
{
    private Matrix4x4 ortho;

    private Matrix4x4 perspective;

    public float near = 0.001f;

    public float far = 1000f;

    private float aspect;

    public static CameraOrthoController Instance
    {
        get
        {
            return instance;
        }
        set { }
    }

    //-----------------------------------------------------
    private static CameraOrthoController instance = null;
    //---------------------------------------------------
    // Use this for initialization
    void Awake()
    {
        if (instance)
        {
            DestroyImmediate(gameObject);
            return;
        }

        //  이 인스턴스를 유효한 유일 오브젝트로 만든다
        instance = this;
    }

    private void Start()
    {
        perspective = Camera.main.projectionMatrix;
    }

    public void StartMatrixBlender(float OrthoSize)
    {
        aspect = (Screen.width + 0.0f) / (Screen.height + 0.0f);

        if (OrthoSize != 0f)
        {
            float vertical = OrthoSize;
            float horizontal = (vertical * 16f) / 9f;

            ortho = Matrix4x4.Ortho(-horizontal, horizontal, -vertical, vertical, near, far);

            BlendToMatrix(ortho, 1f);
        }
        else
        {
            BlendToMatrix(perspective, 1f);
        }
    }

//---------------------------------------
    private Matrix4x4 MatrixLerp(Matrix4x4 from, Matrix4x4 to, float time)
    {
        Matrix4x4 ret = new Matrix4x4();
        int i;
        for (i = 0; i < 16; i++)
            ret[i] = Mathf.Lerp(from[i], to[i], time);
        return ret;
    }

    IEnumerator LerpFromTo(Matrix4x4 src, Matrix4x4 dest, float duration)
    {
        float startTime = Time.time;
        while (Time.time - startTime < duration)
        {
            Camera.main.projectionMatrix = MatrixLerp(src, dest, (Time.time - startTime) / duration);
            yield return new WaitForSeconds(0f);
        }
        Camera.main.projectionMatrix = dest;
    }

//-------------------------------------------------
    private Coroutine BlendToMatrix(Matrix4x4 targetMatrix, float duration)
    {
        StopAllCoroutines();
        return StartCoroutine(LerpFromTo(Camera.main.projectionMatrix, targetMatrix, duration));
    }

//-------------------------------------------------
    public void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param = null, object Param2 = null)
    {
        switch (Event_Type)
        {

        }
    }
}

Я использую код таким образом.

CameraOrthoController.Instance.StartMatrixBlender(OrthographicSize);

До сих пор это работало хорошо. Однако проблема возникла, когда я добавил систему частиц для эффекта.

Экран, на котором возникает проблема

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

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

Сначала я подумал, что можно было бы решить это с помощью сортировки слоев, но я не думаю, что это проблема со слоем, потому что она видна в нормальных условиях камеры.

Я хочу знать, в чем проблема с вышеуказанными кодами, потому что я должен их использовать.

Пожалуйста, дайте мне знать, если вы знаете, как решить это. Спасибо.

1 Ответ

0 голосов
/ 09 мая 2018

Когда вы изменяете Camera.projectionMatrix, камера больше не будет обновлять рендеринг в зависимости от поля зрения. Частица будет оставаться за GameObject до тех пор, пока вы не вызовете Camera.ResetProjectionMatrix(), что прекращает действие эффекта, устанавливая свойство Camera.projectionMatrix.


Если это не работает, используйте несколько камер, чтобы система частиц всегда появлялась поверх трехмерного объекта. По сути, вы визуализируете 3D-объект и другие объекты с помощью основной камеры, а затем визуализируете систему частиц с помощью другой камеры.

Уровень

1 . Создайте новый слой и назовите его «Частица»

2 . Измените слой системы частиц на Particle

enter image description here

Основная камера :

1 . Убедитесь, что для Clear Flags основной камеры установлено значение Skybox.

2 . Измените Culling Mask на «Все». Нажмите Everything, который является настройкой Culling Mask и отмените выбор / снимите флажок Particle.

enter image description here

3 . Убедитесь, что для Depth установлено значение 0.

На этом этапе камера не должна отображать систему частиц.

Новая камера :

1 . Создать новую камеру. Убедитесь, что он находится в том же положении / повороте, что и основная камера. Также удалите прикрепленный к нему AudioListener.

2 . Изменить Clear Flags на Depth only.

3 . Измените Culling Mask камеры на Particle и убедитесь, что больше ничего не выбрано в "маске отбора"

enter image description here

4 . Изменить глубину до 1.

Это заставит систему частиц всегда отображаться поверх каждого объекта, отображаемого с помощью первой или основной камеры.


Если вы хотите, чтобы система частиц появлялась поверх объекта Sprite / 2d вместо объекта Mesh / 3D, измените sortingOrder частицы Renderer, чтобы она была больше, чем у SpriteRenderer sortingOrder. По умолчанию 0, поэтому изменение sortingOrder Частицы на 1 или 2 должно быть в порядке.

particle.GetComponent<Renderer>().sortingOrder = 2;
...