News Forums RAIN General Discussion and Troubleshooting Use animator of child object

This topic contains 19 replies, has 2 voices, and was last updated by  Hoju 1 year ago.

Viewing 5 posts - 16 through 20 (of 20 total)
  • Author
    Posts
  • #33564

    prime
    Keymaster

    Here’s the mecanim set parameter script. I have this hardcoded to only work with float params, but you can change it as necessary. It is intended to work like the built-in script, except it will try to use the Unity Animator associated with the RAIN Animator. So, if you use this along with the RAINElement I posted previously, things should work correctly for you.

    using UnityEngine;
    using RAIN.Core;
    using RAIN.Action;
    using RAIN.Representation;
    using RAIN.Animation;
    [RAINAction("Custom Mecanim Set Parameter")]
    public class CustomMecanimSetParameter : RAINAction
    {
        public Expression ParameterName = new Expression();
        public Expression ParameterValue = new Expression();
        public Expression DampTime = new Expression();
        private MecanimParameterValue parameterValue = new MecanimParameterValue();
        private Animator mecanimAnimator = null;
        /// <summary>
        /// Use the Unity Animator associated with the RAINAnimator if possible
        /// </summary>
        public override void Start(AI ai)
        {
            if (ai.Animator is MecanimAnimator)
                mecanimAnimator = ((MecanimAnimator)ai.Animator).UnityAnimator;
            if (mecanimAnimator == null)
                mecanimAnimator = ai.Body.GetComponentInChildren<Animator>();
            parameterValue.parameterName = ParameterName.Evaluate<string>(ai.DeltaTime, ai.WorkingMemory);
            parameterValue.parameterValue = ParameterValue;
            parameterValue.parameterType = MecanimParameterValue.SupportedMecanimType.Float;
            if (DampTime.IsValid)
                parameterValue.dampTime = DampTime.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory);
        }
        /// <summary>
        /// On Execute, the specified MecanimParameter is set into the mecanimAnimator
        /// </summary>
        /// <returns>SUCCESS on normal execution, FAILURE if a mecanim animator could not be found</returns>
        public override ActionResult Execute(AI ai)
        {
            if (mecanimAnimator == null)
                return ActionResult.FAILURE;
            parameterValue.SetParameter(mecanimAnimator, ai);
            return ActionResult.SUCCESS;
        }
    }
    #33565

    prime
    Keymaster

    A couple of issues on the rotation:

    1) Make sure you have “allow 3D rotation” set to true (checked) on your Motor if you want to rotate in the X axis. By default the AI only rotates on the Y axis.

    2) Before you start rotating, determine what direction you want to face. Rotating 180 on the X axis is pretty particular - it means both turning around and facing upside down. If that’s what you want, then you will have to give the AI a little help to get it right, because there is more than one way to be “facing” in that overall direction.

    3) Since you are doing this in a custom action, don’t use any of the Motor Move commands. It is easier to just rotate the game object directly.

    4) It will work best if you adjust the ai Kinematic. For example:

    private Vector3 newOrientation;
    public void Start(AI ai)
    {
      newOrientation = ai.Kinematic.Orientation;
      newOrientation.x = Mathf.Abs(MathUtils.WrapAngle(newOrientation.x + 180f));
    }
    public ActionResult Execute(AI ai)
    {
      if (Mathf.Abs(MathUtils.WrapAngle(ai.Kinematic.Orientation.x - newOrientation.x)) <= ai.Motor.CloseEnoughAngle)
        return ActionResult.SUCCESS;
      Vector3 turnRotation = RAIN.Motion.SimpleSteering.Align(ai.Kinematic.Orientation, newOrientation, ai.Motor.RotationSpeed, ai.DeltaTime);
      ai.Kinematic.Rotation = turnRotation;
      return ActionResult.RUNNING;
    }

    I didn’t actually test that code - just typed it - but it should be close. Let me know…

    • This reply was modified 1 year ago by  prime.
    • This reply was modified 1 year ago by  prime.
    #33590

    Hoju
    Participant

    Animation is working now! Thanks a million Prime.

    As for the rotation thing, 3D rotation is enabled. I misspoke when I said X axis. I was thinking the AI needed to be facing the opposite direction in the X, so I meant the Y axis. I changed the references in the code you posted to y already, though even with this code, the AI will still only rotate when the AI is facing left. Same behavior as the code I posted so maybe its not the code but something else.

    What I’m trying to do is while the AI is patrolling, it will pause after a time and right before it resumes patrolling, I want it to turn around for a moment and look behind for the player. All is working except for when the AI is already patrolling to the right. I have it on a waypoint route in a PingPong pattern. I’m gonna keep playing with it an see what I can come up with.

    #33593

    prime
    Keymaster

    Ok - this is all much simpler then. The mistake with your prior code is that it is testing for global left/right - i.e., only along the axis and not relative to the AI itself.

    So:
    1) Turn OFF 3D rotation. If you are doing normal character movement you want that off, otherwise the AI can do some very strange things.
    2) Create a custom action that sets a face target behind the AI:

    Vector3 faceTarget = ai.Kinematic.Position - ai.Kinematic.Forward;
    ai.WorkingMemory.SetItem<Vector3>("faceTarget", faceTarget);

    then add a Move node to your behavior tree that does not have a move target, but has Face Target set to faceTarget.

    This will cause the AI to pick a spot directly behind it (the custom action), set that as a variable in memory (faceTarget), and then turn to face it (move node).

    #33599

    Hoju
    Participant

    That worked perfectly! I knew it had to be something more simple. You’re awesome dude! Hopefully, I can get everything else myself from here. Thank you again!

Viewing 5 posts - 16 through 20 (of 20 total)

You must be logged in to reply to this topic.