/** * Add a new foliage type to the runtime data. After it has been added it can be used for * painting grass around. * * NOTE: Make sure that it's a normal prefab or a SpeedTree prefab! Or of it's generated at runtime make * absolutely sure that it will not go away with some scene unloading or that it will get eventualy nulled. * * @param builder * Builder that contains the data that will populate the type * @return The foliage type hash that can be later used to remove the foliage type and add/remove foliage instances */ private int AddFoliageType(FoliageTypeBuilder builder) { throw new System.NotImplementedException(); }
public static void ConfigurePrefab(GameObject foliage, out FoliageTypeBuilder outBuilder, out bool outAnyError) { PrefabType type = PrefabUtility.GetPrefabType(foliage); if (type != PrefabType.ModelPrefab && type != PrefabType.Prefab) { FoliageLog.e("The prefab type of: " + foliage.name + " is: '" + type + "'! Must be a 'ModelPrefab' or a 'Prefab'!"); outAnyError = true; } string path = AssetDatabase.GetAssetPath(foliage); FoliageLog.i("Path of added foliage type: " + path); FoliageTypeBuilder builder = new FoliageTypeBuilder(); // Build all it's required data builder.m_PaintInfo = new FoliageTypePaintInfo(); builder.m_RenderInfo = new FoliageTypeRenderInfo(); bool anyWeirdGrassError = false; // Attempt to auto-configure the foliage for the easiest possible user interaction if (path.EndsWith(".spm")) { // We have a SpeedTree LODGroup lodGroup = foliage.GetComponent <LODGroup>(); if (lodGroup != null) { if (lodGroup.lodCount == 1) { FoliageLog.i("Detected a SpeedTree grass, since it has 1 LOD!"); builder.m_Type = EFoliageType.SPEEDTREE_GRASS; builder.m_EnableCollision = false; if (foliage.GetComponentInChildren <MeshRenderer>() == null) { anyWeirdGrassError = true; FoliageLog.e("SpeedTree grass without any MeshRenderer detected!"); } } else { FoliageLog.i("Detected a SpeedTree tree, since it has 1+ LODS!"); builder.m_Type = EFoliageType.SPEEDTREE_TREE; builder.m_EnableCollision = foliage.GetComponentInChildren <Collider>() != null ? true : false; if (foliage.GetComponentInChildren <BillboardRenderer>() != null) { builder.m_Type = EFoliageType.SPEEDTREE_TREE_BILLBOARD; } if (foliage.GetComponentInChildren <MeshRenderer>() == null) { anyWeirdGrassError = true; FoliageLog.e("SpeedTree tree without any MeshRenderer detected!"); } } // Set the bounds builder.m_Bounds = lodGroup.GetLODs()[0].renderers[0].GetComponent <MeshFilter>().sharedMesh.bounds; } else { FoliageLog.e("Weird, we have a SpeedTree without a lod group. Anything wrong here? Please fix."); anyWeirdGrassError = true; builder.m_Bounds = foliage.GetComponentInChildren <MeshFilter>().sharedMesh.bounds; } } else { LODGroup lodGroup = foliage.GetComponent <LODGroup>(); if (lodGroup != null && lodGroup.lodCount > 1) { FoliageLog.i("Detected an object tree!"); builder.m_Type = EFoliageType.OTHER_TREE; builder.m_EnableCollision = foliage.GetComponentInChildren <Collider>() != null ? true : false; if (foliage.GetComponentInChildren <MeshRenderer>() == null) { anyWeirdGrassError = true; FoliageLog.e("Object tree without any MeshRenderer detected!"); } // Set the bounds builder.m_Bounds = lodGroup.GetLODs()[0].renderers[0].GetComponent <MeshFilter>().sharedMesh.bounds; } else { FoliageLog.i("Detected an object grass!"); builder.m_Type = EFoliageType.OTHER_GRASS; builder.m_EnableCollision = false; if (foliage.GetComponentInChildren <MeshRenderer>() == null) { anyWeirdGrassError = true; FoliageLog.e("Object grass without any LOD group or MeshRenderer detected!"); } // Set the bounds builder.m_Bounds = foliage.GetComponentInChildren <MeshFilter>().sharedMesh.bounds; } } LODGroup group = foliage.GetComponent <LODGroup>(); if (group != null && group.lodCount > 0) { LOD[] lods = group.GetLODs(); for (int i = 0; i < lods.Length; i++) { Renderer[] rends = lods[i].renderers; if (rends == null || rends.Length != 1) { anyWeirdGrassError = true; FoliageLog.e("Detected object with a lod without any renderers on it or with more than one renderer attached to it!"); } } } if (anyWeirdGrassError) { EditorUtility.DisplayDialog("Error", "Found error for foliage: " + foliage.name + "! Could not add to system! Check the log for more info!", "Ok"); FoliageLog.e("Found error for foliage: " + foliage.name + "! Could not add to system!"); } else { // Set the prefab builder.m_Prefab = foliage; builder.m_PaintEnabled = true; switch (builder.m_Type) { case EFoliageType.OTHER_GRASS: case EFoliageType.SPEEDTREE_GRASS: builder.m_RenderInfo.m_CastShadow = false; builder.m_RenderInfo.m_MaxDistance = 30; break; case EFoliageType.OTHER_TREE: case EFoliageType.SPEEDTREE_TREE: case EFoliageType.SPEEDTREE_TREE_BILLBOARD: builder.m_RenderInfo.m_CastShadow = true; builder.m_RenderInfo.m_MaxDistance = 100; break; } } switch (builder.m_Type) { case EFoliageType.OTHER_GRASS: case EFoliageType.SPEEDTREE_GRASS: builder.m_PaintInfo.m_SurfaceAlign = true; break; case EFoliageType.OTHER_TREE: case EFoliageType.SPEEDTREE_TREE_BILLBOARD: case EFoliageType.SPEEDTREE_TREE: builder.m_PaintInfo.m_SurfaceAlign = false; break; } if (anyWeirdGrassError == false) { if (builder.m_Type == EFoliageType.SPEEDTREE_GRASS || builder.m_Type == EFoliageType.SPEEDTREE_TREE || builder.m_Type == EFoliageType.SPEEDTREE_TREE_BILLBOARD) { // Get a hue builder.m_RenderInfo.m_Hue = foliage.GetComponentInChildren <MeshRenderer>().sharedMaterial.GetColor("_HueVariation"); builder.m_RenderInfo.m_Color = foliage.GetComponentInChildren <MeshRenderer>().sharedMaterial.GetColor("_Color"); if (builder.m_RenderInfo.m_Hue == new Color(0, 0, 0, 0)) { builder.m_RenderInfo.m_Hue = Color.white; } if (builder.m_RenderInfo.m_Color == new Color(0, 0, 0, 0)) { builder.m_RenderInfo.m_Color = Color.white; } } else { builder.m_RenderInfo.m_Hue = Color.white; builder.m_RenderInfo.m_Color = Color.white; } } outAnyError = anyWeirdGrassError; outBuilder = builder; }
/** Adds a new foliage type to the painter */ public void AddFoliageType(FoliageTypeBuilder foliageType) { m_Painter.AddFoliageType(foliageType); }