Friday, August 24, 2018

Leader-Following Flocking/Steering in Unity

I have created a flocking algorithm in C# for my unity project. I have tried to follow this example, but the problem is bringing everything together, and I'm failing to extrapolate. The following code is part of my desire to have a leader-following flocking system.

I have added following/seeking steering to the basic three steering subroutines (alignment, cohesion, separation), but right now the boids just flock on top of the leader and shadow him. I'd like for them to follow the leader, but also maintain separation from each other rather than just piling on each other like they're out of phase.

When the user selects a group of boids, and then selects where they should flock to, the boid closest is allocated leader and is assigned an A* path to the target. The other boids then call the flocking instead of pathing code.

void Update()
{
    if (flock.Count > 0 && 
        flockLeader != gameObject)
    {
        Flocking();
    }
    else
    {
        Movement();
    }
}

private void Flocking()
{
    Vector3 vector = Vector3.zero, alignment = Alignment(), cohesion = Cohesion(), separation = Separation(), following = Following();
    int weightAlignment = 1, weightCohesion = 1, weightSeparation = 1, weightFollowing = 1;

    NeighbourhoodWatch(); // determine neighbour boids (exclude self)

    vector += (separation * weightSeparation);
    vector += (alignment * weightAlignment);
    vector += (cohesion * weightCohesion);
    vector += (following * weightFollowing);
    vector.Normalize();

    if (!vector.Equals(Vector3.zero))
    {
        if (Vector3.Angle(vector, transform.forward) >= 1f)
        {
            transform.rotation = Quaternion.LookRotation(Vector3.RotateTowards(transform.forward, vector, rateOfTurn * Time.deltaTime, 0.0f));
        }
        else // rotate and move
        {
            transform.rotation = Quaternion.LookRotation(Vector3.RotateTowards(transform.forward, vector, rateOfTurn * Time.deltaTime, 0.0f));
            transform.Translate(Vector3.forward * (speed * Time.deltaTime));
        }
    }
}

private Vector3 Alignment()
{
    Vector3 vector = Vector3.zero;

    if (neighbourhood.Count > 0)
    {
        foreach (GameObject boid in neighbourhood)
        {
            vector += boid.transform.forward;
        }

        vector /= neighbourhood.Count;
    }

    return vector;
}

private Vector3 Cohesion()
{
    Vector3 vector = Vector3.zero;

    if (neighbourhood.Count > 0)
    {
        foreach (GameObject boid in neighbourhood)
        {
            vector += boid.transform.position; // acquire centre of mass
        }

        vector /= neighbourhood.Count;
        vector = vector - transform.position; // direction to centre of mass
    }

    return vector;
}

private Vector3 Separation()
{
    Vector3 vector = Vector3.zero;

    if (neighbourhood.Count > 0)
    {
        int spaceInvaders = 0;

        foreach (GameObject boid in neighbourhood)
        {
            float proximity = Vector3.Distance(boid.transform.position, transform.position);

            if (proximity <= footprint)
            {
                vector += boid.transform.position - transform.position;
                spaceInvaders++;
            }
        }

        if (spaceInvaders > 0)
        {
            vector /= spaceInvaders;
            vector *= -1; // negation (invert direction)
        }
    }

    return vector;
}

private Vector3 Following()
{
    Vector3 vector = Vector3.zero;

    vector = flockLeader.transform.position - transform.position;

    return vector;
}

Solved

Well i have a few time trying something similar to this, if you want your units have a distance from your leader, just take the leader velocity and use that reverse vector, that reverse vector will be your units Destination, also use vector.scale if you want to ajust yourself the separation distance.


Monday, August 20, 2018

Tiny space between the top of menu and the top of the website

I made a simple navigation bar, but there is a small space between the top of menu and the top of page.

body {
  margin: 0;
  padding: 0;
  font-family: Ubuntu, "times new roman", times, roman, serif;
}

.navbar {
  background-color: gray;
  color: white;
  list-style: none;
  text-align: center;
  padding-top: -15px;
  padding: 20px 0 20px 0;
}

.navbar>li {
  display: inline;
  padding-right: 5px;
}

.navbar>li>a {
  font-family: Ubuntu, "times new roman", times, roman, serif;
  text-decoration: none;
  color: white;
}

.navbar>li>a:hover {
  color: lightblue;
}

Also another question - can I add this navigation bar to my actual site and if yes, how to do it?

Solved

.navbar {
 margin: 0; // add this line
 background-color: gray;
 color: white;
 list-style: none;
 text-align: center;
 padding: 20px 0 20px 0;
}

This will work.


Sunday, August 19, 2018

PyCharm 3.4 CE: Remote host access plugin

JetBrains.com says:

Synchronization with servers, uploading, downloading, and managing files on them are provided via the Remote Hosts Access bundled plugin, which is by default enabled. If not, activate it in the Plugins page of the Settings dialog box.

I don't have Remote Hosts Access in Projects Settings/Plugins: projects settings

What should i do to install it? It is also absent in "Browse repositories" window list.

May be i should install it via External tools, but how?

Solved

Remote Hosts Access bundled plugin is not present in newer versions. Try Source synchronizer. It does the same. It supports SCP, FTP, SFTP protocols.

https://plugins.jetbrains.com/plugin/7374?pr=idea_ce


According to the documentation, "FTP/SFTP/FTPS remote host deployment" is indeed "Supported only in Professional Edition".


Friday, August 17, 2018

From window to opengl coordinate system intuitive explanation

I am trying to understand the map from window coordinate axis (origin top-left) to OpenGL coordinate axis (origin left-bottom) when using the mouse function. In relevant book this map is described by the two following lines:

points[count].x = (float) x / (w/2) - 1.0;
points[count].y = (float) (h-y) / (h/2) - 1.0;

I suspect that these two lines depict a scale. Could you please give an intuitive-mathematical explanation of this map?

Solved

What book are you referring to? The origin in NDC-space is the center of the viewport (0,0 is the center; -1,-1 is the bottom-left; 1,1 is the top-right). Any other coordinate space is defined by your projection matrix.

I believe what the book is trying to teach you is that NDC-1,-1 is the bottom-left corner of your viewport and NDC1,1 is the top-right corner.

A more complete mapping would include the X and Y location of your viewport:

  • NDCX = (2.0 * (ScreenX - ViewportX) / ViewportW) - 1.0;

  • NDCY = (2.0 * (ScreenY - ViewportY) / ViewportH) - 1.0;

This mapping is illustrated below (the square on the right is the viewport):

  http://upload.wikimedia.org/wikipedia/commons/2/23/Viewport_transformation.png

You of course have one additional step necessary since the Y-axis runs the opposite direction in your mouse coordinate system. That is why you see the Y-axis flipped in your mapping h-y