Game development on .NET

Inventory and Store System – Part 1

dotGame
Inventory and Store System – Part 1
5 (100%) 1 vote
(Video Transcript)
Hi Guys. Welcome to the next episode of .GAME. In this episode, we’re gonna start preparations for an inventory/merchants store system that we’re gonna be building up. And that’s gonna take over several episodes. So this one is really gonna be about updating the way we’re doing navigation and so that we can path towards an NPC. And while we do that, we’ll take a look at a couple of properties, layers, sorting layers, and tags. Sorting layers and tags, we’ll talk about briefly, since they don’t really apply to what we’re gonna be doing here, but the layers will. So jumping in, I have the scene where we left off last, on our Navigation Part 2 video. And it’s still kinda pretty basic. We’ve got the merchant, and she can pass around depending on where you click. Actually, it looks like I still have a bug in here so we’ll address that bug. You can see when I click, there’s three positioning indicators. At some point, I lost my project and it looked like I’ve written the wrong thing on my update method.

So when I have Input.GetMouseButton down, what it’s actually doing is it’s triggering that, it looks like, three times where we only wanted to trigger it once. So we can change this by doing Get, instead of GetMouseButton, we’ll change it to GetMouseButtonDown. And we’ll do just the one, should do just one check. We save it and come back, that should solve it. So now you can see we only have one position indicator popping up, which is what we want. So the problem with how we have the set up is, so the way that the check works is we’re doing that physics Raycast. And it’s checking to see if it hitting a collider, which we have sitting on the ground. But when we go to check the person, there’s no collider, there’s no way to even identify that this is an NPC. Maybe we want different behavior than when we click on the ground. So that’s the first thing that we’re gonna end up building. And what we can do is we can work with Unity’s layers. So if you go under Edit > Project Settings, and you see there’s a whole bunch of stuff here, but we’re gonna look at Tags and Layers.

And you bring that up, there is a couple section, Tags, Sorting Layers and Layers. So as I mentioned earlier, we’re really not gonna dive into tags or sorting layers, cuz they don’t really have a purpose right now. But to kinda briefly explain them, so tagging is pretty useful to basically, uses the way to organize your objects. So, let’s say you have a bunch of NPCs. And maybe they’re organized by an armor NPC versus a weapon versus, I don’t know, a random one. You could tag them as a way of grouping, or if you had a set of goblin enemies, you could tag it as a goblin. And then when you’re traversing your hierarchy, your game objects, you can do some filtering to check the tags. Actually more practical usage of when I did this was when I was working on the AI in my game. And I had a bunch of NPCs driving through sections. It could check to see when I hit the player and do a conditional break point only if the game object that went through had that particular tab on it.

So it can be useful for both debugging and grouping, and sorting a set of game objects. Now, sorting layers is really useful for when you’re working with bunch of sprites. So basically what you can do, when you’re working with sprites any of your camera. What you’d end up doing to organize background image versus foreground versus the stuff in the middle is you can either scatter it by the transform of the object to space it out, or you can use sorting layers. And then specify on the sprite the layer ordering that it belongs to in order to register it without having to set some weird transform stuff, transform positioning, I should say. So again, those two don’t really apply for now, but the one we will work with is the actual layer. Layers are super useful in a few different scenarios. The first is rendering what the camera can see, and so to show you guys, we can set up a couple of layers. So we’ll set a ground layer, and then we’re going to set an NPC layer. So if I click on this game tab, this is basically what my camera is rendering.

I hop over to my camera, there’s this thing called Culling Mask, and right now it’s set to everything. If I were to check, well, I would uncheck NPC, nothing’s gonna happen because I’ve got to set my actual layer on my objects which probably do that. So if I click on Merchant and I go to Layer, and I set this to NPC. I’m gonna change all the children below. You see that it disappears. It’s still in my scene, but because we set the Culling Mask on the camera to not pick up the NPC, it dropped it. If we were to check it again, it’s gonna appear. So very useful if you wanna maybe isolate out some things from your camera for one reason or another. The other two scenarios that are pretty typical, so you can use it for lights to illuminates, to basically be selective about the parts that are illuminate in. And then the third is in Physics, Raycasts. And you can use it ignore colliders or create collisions. And that’s the one that we’re actually going to take advantage of. So, I’ve set it for the merchant.

I still need to set it for my ground in order for us to take advantage of this. So if I click on, let’s see if I back up, so ground can see that it’s selected. And I change this layer to be ground, now I basically have to everything else. So this is the NPC layer, this is the ground layer. Everything else is just assigned to the default layer which is layer zero. So if I come into the project where we had the code that we had written originally, we have our Physics.Raycast that’s happening. So the first thing that we can do is do a Debug.log and we can just check to see what layer we’re hitting. We come over, so there is no filtering this is literally kind of ray cursing and hitting anything that has a collider. So if I click the ground we can see that it’s registering as eight ,which is the layer that we set it to. If I click on this cave, which has a collider on it but we never assigned a layer to it, you can see it was actually registering as zero, which is the default layer.

Now where this comes in handy is we could do one of two approaches. We can either define in our Raycast a filtering of layers. Or we can let it hit whatever we want and then do a check with an if statement inside of it. So, I’m gonna actually combine both just for the sake of showing how you would do this. So, before we actually do that, let me add a merchant to my glider. So when I click the merchant, nothing happens, I’ll show you. We see that well, I guess that’s just say we’re seeing eight because it’s going right through it and hitting the ground. It’s not registering that there’s anything there and that’s because the merchant have a collider, which is required when you do Raycasting. So, it’s a pretty simple fix, we’ll just add a box collider. You can kind of see down below at our feet that one got added, and if I hit Edit, you can see the boxes. So, you have a choice, you can either kinda drag and position it, or you can just enter in these values which is what I will do.

Position. Here we go. So now there’s a collider around it, and if we go and click, you can see that it registered nine. And nine was the layer that we had assigned to the NPC. You can also see are character path up to it and completely and utterly invaded the personal space of are merchant. Which is a behavior that we don’t really want, right we want the player to kinda walk up towards it, but stay at a health distance away. So, we’ll wind up tackling that, and that’s why we’re gonna do special logic inside of this Raycast, cuz we want a different paper. We hit the ground, we want the player to walk up to exactly where we hit. But if we’re hitting merchant or an NPC, we want them to walk up to a point to a distance away. And then, we’re actually also going to rotate the character to look at, the NPC. So jumping back into the code, we’re gonna take a look at the first thing that I described, which is essentially adding a filtering value to our initial Raycast. And you can do this by doing something called, bit shifting, so the Raycast function takes a bit mask.

And so to shift, we basically would do int layer, mask and then one and then whatever layer that you want. So, to start we’ll do ground. Just to kind of Just to describe or to show this a little bit. So jumping into this area. Here, layerMask. They come over here, if I, If I click on the ground, we’ll see that it gets reported out. If I click on the merchant, we’ll see that the ground is still getting report in. And then collapse this since it’s six times but they’re all in one. So no matter how many times I click that merchant, this is going up, but it’s not triggering. And that’s because the filter is actually happening on just the layer. So the way that you can chain multiple layer masks is using the pipe. So we can essentially do that. And what that’ll do is that’ll say, okay, I wanna pick up layer eight, and layer nine, which is ground and NPC. So again, ground is showing. I click on the NPC. We can see that that now registered. So we’re filtering out both of those.

So if we were to tack on and build up our colliders and our layers, this would let us at least filter down on those two. All right, so now we’ll do the code for when we hit the other layer. Which we can do in else statement because we know our other layer is going to be an NPC. You say this has some flaws if you were to build on it a little bit more. Okay, so what we’re gonna do is we’re still gonna do that same move call with our navigation. But we’re gonna alter it a bit to bring our character in front. So we’ll pull out the x. I do this in a really weird way, actually. Some reason I was gonna separate it out. But you don’t really need to do that. And I think I started to code it one way and then changed it. So we can just do hit.point. And then do transform.forward * -4. Now, you don’t need a new vector actually. There we go. That should be right, I think. We’ll see in a second. But basically, what we’re doing this we’re taking the point in which we hit. Which we know will be the NPC, somewhere on the NPC.

And then we’re grabbing the forward rotation or the forward position of the merchant. And then we’re going to multiply it by -4 to bring our character out, to stop it at a gap, essentially. We might have to increase this. You know what, let’s just increase it to 6 hit. 4 might be still a little too close. And then let’s do, Just log that we clicked on the merchant. It spells there. All right, let’s see if this works the way that I think it’ll work. All right, so we click on the ground, we see we’re moving. Click on the merchant, we see that it logged that we clicked on the merchant and we pathed up to It. So good way to watch the effects of this is if we were to stick another merchant out on the scene. So again, I hit Ctrl + D, I think right here to duplicate it out. Then we’ll just ping pong between these and see. So we’re pathing up. We path to the side, we stop. And same thing goes here. So this is good, but what we’re missing is really a rotation. What we want is two things to happen.

We want to path up, or three things, I guess. We wanna path up like we’re doing. Path at a distance so that we’re not invading our merchant’s personal bubble. Then we actually wanna rotate our character so that it’s facing the merchant. And then the other thing that would be good is to have the merchant rotate back to facing the character. So if we happen to stop right here, the character would rotate, face the merchant. And then the merchant, who at the time, when we start to hook up the UI, we’re gonna zoom in and show a little dialogue that’ll pop up that’ll show what the merchant has to sell. So when that happens, we also want the merchant to turn and face the character. Otherwise, you just look like, in some scenarios, that you’re talking to the back of a merchant, which isn’t a great user experience. So we’re gonna tackle in this video, the first half. Which is the navigation which we’ve already done. But rotating our player character to face the merchant. So that’s what we’ll do right now.

So if we jump back into our code here. We’re gonna do a couple of things. So we’re gonna track a few things. So I can do that, so put that on there. Technically, it’s doing the underline part two, but currently, we’re skipping that. So the first thing we’re gonna do is track to see if we’re moving. And if we’re moving, basically, if we need to rotate. So the reason I’m calling it andNeedsRotation is because if we click somewhere, but we’re not going towards an NPC. Technically, we’re moving, but we don’t need to rotate. We don’t care what direction the character is facing. It’s really they need to face just whatever direction they’re coming in at, so it’s fine. So we’re not always going to need to worry about rotation. The other thing we’re gonna do is we need to track where it is that we wanna rotate to. Because we’re gonna pass this into a method. That’s going to actually handle our rotation. So coming back into our code, We’re gonna do a couple of things. When we click on the NPC, that’s when we’re going to turn.

And that’s actually really where we’re gonna set our npc ToView. And we can get that from our hit. So our hit has a notion of whatever transform which we can also dig into the game object specs based off of what we click. So we can just pull the transform out of what it is that our Raycast hit. And then feed that into our npc ToView for us to access later. And then what we’ll do is start the movement. And then we’re gonna set this to true. Now this is going to come into play inside of our update method. We’re gonna have a check for this. And I’m wrapping this in a check because you wanna be very careful when you’re doing update loops that you’re not calling too many things needless. So I could basically do this rotation check. And nothing’s really gonna happen when it hits the rotation because it’ll be done. So there won’t be anything new to look at. But I don’t wanna constantly ping and do the calculation for that check if I don’t have to. Otherwise, it just bogs down the system.

It can definitely add up and take out your game in terms of performance. So what we’re gonna do is we’re gonna create a new method called RotateTowards. And in this method, we’re gonna do few complicated things. So we’re gonna check for the npc ToView. Actually, normalized. So basically, what we’re doing is we’re establishing our direction. Which way is it that we’re trying to look? And then we’re gonna do quarternion. I totally called it quarternion, quaternion. I always get made fun of for that. I don’t know why. I look at it and I think it should be pronounced differently than it really is. What we’re going to do is we’re gonna call a method called LookRotation. And so quaternions are useful. And that’s to help you with rotation and orientation. So Unity as a whole has basically two ways that you can essentially deal with rotation and orientation. So one is quaternions, and the other one is Euler angles. So they each have their pros and cons. The recommended way that you work with rotation and orientation is through the quaternion.

And the Euler angle is why you can access, then they actually can have some significant drawbacks. So Euler angles are the simpler representation. They’re the ones that show the x, y and z values. So when you look at the inspector inside of Unity, and you see history values. You’re looking at the Euler angles because it’s a little bit easier, more simple to represent. So they suffer when you edit the properties from something called the gimbal lock. So, basically, what that is is when you’re applying three rotations, it’s possible for the first and the second to result in the third access pointing in the same direction as the others. Which basically kills the degrees of freedom. In that the third rotation value won’t be applied on a unique access. So you can basically have just unpredictable experiences when working directly with those. Now quaternions, on the other hand, so they represent the orientation or rotation of the object. And the goal with how Unity has wrapped it up is that you never modify the individual x, y and z properties.

But instead, you end up using helper methods or helper I guess methods or functions, if you will. One of those being the one that we’re looking at, which is this lookRotation. So we’re actually gonna work with lookRotation. Angle is another one which will allow us to do a calculation. And then we’re gonna do something called slurping. Which I’ll describe as we startt to hit that point. The nice thing about quaternions is they do not suffer from [INAUDIBLE]. So that scenario that I described won’t happen. But that thing that’s not so good about them is that they can’t represent a rotation that exceeds 180 degrees in either direction, whereas the Euler angles can. So there’s drawbacks to both, and Unity has a set of documentation and best practices. I’ll link to it in the video. But they even have a section that describes kind of bad practices that you can end up doing with either one. Okay so, jumping back in, so again we have the lookRotation. So we’re grabbing basically the direction.

And then what we’re gonna do is we’re actually gonna do the rotation. And we’re gonna do that, I kind of alluded to it, with the slurping rotation. And I need to define speed. So speed is basically just essentially how quickly we’re gonna be rotating. So we’re gonna make it so we can pass in a value and that way we can kind of mess with it if we don’t like what it’s set to. You can actually even make this a little bit more generic in that you could pass in the object to look at through it. Instead of setting it like I am up above. So for example, if you wanted to make the merchant also rotate back, you’d probably make this a little bit more generic. So that you can maybe call it as a helper method on either side. So you maybe pass in the object that you want to rotate as one parameter. The object that you are looking at in another parameter. And then of course I’d still probably do the speed so that you can kind of tweak it depending on what you are looking at. So you can make it a little bit more generic.

Which is a hint, or is the challenge I’m gonna give you towards the end of the video here. [LAUGH] So let’s see, so we have this. So basically what this is gonna do, so slurping is something I hadn’t really talked about yet. And basically what that stands for is a spherical linear interpolation. And [LAUGH] basically, what that means is because we’re calling this an update. So this is gonna happen every frame. Each time we’re gonna slowly continue to rotate towards our object. So it will be kind of a slow thing. And I’m thinking if there’s a good way to demo that. You’ll see it rotate. I guess what we can do is just remove the conditions so that it checks as false. And basically what you just see is this would trigger once. And it would maybe, if we called it once you’d move slightly. But then it wouldn’t continue because it’s checked that you need to actually have every single frame in order to create kind of a smooth animation, if you will. So, what we can do, is illustrate the next thing that I wanna show you.

So we’ll call this and we’re gonna rotate to float. So we’ll go, and what? I think I’ll do Debug.Log. Yeah, I’m thinking we’ll do. So, what you can do is you can check the angle between two rotations essentially. And so what I’m gonna do is I’m gonna debug out the angle that’s between our transform, so our player and their rotation. And then basically our target lookRotation. And you can kinda see, so we haven’t shut this off. So this is gonna continue to run every single frame. Because we’ve set it to true but we haven’t actually turned it to false. And that’s okay cuz I wanna kinda illustrate this, the fact that it would run as frequently as it will. So notice a couple of things here. I have collapse, which basically means any like messages are gonna collapse into a single line item. And you’ll see this number kinda go up. So, the problem with this, of course, is that as we near the target, it stops right away, i some scenarios I guess. Because the rotation is less than one when it starts.

So If we were to have this as false, this wouldn’t trigger. I guess you can see a little bit better if we go debug, or not debug. We do the false. So doing this You can see that she doesn’t trigger. So really what we we wanna do is a distance check in addition to this. So we wanna make sure that we’ve reached our target and that the rotation has been completed. So you can do this by doing a Vector3.Distance and then passing in to calculate. So we have a transform.position and then our npcToView.position. And then because I checked this a little bit earlier I happen to know that we wanna check under eight. But really what you could do is just Debug.Log this out and watch kinda where it is going. So basically we’re doing two checks. Is our rotation complete? And then this will solve if our character is kind of loosely pointing towards it, but we’re nowhere near it. And then this also confirms that we’ve reached our right distance. So we push Play and we click on our merchant.

We’ll see if she gets to it. She navigates and she’s looking kind of at the character. So that’s ultimately the type of logic that we wanted for this particular episode. So we’re gonna go ahead and stop here. And in the next one, we’ll start to move towards building out the inventory systems. Since we have our character kinda walking up to it. So I had some folks kinda ask for challenges or things to kind of go and explore on your own. So the challenge for this one that I’ll give you is, I kind of alluded to it a little bit earlier. But it’s getting the merchant to also rotate back and look at the characters. So the methods that we took a look at today would basically aid in that. So on the GitHub Repo, when I go to post this project I’ll actually post how I would solve the problem. So you can go and take a look at that if you I guess are curious on how I did it. Or if you’re stuck and just want to take a look. So, thanks for joining. I’ll see you next time.

 

Read the video

In this episode, we continue our RPG project with the next goal of building an item system which will also be used for equipment and merchant functionality. To prepare for the system, we’ll go over more Unity fundamentals, like methods of object rotation, filtering, tags and sorting layers.

Resources


dotGame

dotGame is a blog dedicated to game development with a primary focus on .NET technology. The episodes will focus on tutorials, tips and tricks and interviews. All tutorial project files can be found on the .GAME GitHub repository. Have a topic you'd like to see covered? Great! You can request a topic by opening an issue on the GitHub repository or by emailing dotgame@microsoft.com. General feedback can also be directed to dotgame@microsoft.com.

    Comments to Inventory and Store System – Part 1

    • Great show but I wish you had a better microphone, the audio has been pretty bad in each episode and it makes it hard to watch.

      Niner148239 January 28, 2017 2:59 am Reply
    • thanks for not trying to be a movie star but programe writer.

      Niner17540 January 29, 2017 3:03 pm Reply

    Leave a Comment

    Your email address will not be published. Required fields are marked *

    Loading...
    1Code.Blog - Your #1 Code Blog