Combat Woes

So there are two particular things that still bug me. They both involve getting very close to an enemy in combat.

A quick aside… I’ve made lots of improvements for my project with this course as the base. I am incredibly grateful for this course. It really upped my skills and I am doing things now that I don’t even believe. I’ve added more states, tweaked things, added sound effects in a fairly intuitive way… all while hopefully not spaghettifying my code too badly for when I have to overhaul it to work with different equipable weapons and enemy behaviors.

The first thing is that when you get right up to an enemy, you can move REALLY fast. It bothered me from the moment we set up the targeting cam. I had hope when we had the lecture that addressed something here but it was merely the camera wiggle. I’m curious if there are any easy fixes to even just hack this to where you aren’t spinning around a point so closely. It is just physics so I get WHY it SEEMS like you are moving much faster than usual. And I believe the root cause (being able to get so close in the first place) is related to my other big annoyance…

You can cheese enemies by getting as close as possible to them. Even with generous weapon hitboxes you can generally have the enemy swing miss if you get right up on them. It can also confuse their LookAt function. I went back and Smoothed out the LookAt since I had a note there that it appeared we were going to come back and do that but we never did. I lerp it out and I also still have a function to snap right to if needed. The problem is if you get right behind the enemy and super close it won’t smoothly get there at all. I can go behind the enemy but not right up on them and they seem to rotate just fine though…

Anyway, I think fixing how close a player can get would likely fix both these issues. It doesn’t seem feasible to increase the character controller radius on either enemy, player, or both. Maybe an extra capsule around the enemies as a trigger to somehow inhibit forward motion from the player? That seems like it would be twitchy and bad. A physical collider that only interacts with another physical collider of the same layer maybe? A “force-field” layer that is just bubbles around all combatants that only bump against each other? Might work but could also spawn unintended side effects.

I’m open to about anything. I’ve got plenty of things in the project to keep me busy, but I REALLY want to get my combat nailed down to near perfection before I start on other systems. Like… fully working and just some final polish with animations and visuals to be done finished.

EDIT for clarity… I have solved these concerns with a two pronged approach. Better hitbox area with another collider on a separate layer which allows movement to still be unrestricted and on the original character controller radius value. Then just a simple distance check with a modifier for speed for the player when they get too close to their target.

The moving really fast is an illusion, as you suspect. You’re moving the same amount, but an the angle of a step to the left from 10 feet away is much smaller than the angle of a step to the left 1 foot away.

Larger capsule colliders would be my first choice, and they have the advantage of solving another common problem with 1st and third person melee controllers, false misses. Instead of extending the sword’s hit box out an extra two-3 feet, the larger Capsule Controller would do the trick…

On the other hand, a PersonalSpace layer with an extra collider is also an excellent idea, and it avoids issues like not being able to get close enough to a wall because of a larger CharacterController.

1 Like

Have you tried with bigger capsule colliders? I feel like making them too large will cause too many other issues.

I may actually kind of combine the 2 ideas. Have an outer PersonalSpace (love that name) layer that looks for weapon colliders and other PSpace colliders to stop the fast rotation. That may help prevent unwanted side effects. Because yeah, as you say, my concern with the bigger main collider is movement issues. And clipping in general. Always fun seeing random things come up when an enemy steps on my dead body and floats way up in the sky, but that’d be hard with the PSpace as well… Looks like lots of MORE testing is in store for me.

Oh but wait… How DO I make the fake PersonalSpace collider behave like a regular capsule collider that natively makes other capsule colliders repel? I think that was my original issue in my head that I kind of was going to just do a PSpace thing but I got sidetracked explaining it all more elaborately. I don’t even know where to begin with coding a collision/trigger that just acts like a wall for another collider.

Don’t mind me, just blowing up your notifications like usual as I workshop my own questions…

I think my last reply I was trying to think of a way in my head to do it WITHOUT another collider. Checking for distance to another enemy and somehow inhibiting movement. Sounds like a recipe for disaster if I could pull it off.

So let me run this by you. PersonalSpace collider on a layer that you use the handy dandy physics checkbox grid to only collide with other PSpace things. That handles the collision to keep the distance. Then in the WeaponDamage script, in addition to the checking for Health component, check for a PSpace tag so we are interacting with JUST that collider? In theory it would hit that collider first then may make contact with the character controller collider after.

I THINK this sounds right. I’m getting shakier and shakier as I add new features. I’ve jammed in there playing a weapon sound on hit regardless if it not the player and for when it is the player another function that checks to see if the player can block the attack. I have made my block an angle check not just turn on invulnerability, so I can actually quickly make the CHECK for it there while still sending over the hit info to Health to let it nullify the damage if the angle is right, play the block sound rather than the weapon hit, and still apply the knockback. I am rather proud of that actually.

EDIT:
Well I can’t very well put the capsule collider on the base player gameobject if I want it on a separate layer. I put it on a child object and after manipulating kinematic and rigidbodies and stuff (always bad at this) I finally get it set right for player and enemies… Getting the collision to spit out in the logs but still right up in each others’ faces… Popup the scene view and basically the object with the PSpace collider just gets nudged away from the player’s body… Any ides?

I workshop like this from time to time myself, no worries.

Yeah, something I didn’t think of… The personalSpace collider definitely has to be on it’s own GameObject so you can set the layer… You’re going to need some sort of broker between the PersonalSpace layer and the top layer… My best guess is that PersonalSpace will need to be a trigger, and then you’ll need a component to get that trigger message and relay it to a component on the top layer… Maybe a well calculated nudge to the ForceReceiver?

Oooof… Yeah I really, really didn’t want to have to go that route. I am not even sure if I would know how to make any sort of proper calculations to simulate this to make it feel natural in any way.

I did try to make the PSpace object the main parent for the player, but that didn’t seem to accomplish anything. It stayed in place and the player zoomed off.

I guess at a minimum I can use it as a separate hitbox for players an enemies that doesn’t restrict their movement in the world. But I just can’t think of any meaningful way to keep that combat distance to a reasonable amount to prevent that zooming around.

FWIW, I also even added an if check in the enemy chasing state to have them lerp face the player so they aren’t snapping directly to them but still able to aim at the player. Angles are REALLY weird as I found out from shield block testing. The lowest angle I’ve ever seen for facing directly is about a 7 but it is usually somewhere between 10 and 15. But this leads to some inaccuracy for when they finally do switch to attack state. This is aside from my main issue, but I just wanted to point out I am really trying to flesh this out as best I can and that extreme angle rotation is super agitating.

I also had thought of something to ask you that was a more general question for this or Unity in general and I am blanking. Hopefully it comes to me later and I’ll make a proper new post. But any help you could give on how to have the ForceReceiver GRACEFULLY keep the distance up would be appreciated.

It doesn’t even matter. WeaponDamage doesn’t even ever detect PSpace. I’ve tried it with every combination of trigger/rigidbody/etc… This is pointless. (And I rewrote it to not to TryGet since I needed to get PARENT components which doesn’t have a Try version… and still nothing. Debug.Log all collisions and it never finds my PSpace tagged collider)

Radius 0.5 for the character controllers feels pretty good for hitbox size and combat rotation… Just terrible for world navigation. I’ll just have to remember it when building out my world. Nothing even remotely resembling a tight squeeze.

FUN! Now my collider is too fat to reliably do ledge hangs. It was already not the most reliably proposition but now it is far worse.

It’s sounding more and more like a PersonalSpace collider just isn’t going to work.

Yep. Seems like it should be simple. But of course it isn’t. I had told my friend I knew it wouldn’t work because it works so well on paper.

I have always wanted to learn UE. Wonder if their collider stuff is less nightmarish than Unity’s. It has always been the worst part for me.

Oh wow…

So, this is n00bish of me… But I thought the COLLISION matrix was only for COLLISIONS and not TRIGGERS…

So that explains why none of it was working. So sometimes it is good to blow it all up and try again. Sorry for being angsty on this thread. The little crap like this ASTOUNDS me there aren’t better built in ways of doing this when so many quality AA games have been made in Unity.

Other findings… Yeah even with a sibling GameObject NEXT TO the player/enemy… it won’t apply any physics to the player itself. The RigidBody for the PersonalSpace collider moves around on its own but doesn’t affect the avatars. So I went back to a trigger and have the combat code working just as well! I Really wish TryGetComponentInParent was a thing… but I guess they thought that was TOO long of a function name… But I did avoid having to declare all 3 things(health, playerstate, force) separately. Get comp in parent and then check for null before executing. I realized I could just get the PSM from TryGet from the health directly. That was a strange oversight in… hind…sight from how we had this originally.

Sooooooo… my rant is here because any guidance you can think of on the invisible forces to keep the combatants at that edge of their PSpace collider would be helpful. A few things pop into my head but I have little confidence in any of them. I assume a new script for the PSpace itself(well replace my testing one anyway) that handles it. Otherwise maybe serialize a field for each SM flavors then check in the ForceReceiver directly? But then the actual “math” of it boggles my mind too. Just a gentle nudge in the opposite direction of forward if it feels the trigger state? But I would think skating around it at an angle would make for some funky movement.

I’ll probably play around with a bit as always, but I can almost guarantee I’ll need some patented Uber-TA help here.

Yeah that was getting nowhere fast. I am starting to think cheating and having a check in PlayerTargetingState to figure out the distance to the enemy and under a certain amount halve movement speed :rofl:

YEP! It works! Add some hacks to PlayerTargetingState

Delcare some consts:

private const float DISTANCETHRESHOLD = 1f;
private const float SPEEDOFFSET = 0.5f;

Add a multiplication function to the Move call in Tick

Move(movement * stateMachine.TargetingMovementSpeed * DistanceSpeedModifier(), deltaTime);

Then let her rip:

    private float DistanceSpeedModifier()
    {
        // Checks distance to target and returns a speed percent offset if under threshold.
        // This is to prevent the illusion of super speed when very close to targets.
        float distance = (stateMachine.transform.position - stateMachine.Targeter.currentTarget.transform.position).magnitude;

        if (distance > DISTANCETHRESHOLD) return 1f;
        else return SPEEDOFFSET;
    }

This seems to work like a charm with the threshold set to 1. I just kind of guessed at both values and it seems to be pretty spot on and seamless. Well, I did spit out the distance to the console a bunch to get an idea where the speed really ramps up before settling on 1, I suppose.

My only concern would be if this is too intensive to do with every Tick. It would not nearly be as elegant, but I could always just make DistanceSpeedModifier be a bool and have two separate calls to Move for the results.

1 Like

Since this is being run in the targeter and just on PlayerTargettingState, I don’t think the calculation will be much of a strain on the system. Good job working that out, and without any of my patent pending TA help!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms