Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

AI agent scripting problem humanoid vs animal/vehical

Discussion in 'Scripting' started by Ridgerunner, Jul 18, 2017.

  1. Ridgerunner

    Ridgerunner

    Joined:
    May 31, 2014
    Posts:
    34
    I have a script that I have found and I'm trying to make it work to alien my AI Agent to the y an z axis mostly the y axis to the ground while still having my AI controller script control the x axis (left right)

    This scripted works for aliening the AI Agent to the ground, But it locks the x axis to a world and will not let the AI Agent rotate left or right on the x axis I need the axis to be free to rotate on x axis any direction, Can some one give a hand with my problem I think I need to pass in a local transform in to the Euler of the AI Agent but can't seem to figure it out ,

    Also das any one know if Unity has planes to add an humanoid vs animal/vehical script?
    As we all know a humanoid Agent walking upright so there really is no problem with humanoid AI Agents ,But with an animal/vehicals they follow the contour of the ground so it looks really bad when animal/vehicals AI Agent dos not follow the contour of the ground.


    Here is the script I'm trying to convert


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class EnemyMeshAline : MonoBehaviour {

    public GameObject target;
    float curDir = 0f; // compass indicating direction
    Vector3 curNormal = Vector3.up; // smoothed terrain normal
    public float turn;

    // Update is called once per frame
    void Update ()
    {

    curDir = (curDir + turn) % 360; // rotate angle modulo 360 according to input
    RaycastHit hit;
    if (Physics.Raycast(target.transform.position, -curNormal, out hit))
    {
    curNormal = Vector3.Lerp(curNormal, hit.normal, 4*Time.deltaTime);
    Quaternion grndTilt = Quaternion.FromToRotation(Vector3.up, curNormal);
    target.transform.rotation = grndTilt * Quaternion.Euler(0, curDir, 0);
    }
    }
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    for one.. use code tags. That helps a bit.


    I tinkered with it to make it run. I had to add movers and such to make it follow the target.

    For the model, I used a capsule, but attached it to an empty game object. That gameObject was set at the base of the capsule, so all my movement derived from the target.

    This being said, I would strongly urge you to use a CharacterController, and simply hide the graphic, then do your rotational stuff after the fact on it. This will give you a base for movement and be alot cleaner in the long run.

    This, will help you with understanding how to get the rotational surface from what you are working on.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. using UnityEditor;
    6.  
    7. using UnityEngine;
    8.  
    9. public class FollowGroundController : MonoBehaviour {
    10.  
    11.     public GameObject target;
    12.     public float speed = 8;
    13.     float curDir = 0f; // compass indicating direction
    14.     Vector3 curNormal = Vector3.up; // smoothed terrain normal
    15.     private bool isGrounded = false;
    16.     private int layer = 31;
    17.  
    18.     // Use this for initialization
    19.     void Start ()
    20.     {
    21.         var colliders = transform.root.gameObject.GetComponentsInChildren<Collider>();
    22.         foreach (var col in colliders)
    23.         {
    24.             col.gameObject.layer = this.layer;
    25.         }
    26.     }
    27.    
    28.     // Update is called once per frame
    29.     void Update () {
    30.         Vector3 position = transform.position;
    31.         float turn = 0;
    32.         transform.rotation = Quaternion.Euler(0, curDir, 0);
    33.  
    34.         if (this.target != null)
    35.         {
    36.             if (true)
    37.             {
    38.                 var dir = this.target.transform.position - position;
    39.                 dir.y = 0;
    40.                 if (dir.sqrMagnitude > 1)
    41.                 {
    42.                     position += dir.normalized * speed * Time.deltaTime;
    43.                 }
    44.             }
    45.  
    46.             var angle = Vector3.Angle(transform.forward, this.target.transform.position);
    47.             angle = transform.InverseTransformPoint(this.target.transform.position).x < 0 ? -angle : angle;
    48.             turn = Mathf.Min(angle, 180) * Time.deltaTime;
    49.         }
    50.  
    51.         var normal = Vector3.up;
    52.         RaycastHit hit;
    53.         if (Physics.Raycast(position + Vector3.up, -Vector3.up, out hit, 1, ~(1 << this.layer)))
    54.         {
    55.             normal = hit.normal;
    56.             this.isGrounded = true;
    57.             Debug.DrawLine(hit.point, hit.point + hit.normal, Color.red);
    58.             position = hit.point;
    59.         }
    60.         else
    61.         {
    62.             position += Physics.gravity * Time.deltaTime;
    63.             this.isGrounded = false;
    64.         }
    65.        
    66.         curNormal = Vector3.Lerp(curNormal, normal, 4 * Time.deltaTime);
    67.         curDir = (curDir + turn) % 360; // rotate angle modulo 360 according to input
    68.         Quaternion grndTilt = Quaternion.FromToRotation(Vector3.up, curNormal);
    69.         transform.position = position;
    70.         transform.rotation = grndTilt * Quaternion.Euler(0, curDir, 0);
    71.     }
    72. }
    73.  
    This all being said, I would use this type of script on a car, or some such. A horse, or animal, I would prevent the whole thing from tilting sideways. That looks kind of weird.
     
  3. Ridgerunner

    Ridgerunner

    Joined:
    May 31, 2014
    Posts:
    34
    I set my enemy AI Agent in the target slot that make it alien with the ground but it locks the agent to a world axis that not what I want to happen, And I have a separate AI agent controller script that handles free going left or right as it wishes or needs to traverse the ground to the waypoints, But need it be able go up ramps with out looking weird, I would like it to title on the y axis like a car would driving over a mouton, Do thing the script you send me will do that?
     
  4. Ridgerunner

    Ridgerunner

    Joined:
    May 31, 2014
    Posts:
    34
    My goal is to allow this script to have the AI agent align to the floor so it can tilt up and down stairs/ramps and only effect the Agent on the y axis an then allow Unity navmeshagent script to go any direction on x axis left or right that the navmeshagent script takes it.

    This script locks the left and right x axis direction an dose not allow the Unity navmeshagent script to go any direction left or right that the navmeshagent script takes it.

    So how do I fix this and take out Quaternion.Euler(0, curDir, 0); and replace it so that the Unity navmeshagent script can have free control on x axis.

    Can some one help with a simple way to fix this, I just need a the 360 axis on x axis to not be effect.
    Thanks please help.
     
    Last edited: Jul 21, 2017
  5. Ridgerunner

    Ridgerunner

    Joined:
    May 31, 2014
    Posts:
    34
    What should I do for cod tags