Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Webplayer Fail or Brain Fail?

Discussion in 'Editor & General Support' started by twobob, Apr 9, 2015.

  1. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Hi, TL;DR: When I place Particles Individually it works in the editor but not in a build:

    I had a very simple idea for trees. cheap simple billboard trees like down the side of the old racing games.

    In order to make them as cheap as possible I went for particles.

    which I setup like this:

    upload_2015-4-9_2-24-54.png

    And I attach this rudimentary, but nicely commented script to it.
    Which - if you can't be bothered to read it, simply:
    1) Creates a bunch of random positions on a mesh surface.
    2) Then assigns those positions to a particle list and then
    3) Assigns that list of particles to the system.

    here is that code
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.UI;
    5. using System.Text;
    6.  
    7. public class PlaceParticles : MonoBehaviour
    8. {
    9.  
    10. public bool debugThisMess = true;
    11. public ParticleSystem tree;
    12.  
    13. public Transform ObjectToPopulateWithParticles;
    14.  
    15. private StringBuilder _sb = new StringBuilder(256);
    16.  
    17. // perhaps this is getting called out of sequence?
    18. void Start()
    19. {
    20.  
    21. // should be 1000
    22. int partNum = tree.particleCount;
    23.  
    24. // make a list, of the same length
    25. ParticleSystem.Particle[] ParticleList = new ParticleSystem.Particle[partNum];
    26. tree.GetParticles(ParticleList);
    27.  
    28. if (debugThisMess)
    29. {
    30. _sb.Append("placing " + partNum + " particles as trees");
    31. DisplayError(ref _sb);
    32. }
    33.  
    34. for (int i = 0; i < partNum; ++i)
    35. {
    36. //for sanity we check the positions created by our helper methods.
    37. // "5" is the tree sprite height offset we want, ignore it.
    38. //
    39. // GenerateRandomLocationInArea and ShootRayReturnParticlePosition
    40. // just find a place in a block and shoot a ray down,
    41. // nothing fancy, just puts it on the floor.
    42.  
    43. Vector3 newPlace = ItemSpawner.ShootRayReturnParticlePosition(ItemSpawner.GenerateRandomLocationInArea(ObjectToPopulateWithParticles)) + (Vector3.up * 5); // magic number erk!
    44. // we should have a valid position
    45. // (since this is a "tested as working" method used for non-particle placement)
    46.  
    47. if (debugThisMess)
    48. {
    49. _sb.Append("placing particle " + i + " at " + newPlace);
    50. DisplayError(ref _sb);
    51. }
    52.  
    53. // actually assign the location to the particle in the list
    54. ParticleList[i].position = newPlace;
    55. }
    56.  
    57. //actually assign the particles, with new postions, back to the system
    58. tree.SetParticles(ParticleList, partNum);
    59.  
    60. //tree.gravityModifier = 0; in case your trees sink...
    61. }
    62.  
    63. ///<summary>
    64. /// Ugly helper to spit out stuff to screen and log
    65. ///</summary>
    66. ///<param name="sb"></param>
    67. private void DisplayError(ref StringBuilder sb)
    68. {
    69. Debug.Log(_sb);
    70. // toScreen code elided
    71. _sb.Remove(0, _sb.Length);
    72.  
    73. }
    74. }
    75.  
    looks like

    upload_2015-4-9_2-57-40.png

    This works perfectly in the editor.

    upload_2015-4-9_3-0-21.png

    Giving me thousands of trees for a couple of draw calls...

    upload_2015-4-9_3-1-3.png

    but if I try to do this in the webplayer I get a 0 result for my test.
    and all the particles stay in the default position (since I don't actually set them in that case)


    upload_2015-4-9_3-4-19.png

    any clues on my mistake?
    I don't think it is a code mistake. I am not understanding the Particle System life-cycle probably..


    Many thanks.

    Okay so it's a delay thing. Workaround in the end posts
     
    Last edited: Apr 9, 2015
    Alverik likes this.
  2. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    I tried setting the execution delay for the script to be last..

    didn't help
     
    Alverik likes this.
  3. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Do I need to wait one frame for the particle system to populate? or something?
    I'll give that a try. I thought that was what Pre-warming was. Plus I told it to jam 1000 right at the start...

    Hardcoding the particles to 1000 and jamming them into the system didn't work :(
    And it's not just the webplayer, it does this on anything /outside/ the editor, where it works fine..

    I also tried with and without prewarming to no avail

    upload_2015-4-9_4-20-38.png

    and I tried putting "Infinity" into the value boxes but it looks like that has been noob-nerfed to 100000 (which could be a pain :( )

    workaround below
     
    Last edited: Apr 9, 2015
    Alverik likes this.
  4. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    so. I was right. it was some sort of undocumented (as far as I can find) delay in the particle creation.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlaceParticles : MonoBehaviour
    5. {
    6. public ParticleSystem tree;  // plural. like sheep.
    7.  
    8. public Transform ObjectToPopulateWithParticles;
    9. // a flatish square mesh is a good idea since our helper will take a
    10. // random point sample in the negative Y on a pre-defined square.
    11. // You can write better helpers...
    12.  
    13. // we will just start a loop until we have our particles ready to reposition
    14. void Start()
    15. {
    16. StartRepeatingCheckForParticleCount();
    17. }
    18.  
    19. void CreateTreesFromParticles()
    20. {
    21. // should be 1000 in my case...
    22. int partNum = tree.particleCount;
    23.  
    24. if (partNum == 0)
    25. return;
    26.  
    27. // make a list, of the same length
    28. ParticleSystem.Particle[] ParticleList = new ParticleSystem.Particle[partNum];
    29. tree.GetParticles(ParticleList);
    30.  
    31. for (int i = 0; i < ParticleList.Length; ++i)
    32. {
    33. // "5" is the tree sprite height offset we want, ignore it. change it for your tree height
    34. // GenerateRandomLocationInArea and ShootRayReturnParticlePosition
    35. // just find a place in a block and shoot a ray down,
    36. // nothing fancy, just puts it on the floor.
    37.  
    38. Vector3 newPlace = ItemSpawner.ShootRayReturnParticlePosition(ItemSpawner.GenerateRandomLocationInArea(ObjectToPopulateWithParticles)) + (Vector3.up * 5); // magic number erk!
    39.  
    40. // actually assign the location to the particle in the list
    41. ParticleList[i].position = newPlace;
    42. }
    43.  
    44. //actually assign the particles, with new positions, back to the system
    45. tree.SetParticles(ParticleList, partNum);
    46.  
    47. CancelInvoke("CreateTreesFromParticles");
    48. }
    49. void StartRepeatingCheckForParticleCount()
    50. {
    51. InvokeRepeating("CreateTreesFromParticles", 0, 0.02F);
    52. }
    53. }
    54.  
    EDIT: I removed all the old debug code


    PROS: fixes the issue. well okay - works around it. which I can live with. Is incredibly cheap.
    Does not require additional batching.
    Is fire and forget (well maybe not, not sure what will happen after 100000 counts...)

    CONS: the shadows are never going to be perfect without more work.
    needs a fast dynamic collider system adding and near frustum intersection checking for the camera to seem like "real trees".

    upload_2015-4-9_4-44-1.png

    upload_2015-4-9_4-44-28.png

    an enterprising person could put a fast spacial grid of colliders in the same places and get some extremely cheap trees this way. see below I provide a worked example of this


    I need to figure out a way to fix the shadows being offset but it seems doable; now we have an "only shadows" option more-so than ever

    Enjoy.

    This does have the unfortunate side-effect of shooting rays onto existent buildings etc...
    So you might want to add a few checks to the ray casting

    EDIT: I simply added a similar conditional wait to my main item spawner and check for a GameManager.TreeParticlesCreated flag that I set upon completion.

    this gives us nicely ordered objects:

    upload_2015-4-9_5-49-43.png
     
    Last edited: Apr 10, 2015
    Alverik likes this.
  5. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    for completeness. The helper really does nothing much: Return a random place in a square. Shoot down a Ray.
    Code (csharp):
    1.  
    2. // partial bits shown for clarity
    3. // 256 is my "magic" block size
    4. public static Vector3 GenerateRandomLocationInArea(Transform chosenparent)
    5. {
    6. return new Vector3(Random.Range(10, 246) + chosenparent.position.x, 35f,
    7. Random.Range(10, 246) + chosenparent.position.z);
    8. }
    9.  
    10. public static Vector3 ShootRayReturnParticlePosition(Vector3 location)
    11. {
    12. Vector3 targetPosition = Vector3.zero;
    13. RaycastHit hit;
    14.  
    15. if (Physics.Raycast(location, -Vector3.up, out hit))  // ugh.
    16. { targetPosition = hit.point; }
    17.  
    18. return targetPosition;
    19. }
    20.  
    And HERE https://gist.github.com/twobob/0ab2a30ecb92c4627c0d is a combined version for simplicity

    and here is what I used exactly https://gist.github.com/twobob/f7b34a4b404a9cee44da
    to actually provide a collider system

    and here are the meaningful particle settings

    upload_2015-4-10_0-25-17.png
     
    Last edited: Apr 10, 2015
    Alverik likes this.
  6. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Tested this today. as of 5.3 seems like this no longer places the particles... hey ho. will investigate at some point
     
    Alverik likes this.