Search Unity

Particle system with dynamic mesh per sub-emitter

Discussion in 'Scripting' started by CraftedGaming, Nov 27, 2021.

  1. CraftedGaming

    CraftedGaming

    Joined:
    Jun 9, 2017
    Posts:
    37
    For the background, I'm working on a 3D game and I have a slime particle system where it shoots out slime balls and places liquid-like textures onto the floor.
    upload_2021-11-28_1-31-15.png

    The problem is that the liquid texture (sub-emitter's particle) extends out far from the mesh / ground mesh and into the air. I could probably make the texture a bit smaller in size so it doesn't have to extend out like the one above. But, I would encounter overdraw within the surrounding area.

    And so, I was thinking of deforming or changing the plane where the liquid texture is shown in such a way that it handles ground collisions. much like those seen in CS:GO or Valorant where the flame grenade or Viper's snake bite can only appear on top of surfaces.

    Here's a reference from Valorant:
    upload_2021-11-28_1-37-54.png

    My expected outcome:
    upload_2021-11-28_1-30-59.png
    So far, this is my code:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SlimeFX : MonoBehaviour
    4. {
    5.     [SerializeField, Tooltip("The height used to pad the raycast properly")]
    6.     float yPadding = 1.5f;
    7.    
    8.     [SerializeField, Tooltip("The final height of the vertex from the ground mesh relative to the normal")]
    9.     float yPaddingFromTheGround = .05f;
    10.    
    11.     [SerializeField] float size = 1;
    12.     [SerializeField, Tooltip("The higher the density, the higher the vertex count found on the texture"), Range(10,200)]
    13.     int density = 10;
    14.    
    15.     [SerializeField] LayerMask groundLayer;
    16.  
    17.     GridInfo[,] grid;
    18.     ParticleSystem psystem;
    19.     ParticleSystemRenderer psystemRenderer;
    20.     MeshFilter filter;
    21.     Mesh mesh => psystemRenderer.mesh;
    22.  
    23.     Vector3 centerPos;
    24.  
    25.     void Awake(){
    26.         psystem = GetComponent<ParticleSystem>();
    27.         psystemRenderer = GetComponent<ParticleSystemRenderer>();
    28.  
    29.         centerPos = psystem.transform.position;
    30.         grid = new GridInfo[density,density];
    31.         GetGrid();
    32.         RaycastTheGrid();
    33.     }
    34.     void GetGrid(){
    35.         int halfDensity = (density / 2) + (density % 2 == 1 ? 1: 0);
    36.         float distanceBetweenVertices = size / density;
    37.         for (int x = 0; x < density; x++)
    38.         {
    39.             for (int y = 0; y < density; y++)
    40.             {
    41.                 Vector3 vertexPos = centerPos;
    42.                 vertexPos.x += distanceBetweenVertices * (x < halfDensity / 2?1:-1);
    43.                 vertexPos.z += distanceBetweenVertices * (y < halfDensity / 2?1:-1);
    44.                 vertexPos.y += yPadding;
    45.                 grid[x,y] = new GridInfo{
    46.                     worldPos = vertexPos,
    47.                     normal = Vector3.zero,
    48.                     hasGround = false
    49.                 };
    50.             }
    51.         }
    52.     }
    53.     void RaycastTheGrid(){
    54.         for (int x = 0; x < density; x++)
    55.         {
    56.             for (int y = 0; y < density; y++)
    57.             {
    58.                 if(Physics.Raycast(grid[x,y].worldPos,Vector3.down,out RaycastHit hit,yPadding + 1,groundLayer)){
    59.                     grid[x,y].normal = hit.normal;
    60.                     grid[x,y].hasGround = true;
    61.                 }
    62.             }
    63.         }
    64.     }
    65.     struct GridInfo {
    66.         public Vector3 worldPos;
    67.         public Vector3 normal;
    68.         public bool hasGround;
    69.     }
    70. }
    71.  
    Any advice on how to resolve this texture problem or another solution to get the photo above?
     
  2. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Have you tried a projector? But this probably looks weird on steep angles but could be worth a try.
     
  3. CraftedGaming

    CraftedGaming

    Joined:
    Jun 9, 2017
    Posts:
    37
    I think that solves the visual part.. at least for perpendicular floors and if the project is using the Built-in rendering pipeline or is using the HDRP decal feature. although, how would I the collisions for it if it has varying height?
     
  4. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    I don't know the games you mention and what you need the collision for. Projector is just a visual thing, not physical. Maybe look if you can somehow restrict the things which it projects on (fe layers)?
     
  5. CraftedGaming

    CraftedGaming

    Joined:
    Jun 9, 2017
    Posts:
    37
    Then I don't think that fully answers the problem I have above... as you suggested a visual solution when I'm looking for a visual and physical solution
     
  6. CraftedGaming

    CraftedGaming

    Joined:
    Jun 9, 2017
    Posts:
    37
    Bump. Just in-case there's a solution out there