Looking For Guidance

The game I’m currently working on is a multiplayer top down survival game. Most of the controls will be done using the mouse. When you click on the ground the player moves, when you click on an enemy the player can attack, click on a resource and the player will gather. There are also items you can pick up, put down, as well as buildings you can place.

I have the majority of this working although I started running into issues and it started looking weird to me. I pretty much had everything coming off the tick function, checking if the player is currently trying to move, if not if he’s trying to attack, if not and so on. I have 2 ideas and I was wondering which one would work better, or if anyone has a better idea :smiley:

My first thought was to use a sequence that goes through all the possible options a player could be doing, but using flags to just jump out of we don’t need it.

My second thought was to use enums and a switch to change based on what the player is currently trying to do. I would just have to figure out what he’s trying to do first and then switch to which action to call.

If anyone has any better ideas please let me know, or if you need more info I can provide that as well. Thanks!

You could try treating the player as an AI.

No, I’m serious. Make a behavior tree for the player. Fill it with all the things you want to let the player do. Then use the player’s inputs to guide that behavior tree.

Helpful resources on Behavior Trees:
Behavior Tree Quick Start Guide (Unreal Documentation)
Behavior Tree Tutorial (Unreal Wiki)
Gamasutra Article by Chris Simpson about Behavior Trees - This one is written by someone who uses a Java-based Behavior Tree solution, but it’s written in a general manner and a lot of what is said applies to Unreal 4 as well. EDIT: I believe this is even written by one of the developers of Project Zomboid. :slight_smile:

Veovis Muad’dib’s solution looks pretty good, but this also sounds like a perfect place for the Command Pattern. Pretty much how I would solve that problem. Using a list of set behaviours and then execute them based on the thing you click on is way better than switch/ifelse blocks.

The article shows how to do it in c++, I am not sure how you would go about it in blueprint though. I don’t think you can have function pointers or delegates in there.

Thanks a lot for the ideas! I’ll have to dive into both of these and see which works better! I’ll post back here with what I come up with :slight_smile:

Alright so far I’ve been trying to move my player towards using a behavior tree. I haven’t messed with behavior trees before, but I went through all the tutorials and links that you posted for me. I managed to create a wandering AI for a rabbit in my game (which works great!).

The issue that I’m running into now is how I would pass what I should do to the behavior tree. The way I have my game set up is that the client has a Player Controller and a Pawn that he controls. When the game begins he spawns an AI controller on the server that spawns the actual character. When I click the Player Controller tells the AI Controller to move the character on the server to the new location. I’ve had all this working fine so far, but kept running into problems when I wanted to add more functionality.

For example my character can place down items/buildings from his inventory on the ground. First he should check to make sure that he’s within a certain distance (if not move closer) then he can place these down. I’m having trouble of thinking how I should do this with the behavior tree. On my player controller should I keep flags for what I’m currently trying to do (bPlacingItem, bPickUpItem) and check the distance, then tell the behavior tree to move first, but then I would need some way to know that we finished moving close so the item can now be picked up. The way I was thinking this would work would be to kind of set some kind of enum from the player controller to the AI controller, so that the behavior tree knows basically what “state” i’m trying to be in. Then I could set the state to moving, have the behavior tree tell me when moving is finished, have the ai controller tell the player controller it’s finished, and add the item to inventory/remove it from ground.

Maybe I’m thinking about this all wrong, would love some insight! Thanks again.

I’ve been playing around with behavior trees and I’m starting to get the hang of them. I also think that this could be the best route to go for handling my players input and moving the character. I have run into an issue that so far I’m unable to figure out how to get around.

This is a section of my character behavior tree that has to do with movement (I cut the rest out that i’m working on since it’s not important right now).

This is my function that I’m calling to set the location to move. When the player click it sets the variable “Hit Location” on my Server_AIController. This tells my Behavior Tree where I want to move my character. and works great. Inside of this function I tried to make it so that if the location hasn’t changed to just jump out, because I’ve been trying to find a way if the location changes while moving, the character should abort the previous move and go to this new location.

When I previously had my character moving you could hold the left mouse button down and the character would follow it. This is what I’m trying to reproduce now using Behavior Tree. What I have so far works as far as moving my character. But he will not move again until after he finishes his previous movement, and I must click again. Holding down the mouse click does nothing. Does anyone have any idea if there is a way I can create this behavior?

Thanks,
Snackmix

I think there’s setting for the on click even in the details panel that control how the input is consumed… seems like maybe what is happening is the click is being consumed causing you to need to click again?

I’ve created a video showing the functions I’m using and how I’m actually moving the character. The movement works, just not continuous. Before I had the movement similar to Diablo 3 where if you hold down the mouse button the character will just continue to follow your mouse. The way I was thinking it would work is to somehow interrupt the MoveTo when the target move location has changed. I just haven’t figured out a way to do this, or if it’s even possible.

Video: https://www.youtube.com/watch?v=-VlKbmrzNzM&feature=youtu.be

Thanks!

Alright so I’ve figured out a lot of my issues. I created my own Task for movement instead of using Simple Move, which let me abort out of the movement and start it again so I can now move using the location in which the player clicks (or holds the mouse down).

I’ve ran into another issue but this has to do with networking. I figured rather than open an new forum topic I would just update this one so people have more information. When I click to move my player a custom event is called. This event passes where we clicked, and what we clicked on (called state in picture, although it’s not really player states) to the AI Controller on the server that actually handles moving the character. The AI is controlled using a behavior tree (which seems incredibly useful after fighting to learn how to use it correctly) and I have a couple functions in my AIController that simply set a variable passed from our player controller.

All of this works fine for the “Server” player, but when the client tries to do the same the “state” is never passed. The “Hit” however is passed to the server, and both are being passed and set the same way. Using lots of print functions I was able to determine that “state” is always being passed from the client as default, although if I check it after it’s set, it is changed to “ground”. Since I have nothing in my behavior tree to handle default, when the client clicks nothing happens. I checked and made sure that the client can see the tag “ground” from the object he clicks on, but it’s never being passed after set.


This is where I set the “state” depending on what the player has clicked on. The value set here shows using a print function from the client.


This is where I pass the “hit” and “state” to the AIController. The Hit is being passed just fine, but the state is always passed as default. I’ve tried making the state replicated, making the AI’s “state” replicated. Tried creating a different custom event that only handles passing the state. All still pass the same default value.

If anyone has any idea on why this keeps reverting to default I would gladly appreciate a push in the right direction! Sorry If I’m over looking something obvious, I haven’t dealt with networking very much yet.

Thanks,
Snackmix

Feel free to ignore this. I have solved the issue I was having. I forgot to pass the variable to the function, which is why the default was being passed to the AI Controller. Maybe I should go back to school and re learn scope :stuck_out_tongue: Anywho, thanks again for the heads up about behavior trees Veovis! I’ve made a lot of progress the last couple days, and plan on making a lot more!

Glad to help, and glad it’s working for you!

Not going to lie, I suggested it but I haven’t actually used them myself yet, so I wasn’t sure how to help, and I figured I’d wait around for someone in this thread to answer the questions you have so I could also benefit from them in future. :stuck_out_tongue: Have two or three things I’d like to learn next, and then it’s on to Behavior Trees myself, that’s why I had those references ready to go.

Haha well you gave me the push I needed to learn them. Let me know if there’s anything I can help with I’m starting to get the hang of em!