AI Aim and Shoot, should be easy but I don't get it

Leorid

New member
Ok, so I have an enemy AI character, built the character with the 3rd person ultimate character controller kit and he is running around, when I move the UnityEngine.NavMeshAgent - thats cool.

1.)
Also I can turn on Aiming at start if I set the ability to automatic ... but not inside a script
this:

C#:
EventHandler.ExecuteEvent<bool>(_character.gameObject, "OnAimAbilityAim", true);

has almost no effect, the weapon seems to move slightly, but it's not aiming forward.

2.)
ok, next thing, setting the aim direction - I thought creating and attaching a look source with the event:

C#:
lookAtPlayer = new LookAtPlayer();
EventHandler.ExecuteEvent<ILookSource>(_character.gameObject, "OnCharacterAttachLookSource", lookAtPlayer);

public class LookAtPlayer : ILookSource
{
    [...] interface implementation [...]
}

would work, but somehow, this event is passed to the KinematicObjectManager.cs and there it looks for an attached camera component
( m_AttachedCamera = lookSource.GameObject.GetCachedComponent<CameraController>();)
- of course my AI doesn't have a camera, so I'm stuck here.

3.)
Third point: Shooting
The documentation was no help regarding this point, so there are items, itemAbilities, equippedItems and you can Use() them or Fire() ShootableWeapons - all this may can be done with the eventSystem too - but I have no idea how. Digging through the code, the forum and everything, I think there must be a super simple answer but I can't find it.


Why can't I just use the BehaviourTree solution - well Humans are not the only enemies in my game, I also have turrets, mines, drones and the human ones can be quite stupid, no complex behaviour needed.
And the way the code is structured, there must be a good solution. :)

Thanks in advance


Whole class here:


C#:
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Events;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyAttack : MonoBehaviour
{
    public float attackRangeMin;
    public float attackRangeMax;

    UltimateCharacterLocomotion _character;

    public Transform target;
    public LookAtPlayer lookAtPlayer;

    bool _lastIsAiming = false;
    public bool isAiming = false;

    IEnumerator Start()
    {
        yield return null;

        _character = GetComponentInParent<UltimateCharacterLocomotion>();
        if (!_character) throw new System.Exception("Character is NULL");
        if (!_character.gameObject) throw new System.Exception("Character GO is NULL");

        lookAtPlayer = new LookAtPlayer();

        // Throws exception so outcommented to test the aiming
        //EventHandler.ExecuteEvent<ILookSource>(_character.gameObject, "OnCharacterAttachLookSource", lookAtPlayer);

        lookAtPlayer.Transform = target;

        _lastIsAiming = isAiming;
    }

    private void Update()
    {
        if (_lastIsAiming != isAiming)
        {
            Debug.Log("Aim: " + isAiming);
            EventHandler.ExecuteEvent<bool>(_character.gameObject, "OnAimAbilityAim", isAiming);
            _lastIsAiming = isAiming;
        }

        if (Input.GetKeyDown(KeyCode.O))
        {
            // fire
        }
    }

    public class LookAtPlayer : ILookSource
    {
        public GameObject GameObject { get; set; }

        public Transform Transform { get; set; }

        public float LookDirectionDistance { get; set; }

        public float Pitch => 0;

        public Vector3 lookDirection;
        public Vector3 lookPosition;

        public Vector3 LookDirection(bool characterLookDirection)
        {
            return lookDirection;
        }

        public Vector3 LookDirection(Vector3 lookPosition, bool characterLookDirection, int layerMask, bool useRecoil)
        {
            return lookDirection;
        }

        public Vector3 LookPosition()
        {
            return lookPosition;
        }
    }
}
 
Last edited:
has almost no effect, the weapon seems to move slightly, but it's not aiming forward.
This does not start the aim ability. You'll want to start the Aim ability with TryStartAbility.

ok, next thing, setting the aim direction - I thought creating and attaching a look source with the event:
When you created your agent did you select AI in the Character Manager? This should add the Local Look Source component. If you need extended functionality I would just subclass that component. The Local Look Source does allow you to change the look direction.

The documentation was no help regarding this point, so there are items, itemAbilities, equippedItems and you can Use() them or Fire() ShootableWeapons - all this may can be done with the eventSystem too - but I have no idea how. Digging through the code, the forum and everything, I think there must be a super simple answer but I can't find it.
You can shoot by starting the Use ability, similar to the Aim ability. In most cases you do not need to manually send an event - the abilities will send that event for you if they are necessary.
 
I was right and I was wrong at the same time xD
It is actually super simple - it just has nothing to do with events or getting items themselfs.

Sooo - I had a look at the "LocalLookSource" of the enemy, assigned the Head-Bone to the LookTransform (the point from where he should look) and then wrote this litte script that does everything I wanted it to do, glorious, this asset is just awesome. ^^
(and assigned aimTarget to the chest of my player in the "EnemyAttack" Script)

The cool thing is - you don't have to get the item at all, to get the ItemAbilities, just use
C#:
ultimateCharacterLocomotion.GetAbility<TypeOfTheItemAbilityYouWantToReceive>();
Calls like TryStartAbility() and TryStopAbility() also work for the item abilities, simple, sweet, awesome. ^^

Thanks for your help, Justin. :)


C#:
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities.Items;
using UnityEngine;

public class EnemyAttack : MonoBehaviour
{
    UltimateCharacterLocomotion _character;

    public Transform aimTarget;

    public bool isAiming = false;

    Aim aimItemAbility;
    Use useItemAbiltiy;

    LocalLookSource _characterLookSource;

    void Start()
    {
        _character = GetComponentInParent<UltimateCharacterLocomotion>();
        _characterLookSource = GetComponentInParent<LocalLookSource>();

        useItemAbiltiy = _character.GetAbility<Use>();
        aimItemAbility = _character.GetAbility<Aim>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            // toggle aiming
            isAiming = !isAiming;

            if (isAiming)
            {
                _characterLookSource.Target = aimTarget;
                _character.TryStartAbility(aimItemAbility);
            }
            else
            {
                _characterLookSource.Target = null;
                _character.TryStopAbility(aimItemAbility);
            }
        }

        if (Input.GetKey(KeyCode.O))
        {
            // fire
            _character.TryStartAbility(useItemAbiltiy);
        }
    }
}
 
Top