Procedurally Spawned Characters

I just wanted to say, that I got procedurally generated with quests with quest objectives and rewards that are also procedurally determined AND that also save their own state working in less than a day after you responded to me. Thank you so much.

I tried to do this back in August and forget about saving state, I couldn’t even figure out the proper data structure for playing a live game. I spent days and I kept confusing myself. Using this guidance with instantiating scriptable objects at run time and marking them as “instances” was a HUGE help. Again - done AND with state saving in less than a day when prior attempts took days with nothing to show for it.

This builds on top of the procedurally spawned enemies from RPG.Dynamic. They are spawned as part of these procedural quests. I also have enemy levels that are procedurally determined and based off a delta of the player’s current level.

Since my game is educational in nature, I will now using these techniques to dynamically create educational content (not just quests/enemies) based on how well the player is doing. The strategy pattern I learned in SAB is very helpful here.

In the course of figuring this out, I noticed something interesting about how you are serializing and deserializing in JSON and posted a separate question.

For anyone reading this and new to Unity/C#, my recommendation is to take all 4 RPG courses and also do a few of Brian’s tips and tricks before trying to go too far in customizing your game. The stuff you learn doing that will make later customizations so much easier and faster.

Again - thank you so much!

1 Like

Brian,

I think I found another bug here with the CreateDynamicEntity() method you provided. If the dynamic entity to be created has a NavMeshAgent on it, the position you set via entity.transform is not retained.

I initially didn’t notice it because I was using random location spawning in a wide range of the scene. But then I moved to spawning within regions of the scene and noticed that my distribution of spawned entities was not as intended.

I initially thought I had an error in my random point generation logic but then I noticed something weird. In the Mover script of the newly spawned entity, I could see the specified location from CreateDynamicEntity was present in both Awake and Start but by the time of the first Update() it was completely different. It was also different in a semi-reliable manner.

I made the code change below and it seemed to fix it.

        public DynamicEntity CreateDynamicEntity(DynamicCharacterConfiguration configuration, Vector3 position, Vector3 eulerAngles)
        {
            if (configuration == null) return null;
            DynamicEntity entity = configuration.Spawn(transform);
            if (entity == null) return null;
            entity.transform.position = position;
            entity.transform.eulerAngles = eulerAngles;

            // note this change
            var agent = entity.GetComponent<NavMeshAgent>();
            if (agent != null)
            {
                agent.Warp(position);
            }
            // note this change

            RegisterDynamicEntity(entity, configuration);
            return entity;
        }

I can see NavMeshAgent bullying it’s way into disallowing the move directly. Warp is the correct fix for this.

1 Like

I’ll try this tomorrow

OK I was just scrolling through (I know I’m supposed to be fixing my OnAnimal rotation issue first), but… HOW DO YOU MAKE PROCEDURALLY GENERATED QUESTS…?!

Like, what’s the logic behind them?

OK Genuinely curious, what’s the benefit of this system over the fixed entity? All I really wanted was a way to spawn characters outside of the player’s radius, for example cops or people when you enter a new town or something (something to keep the game computationally light), nothing more… :sweat_smile:

Well well well, if I didn’t go through this with Inverse Kinematics and Quaternions in my own version of the game recently…

I’m reading through trying to understand what’s going on here, but all I see is advanced words that my (somewhat) inexperienced brain is struggling to understand :confused:

I still don’t know how will this correlate to the police chasing system that I want to create, but I’m trying anyway

Here’s what I want to integrate. It’ll be similar to the one in Grand Theft Auto. In other words:

  • Get them to instantiate from a distance, preferably if they’re out of sight around a corner if there’s corners. This will add a bit more realism to the pursuit, because he won’t spawn out of thin air in your face
  • (Preferable, but not necessary): potentially give them a random combat level, and random weapons and/or random armour
  • Their goal would be to come at you and try to kill you when you’re close

I don’t really care much about part 2 tbh (if it comes down to it, I’ll assign them their weapons and create multiple versions of them), although it would be nice, but it’s not mandatory. Part 3 is already done (if it wasn’t done by now, then something is concerning)

I think all I need to achieve now is just part 1, but I’m still confused why I’m here…

I’m trying so hard to correlate to how this would relate to what I’m trying to do, but so far I see only little benefit

I’m not saying it’s bad, but please guide me and tell me why am I doing this? Because I, for one, am confused

I’ll leave what I created for the dynamic saving system for 24 hours from now, and if I still get no response I might delete it and try something else :stuck_out_tongue_winking_eye: (because I don’t know why am I even doing this… :sweat_smile:)

And someone please respond and break my “You can’t answer yourself for more than 3 times” curse

Edit: I don’t think I read long enough, because clearly @Cat_Hill had some long term ideas in here. Maybe they just don’t allign with my needs, as I want to hand-craft my own game world instead (I just need a wanted level system. I think my only needs when it comes to dynamic respawning is having enemies pop up when you enter a region (Pirates, for example, when you enter dangerous waters (this will probably be in my final product), or cops when you commit a bad crime))

hey wow. Nice to see this thread (and the one you linked @Bahaa) help someone.

I will say that since ~Feb 2024 I have scaled back my effort on this. Combination of other commitments, technical challenges, and my own limited technical skill set. One challenge I faced was that my game was very heavy in terms of content (images, photos, videos, etc) and that some of the assets I purchased on the asset store had some painful quality issues which required extensive workarounds. I plan to come back to it later this year after I free up and after I scale back the design. But I can help answer questions if you get stuck.

First off did you find this post of mine? It doesn’t address your full need, but it can get you started with a part of it.[Spawning Characters on A NavMesh]

Something like this would be useful for my game though I haven’t built it yet. You need to do a little bit of math but it’s really not that hard if you have some solid fundamentals. Can you answer these questions and I can help you with it.

  • What camera view are you using? Top down? First person? Diablo like?
  • Can the camera point in any direction?
  • Can the camera rotation change relative to where your character/car faces? e.g. can you see the front, side and back of your own car/character?
  • Do you want to continuously spawn enemies or do you just spawn one tranche per spawn trigger?

My game is academic in nature so I needed the ability to scale up the challenge as the character progressed (i.e. got smarter and got stronger). My procedural spawning not only affects the enemies but the academic difficulty. This was really the make or break feature of my game so I went deep on it.

My system allows for hand crafted levels. My procedural spawning is designed to focus on characters and interactable items within a or any given level.

This is not too hard if you already can generate random weapons and armor. Brian’s Spellborn codebase for his own game shows you how to generate items with random stats.

One thing you will have to consider is making sure you scale the game’s difficulty appropriately regardless of the level of your character. I implemented an enemy rank system to deal with this. So in effect one could just spawn enemies that are the same level as your character and let the “rank” take care of applying buffs and debuffs to keep things playable.

The RPG course shows you how to do this. Have you gone through the full course?

Oh there’s a lot to discuss here… Alright, let’s start:

Haven’t found that if you didn’t mention it. I got a bit tracked off to reactivating some homing systems in my game, and because I have a unique system of mine that is 300% off the entire RPG Course, I’m facing my own Unique challenges

Two words: Cinemachine FreeLook (The long version: Circular FreeLook camera, it can point in any direction, yes, I spawn one per trigger. I have my own ‘RespawnManager.cs’ system for that, and whilst it would make sense to me and you, you may have to tune it to get it to work for you too)

Honestly? I don’t want to go that path with this game just yet. I want to go the traditional path where I hand-craft and manually control the existence of everything

I tried this before, didn’t work, so I quit it and decided to make traditional weapons

In my honest opinion, not every new idea is something I’d be willing to try, because I believe there’s value in old stuff as well :slight_smile:

I did a whole lot more than that. I taught them to find their way around obstacles too. It’s not super-effective just yet, and I need to debug that down the line


Just so we’re clear, my game looks absolutely nothing like the RPG Course (anymore). Here’s a quick video to show you what I’m developing (P.S: It was all following up from the RPG Course, but then I did my own modifications. No UI Changes have been done yet, as I’m hard on mechanics right now. Once I get the mechanics correct and running as expected, then I can modify whatever I need to modify down the line):

https://drive.google.com/drive/folders/1Z6ljX2Bp_8vp-sa9LVwUvCxrJk80kEnL?usp=sharing

From a high level you need 1) the vector of the direction the camera points 2) to know your field of view.

I don’t know if it will be appropriate in your case, but a simplified version might be

  1. Precalculate the cosine of your field of view. Round down. E.g. if it is 45 degrees then you would get 0.70
  2. Project the camera vector to the ground (zero out the Y component if the ground is always at 0). Look up how to do projections if you’re not familiar with this and if ground has variable height.
  3. Normalize that vector
  4. Generate a random spawn point (or pre-generate a number of points if you want to prioritize points that are right around corners)
  5. Compute the vector that points to your potential spawn point. The starting point needs to be identical to the “start” of your camera vector as projected on the ground.
  6. Normalize this second vector (and save the distance amount in a separate variable)
  7. Take the dot product of these vectors.
  8. If the dot product is less than what you have in step 1, then the object is almost certainly out of your field of view.
  9. Make sure the distance computed in the prior step is higher than some threshold. (this threshold may need to be variable if you allow your camera to go overhead)
  10. If preceding step is yes, then you’re good to spawn in that location. if no, repeat step 4 and try again with another point.

In general this will always spawn an enemy out of your field of view. There are going to be a few gotchas to this depending on exactly how mobile you allow your camera to be. For example it may not work if you move the camera rapidly.

What I have above is also somewhat limited in that it won’t spawn enemies ahead of you and behind a corner. That’s a bit more complex than what I have here but you don’t need IK to solve spawning enemies ahead of you and behind corners.

If your scenes are always like street corners (90 angles with full occlusion around the corner) and you avoid far overhead camera angles and if you have predefined spawn zones just around corners, you can solve this advanced one without too much difficulty.

Ahh there’s a lot to decouple here. Once I get the new Projectiles Issue (it’s a personal one, because homing arrows from my brand new Ranger Aiming State don’t know how to act like homing arrows yet) dissolved, I’ll investigate this one

Just let me dissolve the weight of knowing that I got parts not working yet resolved first :stuck_out_tongue:

Feel free to post a new question on any of these other topics (to not clutter this thread). I’m pretty familiar with some of the issues you’re encountering and many of them have easy answers if you know where to look.

Decouple or digest… or unpack maybe? :slight_smile:

It would not expect the above suggestion to aggravate or cause coupling issues but I guess anything is possible.

Yeah things can get quite tricky with projectiles, projectile paths and collision detection. :slight_smile: If you have a subscription to something like ChatGPT, I often used it to help me find bugs. It wasn’t that great at writing code, but it was pretty good when I gave it my own code and asked it to find what was causing a certain type of bug.

Also - the math in 3d space usually has an easy answer so happy to take a quick stab at any of those kinds of questions. (Though I’ll admit there was one part of this course - finding a point off the ground in line with where you clicked that was surprisingly tricky despite having seemingly easy geometry).

Again feel free to post a new question and tag me if there’s anything math related. I’ll attempt to answer anything if it looks like it has an easy answer.

@Brian_Trotter will kill me for saying this, but… I do use GPT (GPT 3.5 though. I think 4 is an overkill, and it doesn’t do my designed tasks that well tbh… and I’m broke :crying_smile:)

I think I know how to solve this one though. Let me just give something a go, and see if it solves the problem :slight_smile: (it probably won’t, though, now that I think about it)

Solved the bug, but it’s almost midnight here… in the morning, I’ll give your suggestion a run :smiley:

last 4 days were the nightmare of unlocking the ranged weapons with the new third person system, combined with fixing my laptop that suddenly started running insanely slow, but I won’t send it for repairs because I don’t want anyone doing anything dumb… I’ll give it a run today

Let’s see what I can come up with :slight_smile:

Edit 1: Another delay… fixing bugs (AGAIN)

Nah, even I have given in to a little bit of AI madness… In my case, I use JetBrains Rider, already the best and most intelligent IDE in the C# world. They now have their own AI to answer questions and take care of boilerplate code. Because it’s trained specifically to work with C# and Unity, I get better answers in most cases (it still makes booboos from time to time). Don’t ask it how to bake a chocolate cake, but it’s a pretty good AI.

1 Like

Ehh I just need a companion by my side when things hit the roof

But eventually I learned that having a good friend (friends in our case) who understands the architecture just as well as you do is invaluable, because AI doesn’t know everything, especially with how our architecture works

Speaking of Jetbrains, I’ll probably check that soon as well. I’ll need the extra help too :grinning_face_with_smiling_eyes:

I’ve been using Rider for about 5 years… The great news for me is that I get a loyalty discount on the fee, the longer you use it, the more the discount. It’s a paid editor, but there are some things that are worth what you pay for them… VS Code is… Free… JetBrains is… $$ They’re both worth what you pay for them.

what does it have that VS Code doesn’t, which may be valuable for us? (I’m doing something else right now irrelevant to coding, and it’s taking its sweet time :stuck_out_tongue_winking_eye: )

A) It always works
B) It handles namespaces pretty much automatically if you create the script in Rider rather than creating it in Unity.
C) Automatically lets you open the source (via decompiling) of most Unity and virtually all standard C# functions.
D) Better code suggestions
E) XML comments (the ones with the //Summary, etc) actually work.
And many many little minor things that just make your life easier.

I was about to text you to have a quick review of my latest ‘DynamicNPCSpawner.cs’ script :sweat_smile:

Wait for my text :slight_smile:

Privacy & Terms