Hello community, I'll try to state this briefly:

I have a player movement script that handles basic movement via inputs as well as gravity and jumping abilities (jumping, double jumping, flying, gliding, and falling). Most things, except for jumping and falling, have a bool in the script to say when they can happen. Falling damage is handled through a script that doesn't reference the player movement script, so I can apply falling damage to any character regardless of what is controlling their movement. The falling damage script is a modified version of GiL's script here that adds a skill check to increase the damageThreshold variable based on the character's skills.

So here are the things I want to do and the questions attached to them:

1) I'd like to make things like double jump and flight abilities that you gain during gameplay. How do I set them up so that they are basically a bool value that I can check in my player movement script (that way if the player doesn't have the ability, the bool for double jumping in the script can never be set to true)? How do I set up the gliding ability so that its bool is dependent on whether or not you have a specific item in your inventory?

2) I'm trying to figure out how to separate the player movement controls from the non-player character movement and still achieve activating the falling damage script. Should jumping and falling be abilities in ORK too? My thinking here is that I can create a bool that tells the fall damage script when NPCs are falling (triggering the fall damage to be calculated from the script) and be able to do the same for the player from the player movement script.

3) Along that line of thinking, should I just make all the player logic in one separate script and make my player movement script inherit from that player logic? Wouldn't that, in theory, make it easier for me to make other player scripts for movement systems (like swimming, sneaking, or climbing) from all the same base logic that I gather for the basic player movement script?

I'd like to not rewrite a whole bunch of variables in each script that I'll likely use again to create locomotion underwater or on the side of a cliff. Does that make sense? I'm still getting my coding legs strong, so I just don't really know if I'm going about designing my code well or not yet.

Thanks to the everyone for being a generally amazing community. I feel like I can ask these newbie questions here without getting s**t for it and I appreciate that.
Post edited by dragoonleaph on
  • 1) You can simply check if the combatant has the abilities:
    if(combatant.Abilities.Has(abilityID, level))
    combatant is the combatant, abilityID the ID/index of the ability, level the min level that should be available (e.g. 1).
    Check out this how-to for getting a game object's combatant.

    2) Not sure how your scripts currently work, but I think the easiest way is to have a component on your combatants to log the last position they had on the ground and if the next time they're on ground is lower than a certain value, you apply damage.

    3) Yeah ... that's the basic struggle of writing scripts :D

    It's probably a good idea to do it that way, though it can also get way more complex than it needs to be ... also, I'm sure there are tons of 3rd party movement assets out there that already do what you need (and you should be able to adjust them to check for ORK states like knowing an ability).

    In the end, you just need to consider if you invest your time or your money into it, e.g. scripting a system like this can take days or even weeks, while some asset might just cost $50-100 and a bit of time to learn/adjust it.
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • I appreciate this info a lot, it goes a long way to getting me where I need to be with development.

    1)That's great, I should be able to take that and run with it.

    3) That's good to know, I haven't talked to anyone about this issue yet so it's good to know I'm not alone here. At the end of the day I think it's a good idea to to separate it out too. Sneaking, swimming, climbing... most of those things only the player and their party members will do, but being able to code those systems agnostic of the player and just slap those scripts on their respective game objects will save me some headache (at least I think that now). I'm going to take it as a really good opportunity to level up my programming and coding skills, even though I know you're right about the 3rd party assets.

    2) I'll elaborate a bit on number 2 since I'm still a little confused about how to handle this issue. In my player movement script I have a method for handling my ground to air to ground cycle. It has a ground check to see if you can jump and then sets some bools for being able to double jump, fly, whether you've stopped flying, and whether you're gliding. From any of those states you can of course be grounded again, and if you're not flying you're being pulled down by gravity (if you're gliding you just come down slower than if you're falling). That's all fine; the issue comes when you're headed to the ground from any height. If you land from flying or from gliding you still take damage from the height as if you fell because the fall damage script doesn't differentiate between movement states. It just calculates the start of your descent and the end of it and deals damage if there's a high enough difference between that start and end.

    I should mention that I don't think I can base whether or not you take falling damage on the speed of your fall because you can descend while flying faster than you would fall due to the applied gravity (but I did think about doing it that way).

    So my idea to keep the fall damage script independent of the player movement script is to create an ability in ORK that I could use to set a bool like isFalling to true if the character is falling, and pass that bool value along to the fall damage script to have it trigger at the correct time. I'm not sure if this is good programming design choice in this case though. I hope that makes sense. Any thoughts on that idea?
  • 2) Well, it doesn't really matter if you do this via ORK or only your script, you have to react to special cases like flying or gliding anyway.
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • Okay, so I've changed up the code for fall damage and for player movement. I'm now integrating ORK abilities into them so that I can keep the falling script agnostic of player controls. I'm trying to use abilities to set up bools that I can call in the fall damage script and the player movement script.

    The question now is how do I set up abilities to set bools and have a use cost?

    Let's take double jumping for instance: I have created the ability called 'Double Jump' and in the Level Settings section I put an event that checks if the combatant's 'canDoubleJump' bool is valid and if not, sets it to valid. Then it makes the use cost for double jumping 5% of the consumable stat.

    I think that set up is correct, but when I start the game at the console says the ability has been added, the combatant's canDoubleJump bool is not set to true. Is this how I should be doing this?
  • I assume you're using the Add Game Event for this?
    Make sure your event is set up correctly, e.g. the combatant who learns the ability has to be set up as a Starting Object actor. Also, make sure the variable setup is correct, a common mistake is to use the Game Variable value type for variable keys instead of Value.

    I'm not really sure why you're setting a bool variable, though - you just need to check for the ability to be known to the combatant (e.g. in your script via the code I posted above).
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • Ah! I was setting it up that way because I forgot to use that code. Lol, juggling too many things at once. I'll use the code instead and report back.

    Thanks GiL!
  • Okay, I got everything working correctly except one thing: when you fly or glide the use cost isn't taking effect.

    You can double jump or glide and land, and you won't take damage. If you fall from a significant height under any circumstance, you will take damage.

    But how do I (or what would be the suggested best practice to) trigger the use cost for the double jump, flight, or gliding abilities?
  • edited April 15
    You can either do the ability (or just use cost) calculations from your script, or actually use the abilities via control maps and trigger the functionality from the ability's battle events.

    E.g. getting and using the ability can be done like this:
    AbilityShortcut ability = combatant.Abilities.Get(abilityID);
    if(ability != null)
    List<Combatant> targets = new List<Combatant>();
    if(ability.Use(combatant, targets, false))
    // ability was used > do stuff

    combatant is the combatant using (and also being target), abilityID the ID/index of the ability. Passong false will only do the calculations, if you pass true as parameter instead, it'll use the whole battle action, with battle events, etc.
    The ability's Use function will also return true or false if it was actually used, so if it fails due to use costs, it'd return false.
    Post edited by gamingislove on
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • Alright, now we really have something going on. The last thing is that I need a couple of these abilities to use the cost each second instead of every frame.

    Like when you fly, instead of just having your stamina drain to zero like crazy, it just drains a little each second. How should I implement that?
  • edited April 16
    I guess the easiest way would be using a status effect for the drain, since effects have all the features needed for it.

    You can apply it by your ability (i.e. upon using the previous code) or via script:
    combatant.Status.Effects.Add(effectID, combatant, null, true, false, null, null, null);
    For removing when the action stops, you can do this via script like this:
    combatant.Status.Effects.Remove(effectID, true, false, null);
    effectID naturally is the ID/index of the status effect :)
    Post edited by gamingislove on
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • edited April 18
    I had to edit this comment to remove it, you already gave me the answer. It's time I got some proper sleep. :\
    Post edited by dragoonleaph on
  • edited May 10
    Alright, it's been a bit after fixing up my script and testing it out. I still have one last issue on this.

    I have several abilities tied to one status effect for the drain and one separate status effect for the stat to regenerate(let's call it Stamina Drain and Stamina Regen). The Stamina Drain is used for several abilities like running and gliding that take the same amount of stamina over time. The Stamina Regen has an auto apply and auto remove that applies the regen when the status value is less than 100%, no Stamina Drain is in effect, and no action is being taken. The regen is auto removed when either Stamina Drain is in effect or Stamina value is at 100%.

    Or at least that's the desired result. In truth, it works until I start gliding.

    I run fine, I jump, I double jump, I fly; all fine. When I begin falling I hit the button to glide and my Stamina doesn't drain at all. It fills back up and I'm able to glide until I contact the ground without losing Stamina. I've tried using ORK's abilities to initiate the Stamina Drain, I've tried adding it from my movement script. At one point I had it working somewhat, but instead of draining a the Stamina attribute over time, it drained it down to 0 in a second.

    Any ideas one how to address this issue would be very welcome.

    EDIT: This has been solved by creating a separate status effect for the gliding ability, and adding it to the player at a very specific point in my script. Seems like I just needed some time away from the problem to come back at it with fresh eyes. Imagine that... lol.
    Post edited by dragoonleaph on
Sign In or Register to comment.