Unity – How to copy a string to Clipboard

In Unity there is a cross-platform way to copy a string to Clipboard. Using the GUIUtility class I’m going to show you how to copy a string into the user’s Clipboard. This should work in Unity 2017 and beyond.

By using the GUIUtility class, from UnityEngine, we can fit any C# object with a ToString() function into the Clipboard!

Clipboard Extension

To make it easily accessible I made the function as a string extension. By doing it this way we can use the function on any string anywhere in the code.

using UnityEngine;

public static class ClipboardExtension
{
    /// <summary>
    /// Puts the string into the Clipboard.
    /// </summary>
    public static void CopyToClipboard(this string str)
    {
        GUIUtility.systemCopyBuffer = str;
    }
}

Example

Here is an example on how to copy different elements into the Clipboard using the ClipboardExtension:

public string GetSomeString()
{
    return "This is a string coming from a function!";
}

public void TestCopyToClipboard()
{
    // + Using a standard string
    string testString = "Am I in the Clipboard?";
    testString.CopyToClipboard();
    // The content of test1 is in the Clipboard now!

    // + Using a method to get a string
    GetSomeString().CopyToClipboard();
    // The content returned by GetSomeString() is in the Clipboard now!

    // + Using a C# object with a ToString() method
    Color colorTest = Color.red;
    colorTest.ToString().CopyToClipboard();
    // The string version of the object colorTest is in the clipboard now!
}

You can try out this code for yourself! Run it, then try pasting your Clipboard into a notepad. It has been tested and works on PC, Android and iOS!

Continue reading ...

Game Programmer’s handy math formulas

A collection of useful and common math formulas for game developers.

Fast 90 degrees vector rotation clockwise

Vector2 rotated = new Vector2(-original.y, original.x);

Fast 90 degrees vector rotation counterclockwise

Vector2 rotated = new Vector2(original.y, -original.x);

Fast 180 degrees vector rotation

Vector2 rotated = new Vector2(-original.x, -original.y);

2D Vector Rotation Formula

Vector2 Rotate2D(Vector2 v, float angle) {
  Vector2 rotated = new Vector2();
  rotated.x = (v.x * Cos(angle)) − (v.y * Sin(angle));
  rotated.y = (v.x * Sin(angle)) + (v.y * Cos(angle));
  return rotated;
}

3D Vector Rotation Formulas

Rotation around the Y axis:

Vector3 Rotate3D_YAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = (v.x * Cos(angle)) + (v.z * Sin(angle));
  rotated.y = v.y;
  rotated.z = -(v.x * Sin(angle)) + (v.z * Cos(angle));
  return rotated;
}

Rotation around the Z axis:

Vector3 Rotate3D_ZAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = (v.x * Cos(angle)) - (v.y * Sin(angle));
  rotated.y = (v.x * Sin(angle)) + (v.y * Cos(angle));
  rotated.z = v.z;
  return rotated;
}

Rotation around the X axis:

Vector3 Rotate3D_XAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = v.x;
  rotated.y = (v.y * Cos(angle)) - (v.z * Sin(angle));
  rotated.z = (v.y * Sin(angle)) + (v.z * Cos(angle));
  return rotated;
}

Relationship between speed, distance and time

speed = distance / time
distance = speed * time
time = distance / speed

Dot Product

The dot product takes two equal length vectors and returns a number within the range [-1, 1]. When the two vectors are perfectly aligned the result is 1, when they are perfectly opposed the result is -1, when they are perpendicular the result is 0.

This can be used to determine if two vectors are pointing towards the same direction.

Cross Product

Given two vectors a and b, the cross product returns a vector that is perpendicular to both a and b, it describes the normal of the plane containing both a and b.
If the two vectors have the same direction or if one of them is zero, then their cross product is zero.

Lerp Formula (Linear Interpolation)

float Lerp(float a, float b, float t) {
  t = Clamp01(t); // Clamp01 makes sure t is between [0, 1]
  return (1.0f - t) * a + t * b;
}

Inverse Lerp Formula

The inverse lerp is the function that returns a linear value between [0, 1] by linearly interpolating between the first two values with the third.

float InverseLerp(float a, float b, float v) {
  return Clamp01((v - a) / (b - a)); // Clamp01 makes sure the result is between [0, 1]
}

Examples:

a = 10; b = 20; v = 15;  ->  result = 0.5
a = 10; b = 20; v = 10;  ->  result = 0
a = 10; b = 20; v = 60;  ->  result = 1

Clamp Formula / Truncate Formula

Makes sure the given parameter v is between min and max (included).

float Clamp(float v, float min, float max) {
  return Min(Max(v, min), max);
}

Clamp01 Formula

Makes sure the given parameter v is between 0 and 1 (included).

float Clamp01(float v) {
  return Min(Max(v, 0.0f), 1.0f);
}

Distance between two points

float Distance(Vector p1, Vector p2) {
  float squaredDistance = ((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
  return sqrt(squaredDistance);
}

Signed distance between two circles

We take the distance between the two circle centers and substract the radius of both circles from that distance.
When the two circles are far from each other the distance is positive. When the two circles touch each other the distance is zero. And when the two circles overlap each other the distance is negative.

float SignedDistance(Vector c1Center, float c1Radius, Vector c2Center, float c2Radius) {
  return Distance(c1Center, c2Center) - (c1Radius + c2Radius);
}

Signed distance between circle and point

We take the distance between the circle center and the point and subtract the radius of the circle. When the point is inside the circle the distance is negative. When the point is on the edge of the circle, the distance is zero.
This function also works to calculate the signed distance between a sphere and a 3d point.

float SignedDistance(Vector circleCenter, float radius, Vector point) {
  return Distance(point, circleCenter) - radius;
}

The following function returns the distance between a circle and a point. When the point is inside or on the edge of the circle the distance is zero.

float Distance(Vector circleCenter, float radius, Vector point) {
  float distance = Distance(point, circleCenter) - radius;
  return (distance < 0.0f) ? 0.0f : distance;
}

Distance between segment and point

The following function returns the distance between a segment and a point. The segment is defined between the points v and w.
First we try to find the projection of the point p onto the line described by the segment (v, w). We then return the distance between that projection and the given point p.

float Distance(Vector v, Vector w, Vector p) {
  float dist2 = DistanceSquared(v, w); // Squared distance between point v and w
  if (dist2 == 0.0f) // if v == w
    return Distance(p, v);
  float t = Clamp01(Dot(p - v, w - v) / dist2); // Dot Product
  Vector projection = v + t * (w - v);
  return Distance(p, projection);
}

Source: StackOverflow

Circle Circumference / Circle Perimeter

float CircleCircumference(float circleRadius) {
  return 2.0f * PI * circleRadius; // PI is a constant value of 3.14159265359
}

Circle Arc Length

float CircleArcLength(float circleRadius, float arcAngleInRadians) {
  return circleRadius * arcAngleInRadians;
}

Angle in radians between two vectors

float AngleRad(Vector v1, Vector v2) {
  float cosAngle = DotProduct(v1, v2) / (v1.magnitude * v2.magnitude);
  return ArcCos(cosAngle);
}

Continue reading ...

Fixing Violation of Usage of Android Advertising ID policy

If you recently tried to publish a game made with Unity you might have received an e-mail from Google Play saying that your app got removed. In this post I will show you an easy way to get back on the Store by fixing the Violation of Usage of Android Advertising ID policy.

The mail that you received should be looking like this:

Hi developers at <your company>,

After review, <your game>, com.YourCompany.YourGame, has been removed from Google Play due to a policy violation. This app won’t be available to users until you submit a compliant update.

Issue: Violation of Usage of Android Advertising ID policy and section 4.8 of the Developer Distribution Agreement

Google Play requires developers to provide a valid privacy policy when the app requests or handles sensitive user or device information. We’ve identified that your app collects and transmits the Android advertising identifier, which is subject to a privacy policy requirement. If your app collects the Android advertising ID, you must provide a valid privacy policy in both the designated field in the Play Console, and from within the app.

Next steps: Submit your app for another review

  1. Read through the Usage of Android Advertising ID and User Data policies, as well as the Developer Distribution Agreement, and make appropriate changes to your app. If you decide to collect sensitive user information, be sure to abide by the above policies, and include a link to a valid privacy policy on your app’s store listing page and within your app.
  2. Make sure that your app is compliant with all other Developer Program Policies. Additional enforcement could occur if there are further policy violations.
  3. Sign in to your Play Console and submit the update to your app.

Alternatively, you may opt-out of this requirement by removing any requests for sensitive permissions or user data.

If approved, your app will again be available with all installs, ratings, and reviews intact.

If you’ve reviewed the policy and feel this removal may have been in error, please reach out to our policy support team. One of my colleagues will get back to you within 2 business days.

Thanks for helping us provide a clear and transparent experience for Google Play users.

Regards,

Jaime

The Google Play Team

Please help!

If your game is not using Unity Ads or any ad network you can fix your app in no time! Simply head over to the Package Manager.

Unity Package Manager

Then, from here remove the Advertisement package.

Unity Package Panager - Unity Ads

And that’s it! You can finally build your game and submit it.

If you still get rejected, you can also remove the In App Purchasing package and the Analytics Library package.

Unity Package Panager - Unity IAP

What if I am using Unity Ads?

If your game is using Unity Ads (or another ad network, or Unity IAP and previous section didn’t help) then you have to do as Google said. Provide them a valid privacy policy.
If you need to publish as fast as possible you can quickly create a privacy policy using this generator for example:
https://app-privacy-policy-generator.firebaseapp.com

Continue reading ...

Unity – How to get local IP address

In Unity 2018 getting the player local IP address has changed. Previously we could use the UnityEngine.Network class, but it has become obsolete.

string ipAddress = UnityEngine.Network.player.ipaddress; // obsolete

After doing some research I found the C# way of getting the local IP address of the user:

public static class IPManager
{
    public static string GetLocalIPAddress()
    {
        var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
        foreach (var ip in host.AddressList)
        {
            if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                return ip.ToString();
            }
        }

        throw new System.Exception("No network adapters with an IPv4 address in the system!");
    }
}

This can be used to start a local server or direct connect to one.

Before trying to get the IP, you can also check if you are connected with the following line:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

Sources

Thanks to Mrchief: https://stackoverflow.com/questions/6803073/get-local-ip-address

Continue reading ...

Nil Order Revealed!

Hi!

Today I decided to unveil the personal project that I worked on about a year ago: Nil Order.
It is a procedurally generated Open World heavily inspired by The Legend Of Zelda: Breath Of The WildCédric, Robin and I worked on it for a few months and are now presenting the result! Unfortunately, no build is available yet. But I will keep you informed if that changes.

To me this project was a way to try to reproduce the impressive voxel smoothing technology used in Everquest Landmark. This project was also a way to look into the multi-threading and the procedurally generated geometry capacities of Unity.

You can check out how we did it on the project’s page right here.

 

Nil Order Screenshots

Continue reading ...

Mini Trafic – Public Release

Hello everyone!

I am proud to announce that our most awaited game ‘Mini Trafic‘ is finally available to the public!
In the case that you don’t know what I’m talking about. Mini Trafic is a management game and a serious game. Where the player controls the traffic lights of a city and has to parameter/tweak them in order to keep the drivers happy. The game is entirely in French by the way.

If you want more infos about the game or if you are looking for something with pictures to read. You can check out this page where I describe how we made the magic of Mini Trafic.

Trailer

So, after months of hard bagels and delicious development, the EnigmaVR team is proud to show the official trailer of the game (in French):

 

Download

You can download the game for Windows, Mac OS and Android on IndieDB.

 

If you want more infos about the game you can check out this page.

Continue reading ...

Site launching!

[Actually no, it’s just a testing post, the site is not really ready yet]

Here we go, the website is now live!

If you don’t know who I am you can find out right here 🙂

If you’re interested in what I do, go check this page out.

The last game I did is EngimaVR and has a page of its own over there.

Enjoy and comment if want to!

Continue reading ...