News › Forums › RAIN › General Discussion and Troubleshooting › Integrating Rain AI with my code
Tagged: custom motor, override
This topic contains 17 replies, has 4 voices, and was last updated by Ibrahim 1 year, 1 month ago.
-
AuthorPosts
-
January 13, 2023 at 9:34 pm #39862
I’m finally getting to the point where I want to implement Rain AI into my code. The thing is, I have a body script that does all of the heavy lifting and I really just want to use Rain AI as mainly the brains of the operation and pathfinding. All body things, sitting, standing, walking, etc. I want to intercept the code that does the walking and have it only modify a variable I want it to so that it still functions within my system. Since we don’t have the actual code for the system, what would be the best way to do this?
I have other questions, but let me start here since this is a basic part of my setup.
January 14, 2023 at 1:48 am #39865Hi,
I am not sure if I understood what you want correctly. But have you tried to make a reference to the AIrig and access memory variables using the code, and use these variables to control your behavioral tree?
It could look something like this:
using RAIN.Core; using UnityEngine; using System.Collections; public class MainController : MonoBehaviour { private AIRig _aiRig = null; void Awake() { _aiRig = GetComponentInChildren<AIRig>(); } void Start () { } void Update () { _aiRig.AI.WorkingMemory.SetItem<bool>("boolMemoryVariable", MyGameController.valueOfVaviable); } }
January 14, 2023 at 10:07 am #39866Well, currently, my “mind” script generates movement coordinates that are updated every frame by the “body” of the entity. Looking at Rain AI, I see that there are three motor types, but the custom motor isn’t there (even though I see it on the Wiki). I don’t want the AI program to move, I just want it to pass the variables to the “body” every frame like my current setup does. I haven’t found a way for it to do this. Basically, I only want the Rain AI system to make choices, but not actually DO them. I want the requested actions to be passed to the body script of the entity. This includes moving around. I hope this is a little clearer.
January 14, 2023 at 11:46 am #39867I am not the best one to provide answers about RAIN, but I try my best.
I think you can make a set of variables in the memory of the aiRig, and use these variables in your BT in the mind of your AI. You can access these variables in your “body” script and interpret it in your own way to convert it to actions.
// In the memory you set "nextDestination". // In BT you assign the value of the variable. // In the motor script you access this variable. MoveToNextDestination(_aiRig.AI.WorkingMemory.GetItem<GameObject>("nextDestination")); ... void MoveToNextDestination(GameObject) { // Your motor code.. }
January 14, 2023 at 2:09 pm #39868I’d like for it to calculate where to go, but instead of actually adjusting the transform itself, it just stores the values in a variable of my choosing. Maybe I’m not really understanding what you’re suggesting, either.
January 14, 2023 at 2:54 pm #39869Instead of using a GameObject, you can use a Vector3 to store the new values of the destination. And access these values from the “motor” script.
I would like to point out here that the BT by itself (as far as I learned) can not make heavy computations by itself. So to compute the values of the new destination you’ll need to compute it by another script and feed them into the BT. Afterward use these values from the BT into the “Motor” script.
If you can share real code and BT maybe you get a better help.
January 14, 2023 at 3:13 pm #39870Basically, the body script checks the Vector3 intendedDir every frame.
The mind generates the intended direction when it’s moving or chasing something (like the player).
[code] private void Chasing() { float cordX = (target.transform.position.x - gameObject.transform.position.x); float cordZ = (target.transform.position.z - gameObject.transform.position.z); intendedDir = new Vector3(cordX, 0, cordZ).normalized; } [/code]
This is calculated by the mind. So I want Rain AI to provide the intended direction without modifying the actual transform like it does now. Like I said, I just want the AI to request to do things, not actually do them.
January 14, 2023 at 4:02 pm #39875I think what you are going to want to do is to override a few functions in the BasicMotor to override the actual movement of the AI’s body. Something like this should work:
using RAIN.Motion; using RAIN.Serialization; using UnityEngine; [RAINSerializableClass] public class OverrideMotor : BasicMotor { public override void ApplyMotionTransforms() { // This takes the acceleration, velocity, and position and figures out a new position // for the kinematic (which just holds this information in one location) AI.Kinematic.UpdateTransformData(AI.DeltaTime); // This applies the result from above to the AI's body, you can remove this and call your // code instead using the new position/orientation or you could just use the velocities from above AI.Body.transform.position = AI.Kinematic.Position; AI.Body.transform.rotation = Quaternion.Euler(AI.Kinematic.Orientation); } }
You can select the motor from the drop down in the AI’s motor tab (3rd tab I think) after you add this code to your project.
January 14, 2023 at 4:07 pm #39876Thanks for the information. I might be able to work with this. I’ll give it a shot in a couple of minutes.
What about other cases where I just want the Rain AI to request a function (like attacking) instead of having it actually do the attacking?
January 14, 2023 at 4:23 pm #39877RAIN doesn’t really know about things like attacking out of the box. If you are using a behavior tree you would likely need a custom action to handle the attack and you could access your code from there:
using RAIN.Action; [RAINAction] public class AccessMyComponent : RAINAction { private MyComponent _myComponent = null; public override void Start(RAIN.Core.AI ai) { base.Start(ai); if (_myComponent == null) _myComponent = ai.Body.GetComponentInChildren<MyComponent>(); } public override ActionResult Execute(RAIN.Core.AI ai) { _myComponent.MyFunction(); return ActionResult.SUCCESS; } }
January 14, 2023 at 6:39 pm #39878Cool. That makes a lot of sense. I’ll play with this a bit and see what I come up with. Thanks for the help, guys. Was very insightful.
January 15, 2023 at 1:29 pm #39895I followed your example, but now my NPCs just run all over the place. They don’t idle or stand there waiting for something to happen like they should. Also, how does this tie into animation? I don’t have any animations set, but I’m curious about how the two systems interact with each other.
January 15, 2023 at 2:51 pm #39898Well the example I gave just shows you what our BasicMotor does, so it shouldn’t have behaved differently then the BasicMotor would have. That’s assuming nothing changed about it.
You said you wanted the AI to do all the calculations but not actually move the body right? You can take the bottom two lines where we assign position and orientation to the body, and comment them out. You can then use the AI.Kinematic to get what you need. It has Velocity, Rotation (angular velocity), Position, and Orientation. You can give your other class the intended direction (probably AI.Kinematic.Velocity, or AI.Kinematic.Velocity.normalized if you only want the direction).
As for animation, that can be complex, so perhaps we should fix the above issue first. A quick rundown though is this:
- Create a state machine (in the Mecanim Animator) to control your idling, walking, running etc.
- Create parameters in your state machine to control it, like a float parameter called speed that controls idling vs walking.
- In RAIN, if using the MecanimMotor, add the Speed parameter (or whatever you need) to your motor (drop down at the bottom of the MecanimMotor).
- In RAIN, if using a custom motor, get the Animator off of the Body and call SetParameter to set any values you need (like Speed or Velocity).
If you haven’t used the animation state machines yet, you may want to check out any examples or tutorials Unity has on that before trying to tie RAIN into it. If you are familiar with the state machines (or once you are) I can help you hook up your custom motor to it.
January 15, 2023 at 11:31 pm #39906Thanks for responding quickly. I’m pretty happy with the help I’ve been getting and I just wanted to point that out. It’s been extremely helpful.
Originally, I did what you suggested originally, but looking at it now, it seems like I was using the wrong values. I need the direction vector which should be (targetpoint.transform.position - mypoint.transform.position). Is the previous position cached somewhere so I can use that value to calculate the direction vector? Right now, I’m trying to use transform.forward, but it’s leading to some unnecessary problems.
As for animation, it’s all handled via my animation state machines. All I have to do is enter the correct state and the animation will play. Just gotta make sure the right values are transferred. This is why I just want Rain AI to “request” not “do”. When it’s ready to do something, it sends a request to the state machine and it decides whether that can be done or not. So far I think I have the general gist of it, but gotta get this moving around thing solved first.
- This reply was modified 1 year, 2 months ago by EDarkness.
January 16, 2023 at 10:18 pm #39910From my example you’ll want to use AI.Kinematic.Velocity for your intended direction, after UpdateTransformData is called. That will represent the direction the AI would have moved if you let RAIN handle the movement.
-
AuthorPosts
You must be logged in to reply to this topic.