Autonomous robot - moving from 1 object to the next object

This question falls in line with my last question: Unity 3D - create autonomous moving robot in house + first person camera movement

What I have

I have a 3D model of a house; a first-person camera with movement through the house; a robot that autonomously moves.

What I want

I want the autonomously moving robot to search the house for certain objects. I have placed 4 guns (same model) in the house.

This is the code I have now. This works for 1 gun; not multiple game objects:

using UnityEngine;
using System.Collections;

public class MoveTo : MonoBehaviour {

public Transform goal;

void Start () {
NavMeshAgent agent = GetComponent<NavMeshAgent>();
agent.destination = goal.position;
}
}


What I want - extra

If possible, I want it to communicate with the person navigating the "game" with the first-person camera. For example, if it finds a gun, I want it to say to the person "playing" the game: I found a gun. If it finds the next one: I found 2 guns; I found 3 guns; etc etc.

For that, I used the following code for the player:

using UnityEngine;
using System.Collections;

public class UGV : MonoBehaviour {

public Player player; //assign this variable in the inspector, or using another method

public void CallMethodBInPlayer(){
if(player != null){
player.MethodB();
}
}

public void MethodA(){
//do something (Robot)
}
}


And the same for the robot (but changed accordingly).

I will be honest with you that I have very little understanding of programming or Unity. I want you to know I've been looking for an answer for many hours but even though the idea might be too complicated for me just yet, I still hope you can (and want) to help me :)

To solve all of this problems you still have to write quite a lot of code. So this answer is just a general overview of what you need to do, not a complete implementation. When you need specific help with one of these points, feel free to ask it as a new question.

1. When you want multiple goals, you need to change public Transform goal; into an array of transforms by changing it to public Transform[] goals;. You can then assign as many goals as you want in the inspector.
2. Next you need to decide which of the goals to move to. Finding the ideal order to visit all the goals is a problem which is actually far more complicated than it looks at first glance. But a reasonable algorithm to get you going with a "good enough" order is to just move to the closest destination at first. How do you find which one is the closest? By creating one NavMeshAgent for each goal, call CalculatePath on each of them, see which one returns the shortest path and discard all the others. When you reached the chosen destination, reevaluate which remaining one is the closest now.
3. How do you define "finding a gun"? A possible definition could be "having an unobstructed direct line of sight". The method which can help you to find if there is such a line between the robot and the goal is the method Physics.Linecast.
• Thanks a lot for your quick reply! I have a semi-working solution. I got no errors, I have an array with 2 items, and the following code: public Transform[] goals; void Start () { NavMeshAgent agent = GetComponent<NavMeshAgent> (); agent.destination = goals[0].position; if (agent.transform.position == goals[0].position) { agent.destination = goals[1].position; } } } But it's not moving from location 1 (goals[0]) to location 2 (goals[1]). What am I doing wrong? Thanks a lot once more!! – juuljuup May 29 '16 at 20:36
• When you need specific help with one of these points, feel free to ask it as a new question. – Philipp May 29 '16 at 20:42
• – juuljuup May 29 '16 at 20:49

You don't need to add the Guns via the inspector one by one. Just execute FindObjectsOfType at the start of your game:

Gun[] guns;

void Start () {
guns = FindObjectsOfType<Gun> ();
foreach (Gun gun in guns) {
Debug.Log("Found " + gun.gameObject.name);
//Now you can access their location with gun.gameObject.transform.position
}
}


What do you mean by "talking to the player"?
You could make a GUI for that:

Set up the OK-Button to close (hide) the Message:

...and now you'll just have to add a little bit of code to the robot:

public UnityEngine.UI.Text playerMessage;
public GameObject panel;

public void showMessageToPlayer(string message){
playerMessage.text = message;
panel.SetActive (true);
}


Assign the two variables via the inspector and now the robot can show a text-message to the player by calling the showMessageToPlayer-method.