0
\$\begingroup\$

The logic is that randomly each agent if he is at distance from other agent less then 2 stop moving rotate smooth facing to the other agent wait 3 seconds then both to rotate smooth back facing the next waypoint and keep moving to the waypoint.

There is also a possible that agent that is close to other agent less then 2 distance will not stop and rotate facing to it. The idea is to make random meetings between random agents.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentControl : MonoBehaviour
{
    public List<Transform> points = new List<Transform>();
    public bool randomMeeting = false;
    public float threshold = 3f;
    public float strength = 5f;

    private float speed;
    private int destPoint = 0;
    private NavMeshAgent agent;
    private GameObject[] agents;

    void Start()
    {
        agents = GameObject.FindGameObjectsWithTag("Agent");

        agent = GetComponent<NavMeshAgent>();
        var agentsDestionations = GameObject.FindGameObjectsWithTag("Waypoint");

        for (int i = 0; i < agentsDestionations.Length; i++)
        {
            points.Add(agentsDestionations[i].transform);
        }
        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = true;
        agent.speed = Random.Range(10, 50);
        speed = agent.speed;

        GotoNextPoint();
    }

    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        RandomMeeting();
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (!agent.pathPending && agent.remainingDistance < 2f)
        {
            GotoNextPoint();
        }
    }

    private void RandomMeeting()
    {
        if (randomMeeting)
        {
            GameObject randomAgent = agents[Random.Range(1, agents.Length)];
            if (Vector3.Distance(agent.transform.position, randomAgent.transform.position) <= threshold)
            {
                StartCoroutine(Meeting(randomAgent));
            }
        }
    }

    IEnumerator Meeting(GameObject randomAgent)
    {
        var targetRotation = Quaternion.LookRotation(randomAgent.transform.position - transform.position);
        var str = Mathf.Min(strength * Time.deltaTime, 1);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);

        yield return new WaitForSeconds(3);
    }
}

I added the RandomMeeting method. But it's far away from the behaviour I want.

UPDATE: Still not working. This is what I did so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentControl : MonoBehaviour
{
    public List<Transform> points = new List<Transform>();
    public bool isInMeeting = false;
    public float threshold = 5f;
    public float strength = 5f;

    private float speed;
    private int destPoint = 0;
    private NavMeshAgent agent;
    private NavMeshAgent[] agents;

    void Start()
    {
        agents = FindObjectsOfType<NavMeshAgent>();

        agent = GetComponent<NavMeshAgent>();
        var agentsDestionations = GameObject.FindGameObjectsWithTag("Waypoint");

        for (int i = 0; i < agentsDestionations.Length; i++)
        {
            points.Add(agentsDestionations[i].transform);
        }
        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = true;
        agent.speed = Random.Range(10, 50);
        speed = agent.speed;

        GotoNextPoint();
    }

    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        Meeting();
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (isInMeeting == false && !agent.pathPending && agent.remainingDistance < 2f)
        {
                GotoNextPoint();
        }
    }

    private void Meeting()
    {
        for (int i = 0; i < agents.Length; i++)
        {
            if (agent != agents[i])
            {
                float dist = Vector3.Distance(transform.position, agents[i].transform.position);
                if ( dist < threshold)
                {
                    agents[i].GetComponent<AgentControl>().isInMeeting = true;
                    isInMeeting = true;
                    agent.GetComponent<Renderer>().material.SetColor("_Color", Color.yellow);
                    agents[i].GetComponent<Renderer>().material.SetColor("_Color", Color.yellow);
                    StartCoroutine(Meeting(agents[i]));

                    break;
                }
            }
        }
    }

    IEnumerator Meeting(NavMeshAgent Agent)
    {
        var targetRotation = Quaternion.LookRotation(Agent.transform.position - agent.transform.position);
        var str = Mathf.Min(strength * Time.deltaTime, 1);
        agent.transform.rotation = Quaternion.Lerp(agent.transform.rotation, targetRotation, str);

        yield return new WaitForSeconds(10);
        Agent.GetComponent<AgentControl>().isInMeeting = false;
        isInMeeting = false;
    }
}

The script is attached to a Prefab and then I duplicate the prefab so I have many agents. So each agent have the script attached.

The logic as I see it should be that each two or more agents that the distance is less the threshold should stop rotating smooth facing each other waiting 10 seconds rotate back and continue each one on the way they was.

A meeting can be between two or more agents. And if an agent is on the way and there is already a meeting he can join the existing meeting or maybe not to join and keep moving on his way the logic is to create some kind of meetings or more to say groups of conversations.

So when the game is running you see some groups of agents in conversations some agents will not be at any conversation and some agents will leave/join existing conversations.

But I'm still can't make the first part a simple meeting between two agents. When two agents getting close less then threshold they are in yellow but not stopping then other agents getting close and get in yellow too. In the end there is a bog group of agents all the agents at the same place like a one big conversation (meeting).

\$\endgroup\$
  • 2
    \$\begingroup\$ "But it's far away from the behaviour I want" and what is that current behaviour it's showing? \$\endgroup\$ – DMGregory Jul 18 '18 at 10:38
  • 1
    \$\begingroup\$ Nothing with with the the behaviour I wanted. All the agents just going as one big crowd to the next waypoint. I tried to look closer in the scene view I didn't see even one of them "meeting" with another agent. Maybe also the problem is that the agents all the time in movement ? \$\endgroup\$ – Benzi Avrumi Jul 18 '18 at 11:10
2
\$\begingroup\$
public bool randomMeeting = false;

You've turned off your meeting logic, so it's being skipped.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.