Announcement

Collapse
No announcement yet.

Level generation

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Level generation

    Hi, guys I am not a newb to programming or game dev, I am however a newb to Unreal Engine from Unity work flow.
    With that said I could really use some help getting started in Unreal.
    I started my Adventure Fantasy game in Unity and soon realized that performance wise it was not going to work for what I wanted to achieve. I am now trying to convert the following process into Unreal.
    I was creating procedurally generated levels by taking 100's of maze map images like the one attached, randomly selecting one, randomly selecting the wall type, wall objects, floor tiles and then reading the image pixel by pixel. I would instantiate a wall where it was was black and floor where it was white.
    In Unreal I am still unsure on how to achieve this. Do I write it in a C++ Class code like I wrote it in C# in Unity or do I use a Blueprint.

    Sorry if this all seems really basic, its one HECK of a learning curve for sure

    #2
    In Unreal you can do most things that aren't super low level in either C++ or Blueprints with the stipulation that Blueprints are a bit less efficient. I've worked with some folks on a full-fledged infinite runner VR game using nothing but Blueprints, and it runs fine. However for most of the heavier proc-gen stuff like this I've always stuck to C++. Plus once you get in the swing of things it becomes trivially easy to tie them together. A lot of it is a matter of preference. If you are new to Unreal I found that starting with Blueprints is a great way to quickly learn the game framework.

    As for this specific case, having each pixel represented by a separate mesh can get expensive really quick. You may want to look into a different approach - combine several points into lines, check for intersections, etc. In either case, you'll want to use Instanced Static Mesh Components to render thousands of the same mesh efficiently. Check out the link attached below for a good quick start in the first answer. There are also Hierarchical Instanced Static Mesh Components, which is the same thing but with LOD support.

    For reading pixel by pixel, AFAIK there isn't really a sane way to do this in Unreal. You may be better off finding some C++ library for reading the image type you want (e.g. .PNG) and calling that code in, say, an Actor (Unreal's equivalent of GameObject) responsible for handling spawning.

    Comment


      #3
      I posted this on the OP's other thread, but I thought I'd add it here as well.

      Kowbell actually you can get at the pixel data for Texture2D and Render Targets quite easily from C++, obviously it is not recommended to do it every frame, but for everything I have used it for it works great.

      I would also make sure your images are stored with the UI compression setting, so you don't get compression artifacts.

      And Kowbell is right, definitely use Instanced Static Meshes or you will have a massive performance hit in terms of draw calls.

      Code:
          FTexture2DMipMap* MipMap = &Texture2D->PlatformData->Mips[0];
          FByteBulkData* RawImageData = &MipMap->BulkData;
          FColor* RawColorArray = static_cast<FColor*>(RawImageData->Lock(LOCK_READ_ONLY)); //LOCK_READ_ONLY
      
          int32 Width = MipMap->SizeX;
          int32 Height = MipMap->SizeY;
      
          TArray<FColor> PixelArray;
          FColor PixelColor;
          for (int32 y = 0; y < Height; y++) {
              for (int32 x = 0; x < Width; x++) {
                  PixelColor = RawColorArray[y * Width + x];
                  PixelArray.Add(PixelColor);
              }
          }
      
          RawImageData->Unlock();
      
          return PixelArray
      Last edited by Keiterheit; 04-26-2018, 02:14 PM.

      Comment


        #4
        Keiterheit Ooo, I've been trying to find that solution for a bit. That's quite useful. I'm curious, where did you initially find that? I missed it when I searched.

        Comment


          #5
          Wow guys thanks for the info and sorry for the duplicate post. The first one didn't go and reposted before checking the rules and realizing moderator had to approve initial posts.

          As to the solutions provided this is exactly what I am going after. However I have changed the concept slightly. Rather than having it all generate at run time, I would prefer to create editor script to speak that would generate the level in the editor, I make edits, and save the level. Save the level and then rinse and repeat and randomly choose the level rather than generating on the fly. I figured this might be better all the way around.
          As to combining the points yes I would agree, as my walls and everything are preset and I can figure out through simple math to determine when to display them.

          Any thoughts on the in editor generation method?

          Comment


            #6
            You certainly can call those generation functions in the editor. Just slap
            Code:
            UFUNCTION(BlueprintCallable, CallInEditor)
            on the line before you declare them in your header file and the function will appear as a button on the details panel. I think though it only works if the function takes no arguments, so you can just expose the necessary values with
            Code:
            UPROPERTY()
            and write some call-in-editor wrapper function that feeds those parameters into your actual generation function. Make sure you clean everything up properly if/when you regenerate, or you'll probably have to re open the editor.

            It'll be a bit tricky to work with the Instanced Static Meshes in the editor - you can't select individual instances and manipulate them with gizmos, as it will just select the whole component (and all instances.) If you're willing to make changes in the editor while the game is running, you could detect a particular instance being clicked on and then transform that instance essentially creating your own custom tools for editing the map. To preserve these changes you could save the map; that might be a bit tricky to do it as a proper .png, but you definitely could just write your ordered array of tiles/pixels to some custom binary file (see link below.) A potential plus to this is that you could include this editor in the game - you'd already be making it with all the necessary features you need to modify your entire map!

            Comment


              #7
              Originally posted by Kowbell View Post
              Keiterheit Ooo, I've been trying to find that solution for a bit. That's quite useful. I'm curious, where did you initially find that? I missed it when I searched.
              I originally found the solution from here in the forums and through other examples in Engine\Source\Runtime\Engine\Private\ImageUtils.cpp

              https://answers.unrealengine.com/que...texture2d.html
              https://forums.unrealengine.com/deve...rom-utexture2d
              https://answers.unrealengine.com/que...texture2d.html

              http://api.unrealengine.com/INT/API/...ils/index.html

              Comment


                #8
                Thanks again guys.

                Kowbell in the editor could I not just make them static meshes and then convert them into instanced once I am done with my edits?

                Also do you have any pointers on where to start learning how to use your own C++ code in unreal. My project is already a C++ project so imagine I am already setup to start writing my own classes and methods.

                Comment


                  #9
                  Originally posted by The Gugaru View Post
                  Thanks again guys.

                  Kowbell in the editor could I not just make them static meshes and then convert them into instanced once I am done with my edits?

                  Also do you have any pointers on where to start learning how to use your own C++ code in unreal. My project is already a C++ project so imagine I am already setup to start writing my own classes and methods.
                  You should have a <MyProject>.sln file in whatever directory you created your project in. Open that in Visual Studio (or whatever IDE you prefer) and go to town.
                  Able Ability System - A high performance, robust ability system for UE4. Now Available!

                  Comment


                    #10
                    Originally posted by The Gugaru View Post
                    Kowbell in the editor could I not just make them static meshes and then convert them into instanced once I am done with my edits
                    That could definitely work as converting them to instanced meshes should quite trivial. Of course depending on the map size you may or may not find performance hitches.

                    As for writing your own C++ code, as stated above you can open the .sln file to pull up Visual Studio and start writing code. I recommend you create your classes using the editor (Content Browser: Right click under the desired folder in C++ Classes) rather than manually in Visual Studio as creating them in the editor will add all the extra macros and some default functions you might find useful.

                    Some really quick pointers:

                    Placing

                    Code:
                    UPROPERTY()
                    on the line before a public variable declaration will expose that variable in the editor as well as to blueprints. Inside those parentheses can go a number of keywords that will change how the variable behaves in the editor and blueprints. For example, the default I use (bound to a macro on my keyboard):

                    Code:
                    UPROPERTY(BlueprintReadWrite, Category = "MyCategory|MySubcategory")
                    See https://docs.unrealengine.com/en-us/...nce/Properties for more details and a list of keywords

                    Similarly there is

                    Code:
                    UFUNCTION()
                    which does the same for functions. The default I use is

                    Code:
                    UFUNCTION(BlueprintCallable, Category = "MyCategory|MySubcategory")
                    See https://docs.unrealengine.com/en-us/...ence/Functions for further reference.

                    This forum is a good place to go for help, and the Discord (http://unrealslackers.org/) is very active and incredibly useful - a lot of knowledgeable folks there. Also, hot reload can be a hit or miss especially when making changes to your headers. If you're getting really odd behavior reloading your project is a good first step.

                    Comment


                      #11
                      Kowbell Holy ****! You are a god! You know it took a month for my first post to be responded to on Unity forums and the response I got then and every other post I made, always had the undertone of you just should not be doing this!
                      You guys here are boss and now I really see that Unreal wins out on the community as well! My first post and in 2 days I have my basic problems solved, and have direction to understanding the basics of what I am trying to do in Unreal.
                      As a seasoned IT guy I really appreciate the great help without the salty distaste of having another person learning how to write games.
                      Once again thank you, it is nice to finally be on a track of putting this game together after a year of fighting Unity Environment and the Unity Community. I feel like I have the tools and community around me now to achieve what I want!

                      Comment

                      Working...
                      X