Jump to content

Rick

Members
  • Posts

    7,936
  • Joined

  • Last visited

Everything posted by Rick

  1. Got that to work. This is a balancing act doing it this way, since using Curve creates a sliding effect as you move. To little value and jitters show up, to big of a value and the arms slide too much from controller and it looks strange. I think being able to get cool and realistic camera movement with certain animations will be worth it though.
  2. Hence why I said maybe nw.js could be used for this. Still used offline with the ability to check if it can refresh it's data if online and download and save the updated files locally. Something plain html/css/js couldn't do very well. Using local storage wouldn't be ideal for this. Not to mention that your environment is now stable and known for documentation. No screwing around coding for every web browser under the sun. You know how it looks on nw.js is how it'll look for everyone always. It's basically a better chm system because it allows you do code to pull changes when online but be able to still view it when offline.
  3. I need the arms to be the position for the camera though. The arms use the controller for position and the camera uses the arms for position. So positioning the arm height relative to the camera doesn't make sense in this context as the camera needs to be positioned to the arm head bone for our effects. I tried using curve to smooth the arm position from the controller but that still resulted in jitteing.
  4. I have first person arms model, controller, and camera. The first person arms model has a bone where the head would be. I position the camera to this bone. That works great. However, I then set the position of the arms to the controller position (raising the y up some), and this makes the arms jitter. It would seem the controller jitters pretty bad, even when not moving. How can I hide this jittering on my arms if it needs the controller position to set it's position and that position jitters like crazy? We want this setup so the arms animations control the position (in certain situations we have the camera rotation set to this bone rotation too) so we can do some interesting animations to move the camera and make more realistic camera movements in certain situations. Think player crawling through a window, having the camera position/rotation being on a bone allows the animated to get a more realistic feeling and during this activity we'd remove control from the player in moving and rotating the camera).
  5. The beginners are looking for something easier than Unity which seems daunting from the outside and the experts are tired of Unity's issues so they are looking around. The middle is still putting up with Unity's issues.
  6. That's nice but at first glance it seems like it won't be enough value to charge for. I was just thinking about how leadwerks can get more revenue streams going so that you could hire people and expand the business given the comment you seemed to have made on the hangout about if it was a monthly charge you would have been able to do so.
  7. Yeah if it's the mobile VR support, which it didn't seem like it was, then I get it as you'll have the numbers because it's cheap. If it's the big vendors then you'll have less numbers. Remember an LE license cost the same for everyone so Josh needs quantity of users to make money. That was the issue with mobile support. Very few people bought it and it didn't seem to drive in new people either. If regular mobile didn't how is big vendor VR going to drive in the qty? The reality is when you don't charge royalties then you are selling dreams to people who don't know how to make games. There are a lot more people who don't know how to code or do art but want to make games. It's basically a large % of gamers that fall into that category. If you add mobile VR on that then sure I get it but the big vendor VR I have a hard time seeing that being a big factor in profit.
  8. Doesn't the equipment that josh is targeting cost like $800+? That's a heavy investment right up front for such a market where those people are already buying consoles at similar costs and gfx cards at half/quarter the cost every few years. VR has traditionally always been fools gold. Unless he's targeting mobile VR devices, much cheaper, it would seem surprising that the big VR vendors is the bread and butter. As for the first part that's what my statement means. How many people pass up,on buying LE because it doesn't support VR? I know Josh mentioned upgrading certain things for PC gives VR for free and that's nice but will adding VR mean josh can hire more employees? If not then we have potentially a worse LE experience as this is another area to take Josh's focus away.
  9. Josh wouldn't be the one making these. He'd partner with a person/people who do want to make these. If anything it would probably advance the engine as it's another revenue stream as josh takes a % of thier sales and can now hire an employee who can make LE features that those other specific engines are requesting. He can focus on what he likes doing which is the generic systems for the generic engine. It's basically like he's franchising out the engine while still maintaining LE itself and has a say in the other specific engines.
  10. We're obviously exploring an idea I'm sure josh will never do but the way I'd see it playing out is josh is teaming up other people who make these products so he's not the one working on them so he'd still work on LE. However those people would give josh a % of thier sales in return for access to the LE editor source and top priority on feature requests. It would also be known that those specific engines use Leadwerks at its core. It seems like a win win. There are people who want to make specific games but the idea of starting from scratch with a generic engine just scares them. They aren't programmers or artist, they are game designers. They enjoy working with dialogs to configure thier game. So they most likely aren't buying LE anyway. So josh picks up a portion of those sales. Eventually those people want to maybe try thier hand at another genre so they buy the RTS engine perhaps and josh gets a portion of that sale. Then after years they build up enough knowledge and currage to try LE engine itself so he gets that sale. It's like holding a persons hand as they go on thier game development journey in life. An RPG is a daunting task even for the most seasoned devs here. Having an engine that has all the same level editing LE has but specific systems and configuration setup for an RPG game is a big value. I'm sure a decent number of existing LE users today would buy that too honestly. By the sounds of it josh is struggling to expand the company. He needs a different or more revenue streams. He seems to be hoping VR will do this but given the cost of VR stuff it seems a novelty at best in my opinion. How many people are not buying LE because it doesn't support VR and is that number really a game changer in revenue? I think the number of dreamers who don't know code or art far outweighs the VR crowd.
  11. What a boring world it would be if competition didn't exist . If josh had that mentality he never would have created Leadwerks. There is always a way to do something different/better.
  12. The whole reason for not charging for upgrades was because the workshop was supposed to cover that. I guess it's not? It's tough coming up with ways to make people part with their money when a good number of engines do it with royalties which seems like free at first. Perhaps a monthly service is a good way to generate income. Not for the engine itself but for some other kind of service? $5/mo for "basic" support, $10/mo for "premium" support from Josh? Perhaps charging for add-on utilities for the engine? There are probably some nice to haves but not required things that could charge for. Behavior tree's and visual editor would be one of those. It's not required but is a nice to have for some games. There are probably other things like that too. I've said this before but personally I think Josh should make specific noob friendly engines based off LE's API. Much like how RPG maker is a specific game maker based on PIXI javascript library. It adds an editor that's pretty much specific to RPG's. Josh could do that with all genre's really. I know Josh said it's not his dream to do that but it probably is someones dream to make an 3D RPG maker so if he could get one person for each genre to do this for a promise of a % of the sale and he helps them out where he can he could have multiple revenue streams coming in from that. Leadwerks would be the HUB engine serving these different specific engines. People like specific things and are willing to pay for it I think. Josh would probably just have to give the editor source to these people so they could create custom dialog's and adding/removing features for that specific genre. Then their requests for engine features would take priority for Josh and Leadwerks as a whole would benefit from it in features. I would imagine RPG Maker is the first step before they try their hand at a simple and friendly 3D RPG maker that LE could be the backbone of. I don't know, seems like a win/win if you get the right partners.
  13. @Jen, look at the time difference in Josh's "It's up" post and yours right now.
  14. I would think this might be a good case for nw.js? Store the information locally but do a check for update process with it to call an API to get the updated data? Controlled web environment so you know it'll look the same for everyone vs browser of the week. Just a thought.
  15. I thought we had avoidance with pathfinding before?
  16. You could use an event system. I have a small event class. Your KeyCheck could be a global table that has onKeyHit event. Then inside the scripts you need you include the table like you're doing and you bind that scripts function you want to have called when onKeyHit is raised. The event code allows binding multiple functions from any object. Then your KeyCheck would have an update function that looks for key hits and raises the event which in turn calls all the script functions you bound to it. Then call that KeyCheck:Update function in the main.lua files main loop. The benefit is that you aren't polling in each script so it'll be faster as the more scripts you add what your currently doing the more checking that happens. It also only ever calls the hit functions once then to solve your current issue. Kills two birds with one stone! Usage is inside your table that handles key presses: self.onKeyHit = EventManager:Create(self) To raise event self.onKeyHit:Raise({ key = key}) if EventManager ~= nil then return end EventManager = {} function EventManager:Create(owner) local obj = {} obj.handlers = {} obj.owner = owner for k, v in pairs(EventManager) do obj[k] = v end return obj end function EventManager:Subscribe(owner, method) table.insert(self.handlers, { owner = owner, method = method }) end function EventManager:Raise(args) for i = 1, #self.handlers do self.handlers.method(self.handlers.owner, self.owner, args) end end
  17. @AggrorJorn Yeah for sure. I was thinking about how when a person is new to game dev or coding this is a hard concept to convince a person to use. It's not straight forward and seems like overkill UNLESS the person feels the pain of the more brute force way of coding themselves. You allude to this in your blog post on how Josh isn't a fan of stuff like this and is a more direct programming person. Direct programming I think is the best way to teach a new engine for sure as it gets to the meat without any kind of framework around it, but once a person gets those basics they generally quickly see how unruly and complex to maintain direct programming can be. As soon as a persons game starts becoming more complex and they see how fragile their brute force way of coding becomes then they either give up, thinking it's their fault and they just can't do it game dev, or they start searching for a better way to structure their game. So I feel like really explaining WHY coding this way is so important. Otherwise it can just seem like unnecessary complexity (even though in the long run it's less complex). It's a hard concept to get people to understand why they need it if they've never felt the pain.
  18. Just because I like talking about this I'll give my mindset with component design when I need to add a new feature so others can see the thought process. In our game the player can get drunk. That's the feature. Now we start breaking out how to add that feature to the game. First, this instantly becomes it's own component I call PlayerDrunknessComponent. It manages what getting drunk means. I then think about if this was a library on it's own how would I handle it. Well I would have a Drink() function that's for sure. But maybe different drinks affect how fast you get drunk. So I would probably pass an argument to the Drink() function that tells me what the drink is. I can now test this on it's own which is nice. I then think about what would I like this component to tell the outside world? Well the functionality I want is that we have different drunk levels. Maybe 0-5. Every 2 beers raises the drunk level by 1. So I should probably tell the outside world every time the drunk level changes so I'll have an onchangeDrunkLevel event. So now I have a way to get drunk with my Drink() function and I can tell the outside world about my drunkness. At this point the PlayerDrunknessComponent is completely self contained and ignorant about the outside world. Then I start thinking about what will call this Drink() function? Well my inventory component has an onUse event that passes the item that is trying to get used. That seems like a great way to get drunk right? So I hook up the inventories onUse event to my Drink() function. Now I may have to go back and refactor the params since events will send 2 arguments in my case (the sender of the event and 1 args table that holds other data specific to that event). The interesting thing is how is the onUse event of the inventory getting called? I don't care right now. I just know it's called when an item in the inventory is right clicked because that's what I deemed use to be. So all I care about is that the event exists and gets called and passes the item trying to be used and that meets what I need for this. Interestingly enough I have a Thirst and Hunger component that hooks into onUse as well. The Thirst component has a Drink() function as well that's hooked into onUse. It checks if the item being clicked was a drink and if so it decreases our thirst and sets one arg to true which will tell the inventory component to delete that item once it comes back from raising it's onUse event. That works out great because when I drink alcohol I want my thirst to be reduced too! So this is how I get drunk. I right click an item in the inventory and if that item has alcohol (a check inside drunkness component against the item in question) I can get drunk. But just setting a drunk level isn't really doing anything. What shows the player they are drunk? Well let's randomly rotate the camera to show the head bobbing around. Let's screw around with the controller strafe value so even though the player is moving forward we are adding random strafe values to represent staggering around. Then let's add some shader blurring effect too! By talking about what we want we already see what components need to be affected. When we made those components we weren't thinking about the drunk feature so we probably didn't put any functions for that. So let's go into each component and add function(s) that will handle this. Again, we can test these out in a unit test if we want. Then we hook the onDrunkLevelChange to all these components functions/actions and the parameter would be what the drunk level is. Each component can read this drunk level and act accordingly by increasing/decreasing the effects. We also want to sober up over time so our drunkness component will look at that in it's Update() function. As time passes without having alcohol we'll reduce our drunk level and raise the event to tell the other components. So that is the thought process with adding a feature. Notice the nice thing is that you can add each effect separately to each component over time if you want. Add the staggering to the controller component first. That could pass as drunk for now. At another time add it to the camera for head bobbing. Nice and easy tasks that can be created and checked off with various degrees of what the drunk feature looks like. That's my thought process with component design. Just wanted to show people what goes on with making a new feature.
  19. The religious experience for me was when I went to add functionality and how easy it was. 1) The class component I added the functionality was JUST that. It wasn't all this other **** that isn't about the functionality I needed to add like when you have the massive player class. This was a huge relief and minimized searching and fear that I'd break something else. Not having to worry about the state of all this other ****. 2) Seeing all my events to actions hooked up in 1 spot showed me how my game worked at a high level. This was an amazing realization. The high level idea of my game didn't really even need comments. You could easily see how it worked with the events assigned to actions. You don't get this when you have a giant player class. You have to go hunting for functions but then they are all over the place and figuring out the high level of what that player class does is actually really difficult. When you have all the event hooks in one function you can simply go down line by line (no loops/if's/function calls to follow) and just say what you see on that line and that tells you the functionality that exists for that player/game object. I was shocked by that. That was incredible. So easy for someone else to pick up quickly or you when you revisit something 6 months from now.
  20. FYI, each component generally will have an Update() function to it and can be calls in the game objects Update() function. Like a lot of things in life not everything works perfectly. Generally you don't want to have an event that is raised every frame inside the Update() function of a component, but when you break out the controller and camera you'll find the controller needs the Y rotation value from the camera so the best way to do this without making them aware of each other would be to have the camera fire and event in it's update every frame where it passes as it's argument it's Y rotation value. Then have the controller component subscribe to that event so it can take that Y rotation value and store it off to an internal variable so it can use it inside it's Update() function when you pass it to SetInput(). Ideally events aren't raised every frame but this would be an exception. Also I would say have your GameObject take an LE entity and store that as well. Since your components gets a reference to the GameObject it can then have access to the LE entity. The Controller component would need this since it's calling functions on that entity like SetInput().
  21. That's correct. The player class, which is a game object, shouldn't care about those events because ideally the player class isn't handling them. It wouldn't be controlling the camera. Instead it would have a camera component inside of it and the camera component is the class that creates the camera and gets the events it needs (mouse input) and fires events that other components may be interested in. Your player class then becomes the central hub where you add the components it needs and hook up the events between them. The good news is your comments on functions in your header class help show you the different domains your player class is doing. Those are good hints on how to break out components. Each component should be it's own domain (group of similar logic). So in your case: I don't know what Toolbar is but I can tell it should be it's own component because you have a fair amount of functions supporting it. Health should be it's own component. Carrying it's own component, pick and collision it's own component as well. You are in the exact same boat I was in, and I'm sure a lot of people are in, and I'm telling you when you refactor to use the component design it's like a lightbulb goes off and it becomes fun to make changes/additions because it becomes so easy. Step 1 would be split your domains into their own components. Just create a component class for that specific domain. Now when you're staring at this empty class (PlayerCameraComponent for example), just think of it as it's own library that doesn't know anything else about the other components in your game. It's job is to deal with the camera period. Anything that has to do with the camera happens here. This should create the LE camera entity and then act on that camera entity. What functions does it need to do that? What events should it fire off so outside components can use that. Actions generally are easier to think about at this time. You generally think about another components events when inside a different component and you find yourself saying "I need to know when the camera is in this state". That's your trigger that tells you the event the camera needs. You can right then and there go to your camera class and add the event and fire it when it needs to be fire. Done! It's that simple. You worry about hooking it up later then. It's so nice to be able to do that because it's kind of how we think. Now, the question is how will you do messaging. With events you'd have an event class (I made one a long time ago in C++, I think you mentioned at one point you've used it before) or you do what unity does and you send messages from within a component to the game object. If you go the route of events (I like this way as it's less wasteful and mapping becomes centralized which helps see at a high level what's doing on): // notice how you don't event have a player class in this case. you don't need it as a game object is just a collection of components and the components do ALL the work so no need for a player type class. GameObject* player = new GameObject(); CameraComponent* camera = new CameraComponent(player); player->AddComponent(camera); InputComponent* input = new InputComponent(player); player->AddComponent(new InputComponent()); // hook up the event input->onmousemove.Subscribe(camera, CameraComponent::RotateCamera); If you go the route of SendMessage(); class Component{ GameObject* owner; public Component(GameObject* o) : owner(o){} }; class CameraComponent: Component{ public CameraComponent(GameObject* o) : Component(o){} } class GameObject{ list<Component*> components; void SendMessage(msg, args){ foreach(auto c in components){ c->ReceiveMessage(msg, args); } } } It's been awhile since I've done C++ so I probably screwed syntax up but you get the idea. While the send message approach seems simpler I don't like it. In my view components shouldn't be left to map messages to functionality. For one it takes all that mapping and segments it in different places. Making it hard to see a 10,000 foot level of the interactions that make up that game object. Having it centralized really does help see how your game object behaves at a high level which is handy. I also look at components as separate libraries and it's cleaner if they just raise events and have functions that work on it's internal state. Event args is how you can share details about it's internal state. If you need to know the mouse position inside the camera's Rotate function that is hooked to the input's mouse move event, then the argument (handle this like .NET does where your functions take specific argument classes) can pass that data. So we know that the function inside the camera class should have a parameter of MouseArgs class. The camera class doesn't care how it got that information though right. It just knows it got it and it uses it. The good news is you have all the functionality already. You just need to get it organized better and component design helps with that. So refactoring this stuff is fairly simple. Avoid this trap: I noticed I had an issue with naming my component functions very specific the events I knew they would be hooked up to. Try to avoid doing that. Component functions (actions) should be named for what they do internally to that component. The events are named to what they do. So don't name the camera function MouseMove(). That doesn't make any sense when you think about the camera functionality itself. What's really happening is that the camera is rotating. We know that we're going to do that rotation with the input component but put that out of your head because really anything could call that function and pass in the parameters it needs. Anything! Why is that important? Well, the side benefit of doing all of this is your components are now easier to test. You can do unit tests if you want. In your tests you make an instance of that 1 component, and start calling it's functions passing in whatever data you want to see if you get the right result (examine it's internal state or did an event get called when it should have). That in itself is huge and opens up an entirely new door which will make your code way more stable and make changes way more trustworthy that you didn't screw something up. Generally you'll build up tests and after a change you run them all at the same time and if they all pass you have confidence that you didn't screw anything up.
  22. Generally by events or messages being broadcasted to all other components and the components who care about those messages do whatever they need to do with them to change their internal state and/or raise events/messages. To be clear the player is a game object not a component. The game object has a collection of components and it really only acts as a place to configure how the components interact. Also component design really shines when things get complicated and you have a lot of code. So with your small example we have to imagine a lot since there isn't a lot of functionality but we can do that. So the question I ask about your example is what is the player class doing with mouse input? Why does it need to know that in the intimate way that it does (inheritance, even though you're using it as an interface it's still inheritance)? Your comments in your mouse functions seem to suggest the player class itself will act on the mouse input. What is it going to do with it? Is the reason you didn't show me your actual player class because it's doing a lot of stuff in it and too big and would be confusing for someone to follow? If that is the case, and you don't mind, I'd love to see it to perhaps explain why component design could help it.
  23. Component design really doesn't use inheritance at all. The idea is inheritance is less flexible and causes more issues. Components are about composition. What does your player class look like? This generally is a good test since the player can generally do more than anything else in a game.
  24. The last blog I posted was Nov 2013. The blog section seemed stale for for a week or so so thought I'd share a change in design I recently did for our Dead Anyway game to spark conversation and ideas. Our player script was just getting too massive and was doing too many different things directly inside of it. Adding features or modifying existing features was scary as hell. All the "helper" variables were adding up and the amount of hunting for what I needed in the script was pissing me off. So I decided to re-look at component architecture. After putting this into practice it's really makes programming more fun and changing things a lot easier and less fearful. The first task was to look at this monster player code and break it down into domains. That meant looking at the high level functionality. Play sounds Take input Camera controls Movement controls Inventory FPS arms HUD Handle stats like health, hunger, thirst, etc All of this was happening right in 1 script. Not cool. So I first hand to break all this functionality into their own scripts. However all this functionality works off each other. Even though they are separate when to do what and code X needs to know stuff about Y still exists. So if we want to break code out into it's own domain (and scripts) and reduce coupling on each other to avoid making fragile code AND they need to know about each other in various ways how would I do that? Enter events. I treat each component as it's own little library that is designed to do it's one specific thing related to the game. So it of course has functions that act on it's data. But how would those functions get called? They would get called when events from other components were raised. So now a component has events to tell the outside world that something happened inside this component and functions to act on this components state. It doesn't care how it's functions get called and it doesn't care who is listening to it's events. It's blind to the outside world. An example is the PlayerSound component. It loads sounds in it's init function and then it has functions like WalkForward(), WalkBackward(), StopWalking(), StrafeLeft(), StrafeRight(), Jump(), Eat(), Drink(). These functions simply play the right sounds. The PlayerSound code doesn't care about the input code and when you're in the PlayerSound script you don't either. Your mindset is just all about sound code at that point. You're thinking about what functions do I need for sound, and what possible events should I fire that have to do with sound? The sound script right now is about 100 lines of code (but it will grow in the future). It's nice and contained as it's own component. Every component is like this. PlayerInput converts actions to events. It doesn't care who uses those events. It also has functions to map keys to actions. Who is calling those functions? Who cares. It's not my concern when I'm in coding the PlayerInput component. I just know I want to do that functionality at some point. So how does this all get wired up you may ask? That's the interesting part. Your player script, instead of being an if nested disaster, simply becomes configuration code of linking component events to component functions (I call them actions). I noticed something interesting happen when I did this. Looking at the player script revealed what it's doing much simpler. It provided a nice high level overview of what the player is doing at a glance. I didn't have to read state variables and loops and branch statements to figure it out. I saw it all revealed to me. I feel like it works better with our brains. We think, when this happens do x, y, z. That's the component architecture with events exactly. That's all you see 1 line at a time. When this happens do this. Very little interpretation is needed. Here is an example of what my player script looks like now: PlayerLooting.onLooting:Subscribe(PlayerHUD, PlayerHUD.ShowProgressBar) PlayerLooting.onLooting:Subscribe(PlayerCamera, PlayerCamera.DisableUpdate) PlayerLooting.onLooting:Subscribe(PlayerController, PlayerController.DisableUpdate) PlayerLooting.onCancelLooting:Subscribe(PlayerController, PlayerController.EnableUpdate) PlayerLooting.onCancelLooting:Subscribe(PlayerCamera, PlayerCamera.EnableUpdate) PlayerLooting.onCancelLooting:Subscribe(PlayerHUD, PlayerHUD.HideProgressBar) The PlayerLooting component has an event onLooting and onCancelLooting and those other components are subscribing to those events and telling those PlayerLooting events what functions they could call when that event is raised from within the PlayerLooting component. You can plainly see the HUD shows the progressbar and the camera and controller controls are disabled. If we cancel looting we hide the progressbar and the controls are enable again. Want to add a sound when looting? Just think about how easy that is to think about. No hunting for the right section and state in the old giant player script that is 1000+ lines. You simply: Add a loot sound variable and load a loot sound inside the PlayerSound script (you know exactly where to do this. if it's a sound it's done in PlayerSound component. easy right?) Make a function in PlayerSound to play said sound Make a function in PlayerSound to stop said sound Link the onLooting event to the PlayerSound play looting function Link the onCancelLooting event to the PlayerSound stop looting function It's much more compartmentalized than the traditional design of putting all that stuff into the player script. Here is the event code that I use: if EventManager ~= nil then return end EventManager = {} function EventManager:Create(owner) local obj = {} obj.handlers = {} obj.owner = owner for k, v in pairs(EventManager) do obj[k] = v end return obj end function EventManager:Subscribe(owner, method) table.insert(self.handlers, { owner = owner, method = method }) end function EventManager:Raise(args) for i = 1, #self.handlers do self.handlers[i].method(self.handlers[i].owner, self.owner, args) end end Inside a component to create an event you simply do: -- note I just wanted to use Event but Josh exposed that for his UI stuff so I ended up with EventManager instead self.onmoveForward = EventManager:Create(self) -- events have a table that is an argument that will get passed to the function subscribed to events -- interestingly enough because it's a table, it's passed by reference so inside your action function if -- you change a value the component that raised the event can read that to perhaps act accordingly. -- I do that in a few instances self.onmoveFoward:Raise({ shiftKeyDown = false }) Then to subscribe to the event in the player script where all the components come together you simply call the Subscribe() function on said event passing in the component object and the component objects function/action to get called when that event is raised: PlayerInput.onmoveFoward:Subscribe(PlayerSound, PlayerSound.PlayMoveFowardSound) My future for this is to have an editor that reads all component events/actions and visually allows you to hook up events to actions. Then the player script simply reads the output file of said editor to hook things up. Then we'd have a nice visual of how our game works at a high level. This was a long one but I'm really excited about making the switch. It was an easy transition to make and it makes adding/changing functionality really simple, and it gives me a high level overview of what's going on with the player which was increasingly getting more complex. If you read this far on a weekend then go outside
  25. It can be challenging mixing it into LE since LE isn't component based. Some things don't make total sense. Like my PlayerController component. The LE entity is the thing that can be a controller so inside PlayerController I make it a character controller with SetPhysicsMode() and then in it's update I do SetInput(). Normally this component itself would be a controller but I'm working with how LE works and it still works out. If a person isn't used to communicating between components with events I can see how it might seem strange and not needed (complex) but I find it helps me ask the question for each piece of functionality: What component needs to know about this event. Then I wire up the event to said components so they can handle it. It can be intimidating to see a bunch of events being hooked up to functions, but it's actually really easy to read when it take it one at a time. You understand that this component is listening to this event and does this function when that event is raised. Much easier than a monolithic player class with thousands of lines of code with all sorts of domains mixed in and state if statements all over the place. That was getting to be a disaster to read and maintain.
×
×
  • Create New...