I have this enemy that I want to follow the player among navigation and attack with a melee strike upon reaching him but the enemy just ends up bumping into the player instead. The unfortunate part is I actually had the enemy attacking perfectly the first time but, due to Hard-Drive failure, I lost the entire game save for the models and textures I managed to extract from the apk file I had generated and now I can’t figure out how I got it working the first time. I can kill the enemy just fine but not much of an enemy if it can’t hurt me. Perhaps someone could help me figure it out?
using UnityEngine;
using System.Collections;
public class CyberVermin : MonoBehaviour {
public int VerminWalking = 0;
public int VerminAttacking = 0;
public int CyberHealth = 15;
public GameObject CyberVerminDead;
public GameObject Blood_Spatter;
Animator animator;
public Transform goal;
void Start ()
{
animator = GetComponent<Animator>();
}
void Update ()
{
if (VerminAttacking == 0)
{
NavMeshAgent agent = GetComponent<NavMeshAgent> ();
agent.destination = goal.position;
int VerminWalking = 1;
animator.SetFloat ("VerminWalk", VerminWalking);
}
if (CyberHealth == 0)
{
Instantiate(CyberVerminDead, gameObject.transform.position, gameObject.transform.rotation);
Destroy(gameObject);
}
}
void CyberAttack()
{
int VerminWalking = 0;
int VerminAttacking = 1;
animator.SetFloat ("VerminWalk", VerminWalking);
animator.SetFloat ("VerminAttack", VerminAttacking);
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Pearl")
{
Instantiate(Blood_Spatter, gameObject.transform.position, gameObject.transform.rotation);
CyberHealth -= 1;
}
if (col.gameObject.tag == "Player")
{
CyberAttack();
}
}
}
Is your player properly tagged as “Player”?
Sometimes, we forget to do this part.
Also, I do suggest that you create a Navmesh Agent variable, and set it in Start, instead of getting it on every update, which is more intensive.
Not only do I have it tagged as Player but children objects along with it. Thanks for the second tip, I’ll keep a note of it but right now I’m concerned with my enemies posing an actual threat.
Okay, does the Collision trigger fire when the enemy comes into contact with the player?
You might try adding a few Debug.Log statements in there just to make sure.
For example:
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Pearl")
{
Instantiate(Blood_Spatter, gameObject.transform.position, gameObject.transform.rotation);
CyberHealth -= 1;
}
if (col.gameObject.tag == "Player")
{
Debug.Log("I hit the player!");
CyberAttack();
}
}
If you do not see that log statement show up in the console when the little vermin hits the player, then one of the following is the problem:
- The vermin is not actually colliding with the player for some reason.
- What ever the vermin is colliding with, is not tagged as Player.
Also, I noticed that the CyberAttack method does not actually do any damage to the player, it just plays the attack animation.
Does the vermin actually play the attack animation, but just does not hurt the player?
If so, it is because you forgot to apply damage to the player after playing the attack animation.
I was going to instantiate a trigger cube to deal the actual damage once I was able to make its attack actually work but it looks like you identified the source of the problem, collision. The Debug Log you suggested failed to show, meaning it’s not actually colliding with the player at all, despite bumping into the player and physically making him move. Here’s some information about the Inspectors of both if this helps?
Are there any children objects connected to the player that might have their own colliders?
Also, I have another Debug.Log you might want to try:
void OnCollisionEnter(Collision col)
{
Debug.Log(" I hit " + col.gameobject.name + "which has the tag: " + col.gameobject.tag);
if (col.gameObject.tag == "Pearl")
{
Instantiate(Blood_Spatter, gameObject.transform.position, gameObject.transform.rotation);
CyberHealth -= 1;
}
if (col.gameObject.tag == "Player")
{
CyberAttack();
}
}
This will hopefully give us a little more information on what is going on.
That gave me a compiler error.
Ops! That is my bad, forgot to capitalize the “o” in gameobject.
Replace the debug with this one:
Debug.log("I hit " + col.gameObject.name + " which has the tag: " + col.gameObject.tag );
Okay, now THIS is weird. Literally nothing shows up period. I know it works, though, because it appears when I shoot it, as shown in the part with the Pearl tag. Is there something preventing the Cyber Vermin from colliding at all? Clearly, the Player and enemy’s colliders aren’t agreeing with each other or something.
Check the player’s collider while in play mode, and make sure it is not set to trigger.
If it is, then something is changing the collider into a trigger when you start the game.
One thing you might try, is creating an empty game object with a capsule collider, and parent it to the player.
Make sure to tag this game object as Player, and you might want this collider to be a little bigger than the one used by the Character Controller. Then run the game, and see if you get the same result.
EDIT:
Does your player have a Rigidbody component?
If not, try adding one.
Of course! I can’t believe I forgot that I needed a rigidbody, I am incredibly stupid.
I still can’t get the thing to actually go into its attack routine at this stage but at least now it’s possible to die since I currently have it set up to harm the player just on touching the Vermin itself. It’s no longer a collision problem, at least, the log correctly identified it as touching the player.
You mentioned something about putting a nav into the starter instead of with an update, would it allow for the creature to stop while it’s attacking?
It would allow you to use the NavMeshAgent outside of the Update function without needing to use GetComponent every time you needed to access it.
What you might try to do, is set the NavmeshAgent’s destination to the Vermin’s own position while it is attacking.