News › Forums › RAIN › General Discussion and Troubleshooting › RAIN Mecanim help
Tagged: animation, mecanim motor, mecparam
This topic contains 9 replies, has 2 voices, and was last updated by svalero1124 1 day, 4 hours ago.
January 25, 2023 at 3:11 pm #39957
Before i ask for help, I have been trying to figure this out for a week or so now. I have watched all of Unity’s and RAIN’s tutorial videos out there. A lot of them are old and thus don’t match up with the current RAIN asset.
Essentially all I am trying to do is make my AI patrol a certain area and pause after certain way point marks. I don’t want him to pause on EVERY single one but every now and then i want him to pause and idle for a bit.
i ran into this post http://rivaltheory.com/forums/topic/simple-waypoint-pause/. This didn’t really help me because I am completely lost on how RAIN interacts with the unity animator states.
I also ran into a few post’s where Prime said we should use the MecanimMotor and the MecanimAnimator to control the animation states but there isn’t any video i can reference to. Most of the tutorial videos out there already have the animations provided and use root motions.
The model i have has no root motion and only has a idle, walk , run , and attack animation.
What i really want is to learn how to use rain with animations properly. I can Provide a small portion of my current game just to show you what i have so far and how I’ve been going about it. If this is too much to ask then if you could just help me setting up to get my AI to take a random pause after he reaches a certain point and idle and then resume patrolling.
what i have so far is…
-MecParam(Repeat=never,this sets my animation value to ‘walk’ essentialy)
—MOVE(to next waypoint)
—MecParam(Repear=Never,This sets my animation value to ‘idle’)
When i run it he walks up to the first waypoint marker and then pauses and idles which is good! BUT when he starts moving again he’s in idle animation while moving which is wrong! If i set the first MecParam to Repeat = forever then when he pauses he just walks in place and the idle animation never happens.
As i said earlier i know i’m probably using Rain incorrectly with the animation but there isn’t a video i can reference too. I am willing to learn if someone can teach me.
PS: running off to work right now so i won’t be able to check this for about 5 hoursJanuary 26, 2023 at 1:28 am #39970
The reason he never goes back to walking is that the waypoint patrol node continues to run its children until the AI is done patrolling (if it is looping or ping pong, that’ll be forever). If it is the waypoint path node, it works similarly except it will stop once the AI gets to the end target.
So your first mecparam only gets hit the first time, and never again, as you noticed. You can move that first mecparam into the waypoint node, before the move, and it’ll start working the way you want.
If you want it to be random amount of time, and only sometimes occur, something like this would work (may have to change some of the details).
sequencer waypoint patrol (waypoint route: "Patrol Route", move target variable: _waypoint) mecparam (parameter: Speed, value: 1) move (move target: _waypoint) random sequencer // empty sequencer mecparam (parameter: Speed, value: 0) timer (seconds: random(1, 3))
So that would move to the first waypoint, and then randomly choose between the empty sequencer and the sequencer that has the idle and timer.
So once you get that working we can go down the route of using the MecanimMotor instead, as that’ll work better for you in the long run (for walking and running at least).January 26, 2023 at 11:44 am #39974
It worked! I feel silly considering I just had to move one node down into the waypoint node. He now walks around and goes into idle at random intervals.
Now I see that Random can use Weights to kind of control which node is more likely to get triggered over the other nodes. In my case i want him to patrol more often than pausing. I know it takes an expression but there doesn’t seem to any information on the wiki about how to use the weight. Is there anyway you could explain a little on how this works? If not its no big deal, i can just add a few more empty sequencer nodes to overcome that.
I also noticed that the mecparam you use in the example above use the parameter ‘Speed’ which is where the MecanimMotor comes in I am assuming? In my MecanimMotor and MecanimAnimator i have no parameters or states.
In my case, for my animator controller, the only parameters i have is AnimSpeed = float and Direction = float(at the moment I don’t understand how to get direction to work). When AnimSpeed is 0 he’s in idle state, if AnimSpeed>.10 then he goes into a walk and if AnimSpeed = 1 then he’s in running state.
so in my animator controller, i have an idle state and a locomotion state. He starts in idle and the only way for him to transition into locomotion is if AnimSpeed > .10. Now locomotion is a bleed tree with a walkleft,walkfoward,walkright, and run. Lets ignore direction for now and just worry about walking and running. In my game currently, you helped me fix the fact that he would get stuck in idle animation while moving, and it now does exactly what i want BUT there is a slight bug. He doesn’t get out of idle animation fast and enough. This means, and i’m staring at my animator controller do it, the idle state has to ALMOST finish running before he goes into walking animation again. So for about 1 or 2 seconds he’s moving while still in idle animation and THEN goes into walking animation. Obviously, an npc would look very odd doing this and thus I’d like help to know what you think i’m doing wrong or how i can overcome this.
I would really like to understand how the MecanimMotor and MecanimAnimator can help and i am assuming that the reason my model is running into these bugs is because I’m using rain incorrectly.
for MY own mecparam i have it as….
mecparam(parameter: AnimSpeed, value: 0) = idle
mecparam(parameter: AnimSpeed, value: .15) = walk
mecparam(parameter: AnimSpeed, value: 1) = runJanuary 26, 2023 at 12:15 pm #39975
Starting with the random node and weights. Any child that goes into a random node will get a weight value that it can assign. You can use any range of numbers for the weight, but it is probably good to be consistent, so lets say we weight things from 0 to 1. If you have two children in a random and give them both 0.5, it’ll just be a 50/50 chance, as if you didn’t do anything. Give one .25 and one .75 it’ll be 25% and 75% respectively. So in your case I’d give the empty sequencer a value of 0.8 and the pausing one 0.2. That should make the empty sequencer happen more often (hopefully close to 80% more often) than the other one.
Next, to fix your animator controller. It sounds like you have Has Exit Time checked on your transitions to/from idle and your blend tree, you’ll want to turn that off. That would have caused the idle or walk/run animation to wait until it finished playing the loop it was on before transitioning.
Next up, using the MecanimMotor. So the MecanimMotor is similar to the BasicMotor but it has a few more options to help you out with locomotion. You aren’t using root motion so make sure that is unchecked to start off. At the very bottom of the MecanimMotor there is an Add Parameter option. This lets you forward values from RAIN to your animator controller. For now, add the Speed parameter and change the name of it to AnimSpeed (to match your state machine). That’s it, now the the MecanimMotor will handle your speed value for you automatically. You’ll want to remove the mecparam nodes from your behavior tree at this point as it will get handled for you.
So what you’ll probably notice right away, is that your AI will likely be running around, but not moving nearly fast enough for the animation. What you’ll want to do is increase your blend tree value for walking and running until the AI starts to look like his feet are actually connecting. At that point you can increase the default speed for the AI until he moves the way you like. You’ll just need to play around with the values for the most part unless you made the animation and know exactly how fast they animated the walk/run speeds.
0.15 is a little slow for walking, I’d start around 1 for walking, maybe 3 for running and start tweaking from there. I’d choose a default for the MecanimMotor speed to be whatever the AI does the most, probably patrol speed. In your behavior tree when you actually have him chase something you can increase his speed there.
As far as the MecanimAnimator is concerned, I would assign it in the editor but I wouldn’t use it. The states are a hold over from an older RAIN and will be going away very soon. They don’t do anything you can’t do in a mecparam though, and if you need more control than that a custom action would be the best bet.January 26, 2023 at 2:39 pm #39977
Thanks so much Sigil! Everything you’ve told me so far has worked flawlessly! i managed to get the mecanimMotor to do all the moving now and it works great!
I have just a few more questions regarding the behavior tree. As i have it now my NPC patrols and when he detects the player he runs after them which is perfect! BUT if the player takes a step to the left or right or just ‘S’ keys backwards the NPC loses sight of him, for just a second, and then chases him again. So what that ends up doing is making him stutter from a run to a walk back to a run very quickly but it’s heavily noticeable and he will keep doing it until you turn a corner or he finally catches you.
My tree looks like this. The first constraint is just his normal patrol route with a random idle added to it.
1) constraint(varPlayer==null) just patrols
2) constraint(varPlayer!=null) goes into constraint #3
3)constraint(varMelee==null) chases player until he’s in melee range
4)constraint(varMelee!=null) some attack animation haven’t got that far yet
And then regarding his waypoint markers, when my NPC reaches any waypoint marker, because of how my map is laid out, most of them are sharp 90 degree angles. My NPC will just turn very quickly towards the next point. What I’m wondering is if there’s a way to tell him to take the turn slightly slower. Kind of like a transition to turning instead of just facing north and then suddenly looking east and having no delay to it.January 26, 2023 at 3:15 pm #39978
Well, as far as the stuttering, it depends on what it happening. If your player is still within the sensor’s range and it is stuttering, check to see if line of sight is causing it. What often happens is that the aspects default right at the feet of the AI, and occasionally dip below the planes you might be working on (or terrain or whatever) causing a line of sight block. So usually raising the aspect up to chest height fixes the issue. If the stutter is occurring because the player leaves the sensor’s range for a moment, then we’ll need to account for that in the behavior tree (I have some solutions for that).
For the waypoints: You can lower the AI’s rotation speed to make him turn slower, and you can lower the face before move angle to make him turn more before he starts moving forward. Rotation speed can be overwritten by a move node in the behavior tree, but the face before move angle is stuck on the motor (that may need to be changed).January 26, 2023 at 3:26 pm #39979
Thanks again Sigil! Let me play around with what you just said and I’ll let you know how it goes.
Running off to work but it looks like if i turn off all of the line of sight masks except for the players he doesn’t stutter but then he can see me through walls so i’ll have to play with it when i get back.January 27, 2023 at 11:36 am #39983
just an update
I fixed the stuttering! It was a line of sight mask issue. For anyone else who might run into this post, when you place the entity on your Player, assuming it’s a First Person controller, the entity will most likely be inside of your main camera. Make sure the layer of the main camera isn’t the same as the entity as it will cause the AI to stutter when he detects you. This is because the AI will constantly search for the entity and this entity will ‘clip’ into the main camera just for a second as you move your player.
I also managed to slow his turning down a bit for the way markers so it looks better now.
I haven’t tried to do this next part yet but just as a general direction, how would you go about having the AI detect you and then if you ran around a corner, i don’t want the AI to necessarily stop chasing you right away. I’d like the AI to keep chasing me but maybe after like 5-6 seconds of no line of sight then he could stop.
On that note, I have an issue where if i have my AI chases me for awhile, i do this on purpose of course, and then break line of sight after chasing me for awhile, he turns around and goes ALL the way back to a way point marker that was near the start. This isn’t much of a problem because i like the idea of him kind of back tracking so the player has no idea where he went but maybe in the future where i might not want that, I’d like to know in advance if there’s a way around this.January 29, 2023 at 10:58 am #39995
We have an expression function to help with that, called position.
Essentially you will need to record his position while you are chasing him, so that in the event you lose your target (but still have his position) you can head to it. I’d have to look at the overall behavior tree, but in general you can do something like this:
root parallel (succeed: any, fail: any, tie breaker: fail) detect (repeat: forever, form variable: myTarget) sequencer constraint (constraint: myTarget == null) waypoint patrol move selector constraint (constraint: myTarget != null) parallel (succeed: any, fail: any, tie breaker: fail) expression (repeat: forever, expression: myTargetPosition = position(myTarget)) move (move target: myTarget) constraint (constraint: myTarget == null) move (move target: myTargetPosition) expression (expression: debug("Lost my target"), returns: success)
I wrote it a bit differently then your original, but the general idea is that you need to handle the failure case of your chasing. Once you start chasing (and recording their position) if you fail it means you lost the target, so you can put a selector around that and handle the failure by continuing to head to the position. If you ever detect the target again, it’ll hit the constraint and fail and start at the top again.
As for your second issue, what would you like the AI to do instead of heading back to the original waypoints? If you wanted them to search around for the player instead, you could have a second waypoint network of search spots that he starts to follow, for instance. Whatever it is, this would end up being the success case for reaching the players last position, so where I have the debug “Lost my target”, you could put a sequencer, or another patrol setup, or have them do a dance, or anything you like.February 2, 2023 at 12:52 pm #40011
Wow thanks Sigil! So recording the position of the player worked perfectly. My AI now chases the player a bit further even after losing line of sight which is exactly what i wanted.
For my second issue, just like you said, i added a second way point network and had him just start patrolling from there and it worked great!
I ran into a new issue after these couple of days. After fixing everything you said from above and got it to work i started implementing a way for my player to take damage after my AI does his attack animation.
So as you said in one of your comments, i added a custom action and got it to pass damage to my script attached to my player which just contains his health at the moment. Now the issue i ran into is that my AI runs through his tree so fast that it goes from 100 -> 0 in a fraction of a second. So obviously i added a timer to this. This way he does his attack animation then the custom action,which sends 20 points of damage to the player health script, waits 1 second and finally repeats the 3 steps i just listed. Okay so this works great! THEN i decided to add a random node where he randomly picks which attack animation he does, because obviously i want a little random in my game. Well, this is where the problem kicks in because what i have is…..
-Attack 1 animation
-Send 20 damage to health script
-Attack 2 animation
-Send 15 damage to health script
So Random will select one of the sequencer to run which is fine and dandy but for some reason after the timer goes off it gets out of that sequencer and go to the other.
So now let me list my problems…
1) Is using the timer node even the best option for the AI’s animation + sending damage? i feel that it’s very unreliable because the animation isn’t necessarily 1 second exactly which would cause the AI to being doing damage either slower or faster rate than his animation is.
2)Should i be trying to use check state node? If so how does it work? I’ve already tried to use it numerous times and it always seems to do something different than what i thought it was going to do.
3)How do i go about, just a general direction, having the AI do no damage after dealing damage? essentially giving the player invulnerability after taking damage to give him a chance to get away and somehow having the AI kind of just idle or taunt or something after doing damage.
Edit: As i was posting this i realized that i didn’t have the sequencer node’s set to loop forever so that fixes part of my issue.
You must be logged in to reply to this topic.