Sensitivity (and Enemy Attack Patterns, apparently)

Any suggestions on dialing in the sensitivity of mouselook in FreeLookCam? I’ve gotten used to it, but when I had some friends test they think that the camera is waay to twitchy when you are just moving around and barely move your mouse hand. I can see this criticism. The only issue is that the speed value for the camera just doesn’t quite fine tune as well as I had expected. At a value of 150 for X axis I feel like it is responsive and quick enough to turn around if needed, but very twitchy when you don’t really need to be adjusting your view. Going much lower than that feels like it takes ages to fully turn when you want to but still a little sensitive for subtle movements. It sounds like acceleration is what I really want but the accel time in the Cinemachine camera doesn’t seem to do much of anything. Anyone work out a better way?

Increasing the speed and the acceleration time may be what you’re looking for…

The higher the speed, the faster the X will change when it is at maximum speed.
The higher the acceleration Time, the longer it will take to get to that maximum speed. This should prevent runaway turning from a slight jossle of the mouse, with full turns happending only when you make a more deliberate movement. You might try shortening the deceleration as well. This should make the mouse feel more responsive.

Yep… tried all that and nothing is quite satisfying. It’s weird. And I’d really like to allow users to edit their own sensitivity. So I forsee intercepting all mouse axis checks and multiplying them by a sensitivity setting. That’s IF I can even get the proper speed feeling right in the first place.

And is the dead zone stuff purely for the camera focus? I’ve seen some interesting YT videos on using Cinemachine looking for others not satisfied with sensitivity and I think that only pertained to when you are tracking things on the screen.

EDIT: Hmm… deceleration is actually having a MUCH bigger impact than I had imagined. I must not have messed with that independently. I might be okay.

It’s a bit like a car in that regard… I once had a car that practically jumped when you hit the accellerator… If you weren’t careful, you could get whiplash when the light turned green. Trouble was, the braking system was horrible, especially on a downslope, so there were more than a few times where I or my wife thought we weren’t going to make a stop in time. Stop and go traffic on the freeway was a nightmare. I was glad to be rid of that car. Deceleration matters. :slight_smile:

1 Like

Be prepared… I am running out of my basic tasks for working combat prototype with some pizazz… I’m going to start migrating the RPG course elements in and am sure to have some four alarm fires I’ll be summoning you for…

But I know my first question (no real need to answer it here… I’ll pose it in a more appropriate place soon enough) is going to be in regards to my “combat pattern” SO system I want to implement. Like… the general idea sounds perfect. And the VERY general idea of doing it seems to work in my mind. But the actual specifics of having an enemy state machine look at their assigned pattern SO to do things is definitely making my brain overheat.

I’m not sure what the SO is you’re proposing quite yet (well, I have an idea), but you could either reference it as a public field on the EnemyStateMachine, or have a component on the Enemy that references it that the State can get it’s grubby mitts on it.

Well that part I can grasp. But it’s more like… Okay… we’ve entered EnemyAttackState… Cool…

I want logic that has the enemy attack… then dodge… then maybe side step… then a different attack… then block for a second… etc…

Just as an example.

Assuming the player is in attack range, if not… they’ll need to pop back over to chasing state… At a minimum I think this complicates things to “remember” where in the sequence they were.

But even beyond that… Just being in AttackState and “starting” the sequence and continuing it. Something just doesn’t seem like it is that straightforward to hard code that logic and I don’t know why.

And there I go hijacking my own thread :man_facepalming: :rofl:

If I understand what you are planning, this is not as daunting as it may sound. SOs can contain logic. In fact, a lot of the stuff unity uses in the editor are SOs: windows, render features, etc.

What I have done in the past was to have an abstract base SO, say, AttackBaseSO. In here I may put an abstract method called DoAttack(). Now I can have several derived SOs that implement different attacks. But best of all, I could also have a SO that executes a combination of attacks by just exposing a list of AttackBaseSO and executing them in sequence (if I choose) in the DoAttack() method. This here may not be the exact implementation, but I’ve used it in this manner and it works a treat

That helps a good deal…

I think part of my confusion would also lie in staying in a state while executing an unknown amount of commands before starting the cycle over. I’ve learned the hard way (forgetting and then relearning) that While loops in an Update (or in the case of state machines, Tick) method cause a fun trip to the task manager :rofl:

But also being interrupted after an attack when you notice you are out of attack range and defaulting back to Chase state and then resuming the pattern seems tough. Although, I suppose it wouldn’t be super efficient, but just building a “close the gap” check into the attack patterns is probably wisest. Leave chase state for the initial chase to get into the attack pattern.

And are you implying that the EnemyAttackState will basically surrender entirely to the Attack SO? Just do all the pattern inside the SO and kick back to the AttackState which would then technically return to chase state briefly before hitting back to Attack and starting over? Or is it that The AttackState would call into the SO which would figure out where in the pattern you are, perform, then kick back, rinse, repeat?

Another use would certainly be to have a Random action taken from the SO… Randomly chooses from 3 attacks, dodge, block, strafe, etc. And eventually I’ll probably try to code in some predictive AI to have the enemy sometimes try to actually block or dodge a player attack. Which reminds me of my little experience with AI… The hardest part tends to be making it more realistic. The easy part is to make AI basically unbeatable. I remember coding a simple game in high school where you take turns taking 1-4 stones or whatever… And whoever ends up with the last stone loses. The way I coded the AI is that it would always win if you didn’t take the exact right first amount and continue to choose properly each turn. It was hard to think of a way rather than making the AI random to avoid this :joy: Clearly a much simpler situation, but I’ve already started brainstorming on how to anticipate a player attack and try to avoid it without basically… automatically succeeding…

But also I did mean to make this its own thread. Feel free to give me any or no response appropriate. I’m renaming this thread and will make a more proper thread when I start attempting this in earnest. I’ll flag the sensitivity response as a solution after the next response so we can put this out of its misery. I know a studious moderator makes their rounds to clean stuff up and I bet this would drive them nuts :rofl:

Yeah, that was pretty much what I meant, but the SO would just be the logic to perform the attack. So, when in the attack state, on tick would call DoAttack() on whichever attack SO is active. A combo attack would also be an attack SO, so the actual state machine would be none the wiser. When I initially wrote the above, the idea was just to run through DoAttack(). That would’ve all been in one frame but in practice, that makes no sense.

I personally prefer coroutines over update (not necessarily a good thing) because it gives me a little more control. Or at least, I feel like it does. The update always starts at the top, while a coroutine will continue where it left off. I would probably change DoAttack() to a coroutine and then let the OnEnter() in the
Attack state start it (Disclaimer: I haven’t done the 3rd person traversal course yet, so I’m not sure how Nathan set up the state machine). This will also allow me to stop the attack if - for example - the state would ‘Exit’.

As for the ‘close the gap’, this may not fit into this pattern, I suspect. It may also be simpler to just exit the attack state and back into a chase state. The DoAttack() could evaluate the range to the target and, if not sufficient, stop executing the attacks. Something like

public IEnumerator DoAttack()
{
    foreach(var attack in _attacks)
    {
        yield return attack.DoAttack();
        if (!InRange()) yield break;
    }
}

Of course, the SO will need more info from the state, like what the target is, and who the executor of the attack is to be able to calculate the range. Or, this could be done in the state’s Tick() and the coroutine could be stopped. Or if the state decides to go to a different state, the coroutine would be stopped in Exit.

I’m just spitballing ideas here.

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

Privacy & Terms