KitPolosa
KitPolosa

Reputation: 39

Ranged attack in Unity3D

I have two objects: a player and an enemy. The main problem is the enemy, which should start shooting at the player when it approaches him at a certain distance (in short, just start the animation). At first I tried to implement this through Vector 3, as with other ordinary opponents. But he is as stupid and crutch as possible, however, you yourself can see everything in the pinned.

I started to implement it more allegedly correctly, through the trigger and the collider (box collider) of the enemy itself. And everything works right as it should, but there is a nuance. The enemy also has boxing implemented through the box collider, the player, hitting which, causes damage to him. There is only one box collider for these two tasks, and since I had to increase this collider so that the enemy could stop in front of the player at a certain distance. Because of this, the player can hit at a great distance (at which the enemy can shoot) from the enemy and the enemy takes damage anyway.

I tried to make a separate object the size of the enemy himself and use it as a box to receive damage. Then he already transmits data about receiving damage to the enemy object. But this does not work, all links between scripts and objects are made, but he does not want to transfer data. That is, simply making two colliders for different tasks does not work. In general, here my powers are all. I searched the entire Internet, but I did not find how to implement this mechanic in a different way so that it does not conflict with others. Therefore, I ask the help of the local experts, where I screwed up.

private Animator ch_animator;
// Start is called before the first frame update
void Start()
{
    myAgent = GetComponent<NavMeshAgent>();
    myAnim = GetComponent<Animator>();
    EnemyH = GetComponent<GDHealth>();
}

// Update is called once per frame
void Update()
{
    dist = Vector3.Distance(/*checker.*/transform.position, target.transform.position);
    if (dist > range)
    {
        myAgent.enabled = false;
        myAnim.SetBool("Idle", true);
        myAnim.SetBool("Move", false);
        myAnim.SetBool("Attack", false);
    }
    if (dist <= range & dist > atRange)
    {
        myAgent.enabled = true;
        myAgent.SetDestination(target.position);
        myAnim.SetBool("Idle", false);
        myAnim.SetBool("Move", true);
        myAnim.SetBool("Attack", false);
    }
    if (dist <= atRange)
    {
        StartCoroutine(Attack());
    }
    if (PlayerH._health <= 0)
    {
        atRange = 0;
    }
    if (EnemyH._health < 0)
    {
        myAgent.enabled = false;
    }
}

public IEnumerator Attack()
{
    yield return new WaitForSeconds(0.5f);
    myAgent.enabled = false;
    myAnim.SetBool("Idle", false);
    myAnim.SetBool("Move", false);
    myAnim.SetBool("Attack", true);
}

void OnTriggerStay(Collider col)
{
    if (col.tag == "Player")
    {
        //gameObject.GetComponent<Animator>().SetBool("Attack", true);
        StartCoroutine(Attack());
        transform.LookAt(col.transform.position);
        transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
    }
}
void OnTriggerExit(Collider col)
{
    if (col.tag == "Player")
    {
        myAgent.enabled = true;
        myAgent.SetDestination(target.position);
        myAnim.SetBool("Idle", false);
        myAnim.SetBool("Move", true);
        myAnim.SetBool("Attack", false);
        //gameObject.GetComponent<Animator>().SetBool("Attack", false);
    }
}

enter image description here

Upvotes: 0

Views: 600

Answers (1)

bartol44
bartol44

Reputation: 562

But this does not work, all links between scripts and objects are made, but he does not want to transfer data.

From this description it could be anything: wrong layers, no rigidbody on either of objects, misstyped tags in OnTriggerStay method.

In my project, I successfully created 2 colliders for 2 separate tasks, so this is how I would see it in your problem:

  1. Use two colliders

Attach one collider with one script to the enemy object - this collider should have a size of the enemy. The OnTriggerStay method here should deal damage to the enemy, check for death, etc. Create child object to the enemy. Attach new collider to it with the size of enemy's attack range. Attach a script with OnTriggerStay method that will stop enemy and begin ranged attack (or whatever you want to do).

If this doesn't work: check collision matrix or try adding a kinematic rigidbody to either of objects.

  1. Measure distance between player and the enemy in update (which you are already doing) and apply necessary code based on distance (stop or attack) thus replacing one of the colliders.

Hope that helps!

Upvotes: 0

Related Questions