How to setup an NPC character? Is there a tutorial?

Hi,

I am using Third Person Controller and have setup my player correctly.
I want to setup my NPC but it seems that the locomotion handler depends directly on PlayerInput so once I remove that it throws exceptions.
Shall I derive a class from PlayerInput that actually uses AI to derive movement?
Is there a more straight forward way?
The npc will depend mainly on navmesh.

Thanks for advance.
 
Hi @Justin
Thank you for getting back to me so quickly.
I have selected AI and things are working great except that the ability NavMeshAgentMovement only rotates the character and doesn't move it.

I have verified that InputVector has a value of (0.0f, 1f) from the following code.

m_CharacterLocomotion.InputVector = InputVector;
Debug.Log(m_CharacterLocomotion.InputVector);

So I guess LocalLookSource doesn't really move the character, only rotate.
Is there a simple solution?
 
@Andrew
You can run SetDestination on the NavMeshAgent to set its target destination for movement.
Thank you very much but this is exactly what I did and it didn't work.
I have confirmed that the InputVector does indeed change but since this is an AI character the input vector has no effect.
The AI character only rotates toward the target but doesn't move toward the target.

EDIT:
------
I am sorry I thought you were talking about the nav mesh ability not the agent. OK, I will try with the agent.
 
@Andrew
You can run SetDestination on the NavMeshAgent to set its target destination for movement.
OK I tried setting navmeshagent's destination directly and it didn't work.
In that case I would need to check the navmeshagent's velocity, rotation parameters etc and I will lose the advantage of using Third Person Controller asset.
It makes sense to make NavMeshAgentMovement work with AI characters that way there is a clear advantage of using Third Person Controller
 
@Andrew
I am sure there is someway to do it using Third Person Controller instead of setting navmeshagent destination directly, otherwise integration with behaviour designer wouldn't be possible.
 

Justin

Administrator
Staff member
You can set the NavMeshAgent destination directly, this is what Behavior Designer does. For movement there isn't a need to specifically call anything within TPC as the NavMeshAgentMovement ability reads the velocity and moves based on that.
 
@Justin
You can set the NavMeshAgent destination directly, this is what Behavior Designer does. For movement there isn't a need to specifically call anything within TPC as the NavMeshAgentMovement ability reads the velocity and moves based on that.
Thank you for the hint. I tried that.
As you can see from the screenshot the navmesh agent's destination is set, the forward movement is set to 1.0 but it seems stuck and doesn't move.
I baked the nav mesh. There must be something I am doing wrong but I am not sure what it is.
1594212796966.png
 
@Justin @Andrew
I finally found the root of the problem but haven't found a solution yet. It's not a problem with the nav mesh it self. The capsule collider falls and penetrates the ground. I guess the collision between the capsule collider and the ground collider is the root of the issue because once I remove the capsule collider the character moves.

1594292862176.png

Or if I took the character too far above the ground and let it fall, it falls without penetrating the ground and it moves like below.

1594292985228.png

How to prevent the main character collider from penetrating the ground?
 
Here is what happens. The first frame is before I press the play button in Unity then as you can see the first frame moves the nav mesh agent to the ground, then the collider falls until it penetrates the ground.
If I start the prefab at much greater distance from the ground the penetration doesn't happen.

ezgif-3-0ddee5024201.gif
 
Update:

I unchecked stick to the ground and now the collider doesn't penetrate the ground, however the character doesn't move until I delete the cylinder collider.
This time it doesn't matter how high I place the player, it never moves until I remove the cylinder collider at runtime.

1594297128437.png
 

Justin

Administrator
Staff member
Is that a capsule collider or a sphere collider on your character? If you don't have the NavMeshAgent component does it settle properly?
 
Is that a capsule collider or a sphere collider on your character? If you don't have the NavMeshAgent component does it settle properly?
It is a capsule collider with low height so it looks like a sphere.
Here it is without the navmesh agent and without the nav mesh ability.
It's worth mentioning that while the nav mesh agent and ability are stuck if I deleted the cylinder collider only the nav mesh agent gizmo moves but the model itself stays at place.
The collider is not on the Colliders child gameobject but on the main character gameobject. I did that to be able to register to OnObjectImpact on my main character's script.

I do get sometimes the problem of spinning too fast when no destination is set the same with the behavior designer sample scene except that I am not using behavior designer in this project.

1594338361208.png
 
@Justin
commenting out m_MoveDirection = platformIndependentMoveDirection + m_PlatformMovement; did solve the problem. Obviously this is not a scalable solution. This line is in DeflectHorizontalCollisions method. Can you guess what is wrong from this info?

And increasing nav mesh agent's stopping distance solved the spinning problem.
 
@Justin
I have checked m_CombinedRaycastHits in DeflectHorizontalCollisions and it does detect the ground obviously.
How do you suggest to fix that?
Can I exclude ground from horizontal detection but keep horizontal detection for other game objects?
 
@Justin
When I moved the cylinder collider back as a child of Colliders it worked.
The reason I moved it to the parent object in the first place is to listen to OnObjectImpact event.
I think OnObjectImpact event should be fired not only for colliders gameobject but for the parent game object that has CharacterLocomotion behaviour.

Something like that:
C#:
var character = m_CollidersHit[i].transform.gameObject.GetComponentInParent<CharacterLocomotion>();

EventHandler.ExecuteEvent<float, Vector3, Vector3, GameObject, object, Collider>(character.gameObject, "OnObjectImpact", hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator, this, m_CollidersHit[i]);
 

Justin

Administrator
Staff member
Glad you found the cause. Yeah, the locomotion excepts the colliders to be in a certain structure so you don't want to move them.

I like your OnObjectImpact suggestion.
 
Top