另一个游戏对象后面的粒子系统渲染

정현우*_*정현우 3 c# unity-game-engine particle-system

首先,我想让你了解我的英语。

我使用源代码手动将相机的投影更改为正交。请参考下面的代码。

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)
        {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我以这种方式使用代码。

CameraOrthoController.Instance.StartMatrixBlender(OrthographicSize);
Run Code Online (Sandbox Code Playgroud)

这到目前为止运作良好。但是,当我为效果添加粒子系统时出现了问题。

出现问题的屏幕

在正常状态下,效果出现在游戏对象的前面,如上图底部的场景屏幕所示。

但是如果我用上面写的代码来操作相机,效果总是会被所有的gameobject遮住,就好像它在图片顶部的游戏屏幕上一样。尽管效果位于游戏对象的前面。

起初,我认为可以通过图层排序来解决它,但我认为这不是图层问题,因为它在正常相机条件下是可见的。

我想知道上面代码的问题在哪里,因为我必须使用它们。

如果您知道如何解决,请告诉我。谢谢你。

Pro*_*mer 6

当您修改 时Camera.projectionMatrix,相机将不再根据视野更新其渲染。粒子将保持在 GameObject 后面,直到您调用Camera.ResetProjectionMatrix()它来结束设置Camera.projectionMatrix属性的效果。


如果这不起作用,请使用多个相机使粒子系统始终显示在 3D 对象的顶部。基本上,您使用主相机渲染 3D 对象和其他对象,然后使用另一台相机渲染粒子系统。

1 .创建新图层并将其命名为“粒子”

2 .将粒子系统图层更改为 Particle

在此处输入图片说明

主摄像头

1 .确保主摄像头Clear Flags设置为Skybox

2 .Culling Mask更改为“一切”。单击Everything它的设置Culling Mask并取消选择/取消选中Particle

在此处输入图片说明

3 .确保将其Depth设置为0

此时相机不应渲染粒子系统。

新相机

1 .创建新相机。确保它与主相机处于相同的位置/旋转。也删除AudioListener连接到它。

2 .ChangeClear FlagsDepth only

3 .Change的Culling Mask相机是Particle,确保没有其他的“剔除面具”被选中

在此处输入图片说明

41 . 将深度更改为。

这将使粒子系统始终显示在使用第一个或主摄像头渲染的每个对象的顶部。


如果您希望粒子系统出现在 Sprite/2d 对象而不是网格/3D 对象的顶部sortingOrder,请将粒子的Renderer更改为大于 SpriteRenderer 的sortingOrder。默认值为 0,因此将粒子的排序顺序更改为 1 或 2 应该没问题。

particle.GetComponent<Renderer>().sortingOrder = 2;
Run Code Online (Sandbox Code Playgroud)