# Question
Title: Procedural generation background works with one type of prefab and doesn't work with another
I have background generation script with 2 arrays. One contains stars prefabs with sprites and another contains nebulas prefabs with sprites. Both have identical types of variables as generating parameters and use same methods for spawning. Nonetheless, it works only with stars. Nebulas don't spawn. What might be a problem?

```
/* This script provides background generation. */

[System.Serializable]
public struct SpritePrefab //struct for stars and nebulas prefabs
{
    #if UNITY_EDITOR

    [HideInInspector]
    public string name;

    #endif
    public GameObject prefab;

    [Tooltip("Share of this sprite in percentages of 100% total.")]
    [Range(0f, 100f)]
    public float share;
}

//________________________________________________________________________

/* These arrays contain all prefabs with all of the sprites needed to generate background. */

[Header("Sprites arrays.")]

[Tooltip("Array of stars prefabs.")]
[SerializeField]
private SpritePrefab[] calculatedStarsPrefabs; //arrays for stars sprites for second distributing method which is DistributeProportionatelyForStars2()

[SerializeField]
[HideInInspector]
private SpritePrefab[] normalizedStarsPrefabs; //array for final use of stars prefabs. Created to avoid struggling with distributing logick when working in Inspector.

[Tooltip("Array of nebulas prefabs.")]
[SerializeField]
private SpritePrefab[] calculatedNebulasPrefabs; //array for nebulas sprites

[SerializeField]
[HideInInspector]
private SpritePrefab[] normalizedNebulasPrefabs;

//=============================================================================

/* These values determine generating parameters such as spawning range and number of stars. */

[Header("Stars spawning parametrs.")]

[Tooltip("Stars Range to spaw.")]
[SerializeField]
private float starsSpawningRange; //spawning range used in vector2 x and y axis

[Tooltip("Number of stars to spaw.")]
[SerializeField]
private int numberOfStars; //Number of stars to spaw

//__________________________________________________

[Tooltip("Minimal star size.")]
[SerializeField]
private float minimalStarSize; //minimal star size

[Tooltip("Maximum star size.")]
[SerializeField]
private float maximalStarSize; //maximal star size

//=============================================================================

[Header("Nebulas spawning parametrs.")]

[Tooltip("Nebulas Range to spaw.")]
[SerializeField]
private float nebulasSpawningRange; //spawning range used in vector2 x and y axis

[Tooltip("Number of nebulas to spaw.")]
[SerializeField]
private int numberOfNebulas; //Number of nebulas to spaw

//__________________________________________________

[Tooltip("Minimal nebula size.")]
[SerializeField]
private float minimalNebulaSize; //minimal nebula size

[Tooltip("Maximum nebula size.")]
[SerializeField]
private float maximalNebulaSize; //maximal nebula size

//=============================================================================

private string[] sortingLayersNames = new string[6] { "S&N 1", "S&N 2", "S&N 3", "S&N 4", "S&N 5", "S&N 6"};

//=============================================================================

private void Awake()
{
    SpritePrefabsGenerating(normalizedStarsPrefabs, numberOfStars, minimalStarSize, maximalStarSize, starsSpawningRange);
    SpritePrefabsGenerating(normalizedNebulasPrefabs, numberOfNebulas, minimalNebulaSize, maximalNebulaSize, nebulasSpawningRange);
}

//=============================================================================

private void SpritePrefabsGenerating(SpritePrefab[] spritesArray, int numberOfInstances, float minPrefabSize, float maxPrefabSize, float spawningRange)
{
    int indexInArray = 0; //this variable counts type of star

    // loops until i == share of prefabs in persentages multiplied by number of instances divided by 100(%) to get total number of particular type of stars

    for (int j = 0; j < spritesArray.Length; j++) //loops through prefabs array length
    {
        for (int i = 0; i < spritesArray[indexInArray].share * numberOfInstances / 100; i++) //loops until
        {
            InstantiateSpritePrefab(spritesArray, indexInArray, minPrefabSize, maxPrefabSize, spawningRange); //instantiates prefab
        }
        indexInArray++; //updates variable to get another type of prefab in array
    }
}

private void InstantiateSpritePrefab(SpritePrefab[] spritesArray, int index, float minPrefabSize, float maxPrefabSize,
    float spawningRange) //receives index to get prefab from array and instantiate it
{
    var spritePrefab = Instantiate(spritesArray[index].prefab,
        new Vector3(Random.Range(-spawningRange, spawningRange), // define spawning range along x axis
            Random.Range(-spawningRange, spawningRange), 100f), // define spawning range along y axis
            Quaternion.identity);

    float randomsizeSize = Random.Range(minPrefabSize, maxPrefabSize); //defines size variety
    spritePrefab.transform.localScale = new Vector2(randomsizeSize, randomsizeSize); //randomizing size variety

    //assigning sprite in prefab to random sorting layer
    spritePrefab.GetComponent<SpriteRenderer>().sortingLayerName = sortingLayersNames[Random.Range(0, sortingLayersNames.Length)];
}

//=============================================================================

#if UNITY_EDITOR
private void OnValidate()
{
    DistributeProportionatelyForSpritesPrefabs(calculatedStarsPrefabs, normalizedStarsPrefabs);
    DistributeProportionatelyForSpritesPrefabs(calculatedNebulasPrefabs, normalizedNebulasPrefabs);
}
#endif

#if UNITY_EDITOR

void DistributeProportionatelyForSpritesPrefabs(SpritePrefab[] calculatedArray, SpritePrefab[] normalizedArray) // When the array is modified, update all the entries' names, and total up the weight accounted for.
{
    float totalWeight = 0; //initiates total share as 0

    for (int i = 0; i < calculatedArray.Length; i++)
    {
        var localPrefabStruct = calculatedArray[i]; //assigning actual prefab struct to local variable
        if (localPrefabStruct.prefab == null)
            continue;

        localPrefabStruct.name = localPrefabStruct.prefab.name; //asigning actual prefab name to name field in struct
        calculatedArray[i] = localPrefabStruct; //reasigning same prefab struct with name
        totalWeight += localPrefabStruct.share; //adds prefabs share to totla share
    }

    if (totalWeight == 0f)
    {
        return;
    }

    float shareMultiplier = 100f / totalWeight; //get number for multiplying

    if (normalizedArray == null || normalizedArray.Length != calculatedArray.Length) // Create/resize the normalized version.
        normalizedArray = new SpritePrefab[calculatedArray.Length];

    // Fill this array with copies of the original,
    // reweighted to add up to 100
    for (int i = 0; i < calculatedArray.Length; i++)
    {
        var localPrefabStruct = calculatedArray[i];
        if (localPrefabStruct.prefab == null)
            localPrefabStruct.share = 0f;

        localPrefabStruct.share *= shareMultiplier; //keeps total share within 100.
        normalizedArray[i] = localPrefabStruct; // filling final array
    }
}
#endif

```

# Answer
> 1 votes
This looks like a refactoring error.

The original example code used just one set of prefabs, with two member variables for the editable and normalized arrays, respectively.

When the editable array changed in size, the normalized array member variable was updated to point to a new array of the same size to match.

When you refactored this to work with two pairs of editable & normalized arrays, you packaged up the normalizing behaviour into a method that could be called on each, and the resizing logic took on a slightly different form:

```
void DistributeProportionatelyForSpritesPrefabs(
    SpritePrefab[] calculatedArray,
    SpritePrefab[] normalizedArray )
{

// ...

if (normalizedArray == null || normalizedArray.Length != calculatedArray.Length) // Create/resize the normalized version.
    normalizedArray = new SpritePrefab[calculatedArray.Length];

```

Note that the `normalizedArray` we're assigning here is not a member variable. It's an argument to the function. That means that if we change which array it's pointing to (by creating a new one of the correct size), we haven't changed which array the original member variable `normalizedStarPrefabs` or `normalizedNebulaPrefabs` is pointing to. So the rest of our code still sees the old array.

This is solved easily enough by using the `ref` keyword:

```
void DistributeProportionatelyForSpritesPrefabs(
    SpritePrefab[] calculatedArray,
    ref SpritePrefab[] normalizedArray )

```

This forces the argument to refer to the variable we pass, so if we assign a new array into it, our member variable gets that new array.

We need to add the keyword where we call the method too, to show clearly what's going to happen to the variable we're passing in:

```
DistributeProportionatelyForSpritesPrefabs(
    calculatedStarsPrefabs,
    ref normalizedStarsPrefabs);
DistributeProportionatelyForSpritesPrefabs(
    calculatedNebulasPrefabs,
    ref normalizedNebulasPrefabs);

```

Or, another way to solve this is to encapsulate the behaviour of these paired arrays in their own type, eg...

```
[System.Serializable]
public struct NormalizedPrefabList : IEnumerable<SpritePrefab> {
    [SerializeField]
    [HideInInspector]
    private SpritePrefab[] _normalizedPrefabs;

    public SpritePrefab this[int index] {
        get { return _normalizedPrefabs[index]; }
    }

    public IEnumerator<SpritePrefab> GetEnumerator() {
        return (IEnumerator<SpritePrefab>)_normalizedPrefabs.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return _normalizedPrefabs.GetEnumerator();
    }

#if UNITY_EDITOR
    [SerializeField]
    private SpritePrefab[] _editablePrefabs;

    // Call this in OnValidate()
    public void Renormalize() {
        // Put the renormalizing method here. No arguments needed - act on "this"
    }
#endif
}

```

That way the rest of your code can just treat the whole thing as an array, accessing its normalized entries with `[indexing]` or `foreach`, and doesn't have to worry about coordinating its internals, beyond calling `Renormalize()` in `OnValidate()` when something might have changed in the editor.

---
Tags: 2d, sprites, procedural-generation, scripting, procedural
---


# Question
Title: Why does this implementation of sweep and prune freeze, and how can I fix it?
When I try to implement sweep and prune the aabb and sphere collisions don't collide properly. I have debugged the code and traced the problem to these methods.

**AABB and Sphere collisions(The code for both is slightly different)**

```
@Override
public boolean collides(Sphere other) {
            //AABB
    float dist = sqDistance(other.getCenter(), this);

    return dist <= (other.getRadius() * other.getRadius());

}

    @Override
public boolean collides(AABB other) {
    float dist = sqDistance(center, other);

    return dist <= (radius * radius);
}

 public default float sqDistance(Vector3f point,AABB aabb) {
    float sqDist = 0.0f;
    for( int i = 0; i < 3; i++ ){
        // for each axis count any excess distance outside box extents
       sqDist += check(point,aabb,i);
    }
    return sqDist;
}

public default float check(Vector3f point,AABB aabb,float axis) {
        float sqDist = 0;
        if(axis == 0) {
            float v = point.x;

            if( v < aabb.getMin().x ) sqDist += (aabb.getMin().x - v) * (aabb.getMin().x - v);
            if( v > aabb.getMax().x ) sqDist += (v - aabb.getMax().x) * (v - aabb.getMax().x);
        }
        if(axis == 1) {
            float v = point.y;

            if( v < aabb.getMin().y ) sqDist += (aabb.getMin().y - v) * (aabb.getMin().y - v);
            if( v > aabb.getMax().y ) sqDist += (v - aabb.getMax().y) * (v - aabb.getMax().y);
        }
        if(axis == 2) {
            float v = point.z;

            if( v < aabb.getMin().z) sqDist += (aabb.getMin().z - v) * (aabb.getMin().z - v);
            if( v > aabb.getMax().z) sqDist += (v - aabb.getMax().z) * (v - aabb.getMax().z);
        }
        return sqDist;
}

```

Could anyone please try and tell me what is wrong with these methods.

# Answer
> 0 votes
For starters, this doesn't look like sweep and prune. You're checking the whole bounding box in each comparison, rather than doing a series of sweeps filtering each axis. That's fine, comparing a whole bounding box is not a wrong way to do collision detection. Sweep and prune is a particular algorithm though, so for clarity it's best to use that term only when you're referring to that specific technique.

It looks like you're trying to do the following...

1. For each box in my original list
2. Check it against each preceding box in the list
3. If they collide, do something
4. Otherwise, do something else

But your 3. "do something" & 4. "do something else" don't make a lot of sense. You're either adding the next box to your active list (why? The next iteration of the loop will do that anyway) or removing the box you're checking from the list (why? It might still collide with the next box you check in your inner loop)

I think maybe you want something simpler:

```
for(int collider = 1; collider < axisList.size(); collider++) {

    BoundingBox colliderBox = axisList.get(collider);

    for(int collidee = 0; collidee < collider; collidee++) {

        BoundingBox collideeBox = axisList.get(collidee);

        if(colliderBox.collides(collideeBox)) {
            System.out.println("COLLISION " + collideeBox + ":" + colliderBox);
            // Record the collision here.
            // eg. collisionList.add(new collision(collidee, collider));
        }
        // No else. We have to keep checking the next collidee
        // until there are no further possible collisions.
    }
}

// Once we've detected all collisions, now we can act on them,
// by iterating over our collisionList for example.

```

There. Now we're not modifying a collection while we're traversing it, we just check each box against each box that precedes it in the same collection.

---
Tags: java, collision-detection, physics
---


# Question
Title: Property replication vs RPC: Communication directions
I have an `UParticleSystemComponent` attached to `ACharacter`. Its activation is controlled by user input, so it receives several updates per second.

For replicating the activation state of the particle system, the user input triggers an update of the value of a replicated variable (`UPROPERTY(Replicated)`) on the ACharacter. This works fine for the direction

* Listen server -\> Clients,

however **not** for the directions

* Client -\> Listen Server
* Client -\> Client.

I assume this is the case b/c "Property updates only come from the server (i.e., the client will never send property updates to the server)".

So for Client -\> Client replication I have to rely on RPCs and can't use property replication at all?

# Answer
> 2 votes
In order to replicate properties, you need to replicate the actor holding the properties. In Client/Server, the server is simulating the behaviors of all the replicable actors, then sending updates out to clients. So you should use Broadcasts (Run on Server not Run On Owning Client or Multicast) to send input to the server, which then acts on receiving the broadcast.

---
Tags: multiplayer, unreal-4
---


# Question
Title: How do you handle pathfinding for non-tilemap 2d games?
What methods do you use to handle path finding in non-tiled 2D games? Tilemap based methods can use A\* and 3D has NavMesh available. The only success I’ve had is with raycasts but it doesn’t seem like a great way to handle things with hand draw sprites or uneven terrain.

# Answer
There is nothing about A\* that is specific to a tile map or grid. A\* is usable in any kind of directed graph so long as there is a usable heuristic - e.g., distance to destination. When there *isn't* a good heuristic to use, recall that A\* is just a specialization of Dijkstra's, which likewise can be used on *any* directed graph.

The only thing A\* thus requires is a node and a hueristic. With a tile map, the nodes are the grid locations. With a navigation mesh, the nodes are based on the mesh geometry. Some games have used explicit nodes placed in the world (either automatically or even manually) which is essentially just a generalization of a navigation mesh.

There's also no reason you couldn't use a navigation mesh in 2D. Note that 2D is just a subset of 3D (set the Z axis to 0). Navmeshes most certainly have been used (with A\*) for decades in 2D games.

I'm not aware if *Unity* is imposing some kinds of limitations here; if if is, you're certainly capable of writing A\* or nav meshes yourself without using whatever Unity provides by default.
> 5 votes

# Answer
This is a rather broad topic, so my answer will be rather high level.

General path finding algorithms (including A\*) find a shortest path on a weighted graph in which the vertices (aka nodes) represent locations & edge weights represent a cost (typically related to the distance between the nodes.

In a simple tile map, generating the graph representation is usually done as follows:

* each tile (or center thereof) is a node
* adjacent neighbors share an edge

One solution for non-tiled 2D games is to impose a tile map on the area of interest. If your virtual tile is 20x20, you simply do integer division on a coordinate location & use that to look up the tile. In some cases, this works fine, but it has limitations - namely the trade-offs between resolution & performance.

The other common solution is to generate a navigation mesh. At a high level, this basically means:

* decomposing the area of interest in a polygon mesh
* establishing a corresponding weighted graph
* applying some path finding algorithm

The challenge with a navigation mesh is finding a good decomposition. There are ways to automate this, but it's not uncommon to need to fine tune things.

Finally, as you pointed out, you can also do raycasting. I've done this once myself for a research project. I had a static 2d map & for every corner, I did raycasting to other corners. Essentially, the corners became my nodes & rays that didn't clip anything became edges.

While this was appropriate for that particular problem, it also has some challenges. Specifically, if you have N vertices, there are potentially N2 edges. Also, you usually can't travel exactly on the edges of your obstacles, so you may need to adjust for that as well.

Amit P has a great tutorial on path finding that covers this & many other details (and is the source for the illustrations used here).
> 3 votes

# Answer
A\* works for all graphs, not just grids. "Nav meshes" are just a method of forming a graph for maps that are not tilemaps, and should work equally for 2D and 3D.
> 1 votes

---
Tags: unity, path-finding
---


# Question
Title: When I pause my game scene in unity editor by keyboard ctrl+shift+P，‘Assertion failed ...’ appears in console window
I am using Unity 2017.2.0f3. When I pause my game scene by use mouse click on pause button & play it frame by frame, it works OK. Instead, pause by use ctrl+shift+P keys down, an error will play once in console window at the time I press frame by frame button.

```
Assertion failed: Assertion failed on expression: '!dest.m_MultiFrameGUIState.m_NamedKeyControlList'
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

```

This would happens even in the new created empty scene!

Any help will be appreciated!

# Answer
> 3 votes
This appears to be a known error.

The error report doesn't specifically include Unity 2017.2.0f3, but the patterns seems to fit. Since the error is not reproduced in 2018.1.0a4 and up, the best recommendation I can give is to upgrade / update to that version or later.

Here's the full error report:

> **Assertion failed error is thrown after pausing the game with a shortcut key and stepping one frame**
>
> Steps to reproduce:
>
> 1. Create a new project
> 2. Enter Playmode
> 3. Press Ctrl+Shift+P or Cmd+Shift+P at the same time
> 4. Press "Step" button
>
> --Assertion failed error occurs
>
> Error: "Assertion failed: Assertion failed on expression: '!dest.m\_MultiFrameGUIState.m\_NamedKeyControlList'UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)"
>
> Reproducible with: 2017.2.0b5, 2017.2.1f1, 2017.3.0f2, 2018.1.0a3 Not Reproducible with: 2017.1.2p4, 2017.2.0a4 Regression introduced in 2017.2.0a4
>
> Is not reproducible with 2018.1.0a4, a5, a6, a7

---
Tags: unity, gui
---


# Question
Title: How to make an existing Editor window floatable
I added a second inspector window tab to Unity and locked it. I tried moving it to another desktop on my Mac but it doesn't move to the next desktop. How can I make a duplicate Inspector Window floatable?

# Answer
Just hold the tab and drop it on the top of your screen. It should make the window float able.

Step one: Hold the window you want to make float able.

Step two: Drag the window to the top of your screen (The maximum you are able to drag)

Step three: Release the mouse button and you got yourself a floating window.
> 1 votes

---
Tags: unity
---


# Question
Title: Unable to list target platforms. Please make sure the android sdk path is correct. (Error)
When i am trying to build an apk from unity. Than its show me some error something like this :-

```
CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct.
E:/DEWA/msgs/Kunal/android-sdk-windows-1.6_r1\tools\bin\avdmanager.bat list target -c

stderr[

]
stdout[

ERROR: JAVA_HOME is set to an invalid directory: C:\Program Files\Java\jdk1.8.0_121\lib\tools.jar;C:\Program Files\Java\jre1.8.0_141\lib\rt.jar;

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
]
exit code: 1
UnityEditor.Android.Command.WaitForProgramToRun (UnityEditor.Utils.Program p, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunAndroidSdkTool (System.String toolName, System.String arguments, Boolean updateCommand, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.ListTargetPlatforms (UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit)
UnityEditor.Android.AndroidSDKTools.GetTopAndroidPlatformAvailable (UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit)
UnityEditor.Android.PostProcessor.Tasks.CheckAndroidSDK+SDKPlatformDetector.GetVersion (UnityEditor.Android.AndroidSDKTools sdkTools)
UnityEditor.Android.PostProcessor.Tasks.CheckAndroidSDK+SDKComponentDetector.Detect (UnityEditor.Android.AndroidSDKTools sdkTools, System.Version minVersion, UnityEditor.Android.PostProcessor.ProgressHandler onProgress)
UnityEditor.Android.PostProcessor.Tasks.CheckAndroidSDK.EnsureSDKComponentVersion (System.Version minVersion, UnityEditor.Android.PostProcessor.Tasks.SDKComponentDetector detector)
UnityEditor.Android.PostProcessor.Tasks.CheckAndroidSDK.EnsureSDKComponentVersion (Int32 minVersion, UnityEditor.Android.PostProcessor.Tasks.SDKComponentDetector detector)
UnityEditor.Android.PostProcessor.Tasks.CheckAndroidSDK.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

Build completed with a result of 'Failed'
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

UnityEditor.BuildPlayerWindow+BuildMethodException: 2 errors
  at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (BuildPlayerOptions options) [0x0020e] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:181
  at UnityEditor.BuildPlayerWindow.CallBuildMethods (Boolean askForBuildLocation, BuildOptions defaultBuildOptions) [0x00065] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:88
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

Error building Player: CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct.
E:/DEWA/msgs/Kunal/android-sdk-windows-1.6_r1\tools\bin\avdmanager.bat list target -c

stderr[

]
stdout[

ERROR: JAVA_HOME is set to an invalid directory: C:\Program Files\Java\jdk1.8.0_121\lib\tools.jar;C:\Program Files\Java\jre1.8.0_141\lib\rt.jar;

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
]
exit code: 1

```

# Answer
> 1 votes
Try installing older version of the android SDK, I'v seen that it solves this problem to many many people.. including my friends.

---
Tags: unity, c#
---


title: Limit Rotation Angle Unity 3D

text:
# Question
Title: Limit Rotation Angle Unity 3D
i'm trying to limit maximum rotation angle and i do not know how to do that.. i am using this code currently, how can i limit maximum rotation angle of object?

```
    using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class rotObj : MonoBehaviour {

    void Update () {
        var dir = Camera.main.ScreenToWorldPoint (Input.mousePosition) - transform.position;
        var angle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
        var rot = Quaternion.AngleAxis (angle, Vector3.forward);
        transform.rotation = rot;
    }

}

```

# Answer
> 0 votes
What you have to do is just check if the rotation is bigger than the rotation that you want to be max. If it's bigger, then set it to max and if it's not then just leave it. Code should be something like:

```
currentRotation = Mathf.Min (currentRotation, maxRotation);

```

This will take the smaller one. If you are limiting it to mininum rotation. Instead use:

```
currentRotation = Mathf.Max (currentRotation, minRotation);

```

I haven't tested this code but i think it should work!

---
Tags: unity, c#
---


title: Inside realtime lighting

text:
# Question
Title: Inside realtime lighting
I have a small house with point light in it. But as you see, directional and sky lighting affect inside lighting. It's too bright.

How can I make that inside is only affected by point light and not by directional light. Or maybe just a small amount of directional light.

# Answer
You can use layers to control what content is lit by which lights.

Here I've built a room with two shells of geometry cladding: the exterior shell is in the Default layer, and the interior shell is in a new layer I called Interior.

My red point light's culling mask is set to light only the Interior layer.

My directional sunlight's culling mask is set to light every layer *except* the Interior.

I also edited my scene settings to drop the "Environment Lighting" ambient multiplier to zero, and added a couple of extra directional lights in a soft blue to make up for it. These fill lights also don't light the interior, and don't cast shadows.
> 1 votes

# Answer
I think you might need to see this 16 min video about Unity's lighting.

LIGHTING in Unity. But the general idea is that your indirect lighting is too strong and you need to tweak the Directional light for indirect lighting as well the global lighting settings.
> -2 votes

---
Tags: unity, lighting
---


# Question
Title: Can a block-chain with embedded shared content stop cheating?
I want to make a game where users create their content and embed it in a block-chain. For example, they have a small x,y grid. In the grid they place objects... After the grid is made they share it via block-chain with others. The other players then experience this content and try to pass it unfairly. I feel like there is a way in the block chain to stop them via agreement or algorithm? Is this possible?

# Answer
## Centralized Game

If are going to control the servers of the game. You do not need a decentralized solution such as block-chain. In fact, you will not even need cryptography (beyond what is necessary for proper user authentication) to maintain it.

Considering that you tag a server side technology (node.js), I suspect you intend to deploy servers. Thus, you will be making a centralized game. If that is the case, then you do not need block-chain.

**Note**: Your game can still be P2P, offline, or whatever. When I say decentralized, I am not referring to who hosts the game, but who creates the content of the game.

Before you consider a decentralized game. Consider that you could make a game that includes a map editor, and then people can create their own maps, and perhaps mail them to their friends or share them on some website.

---

## Decentralized Game

So, do you want a decentralized game? *One in which people can create content for it, and it is considered official and part of the core game without the need of a central authority serving, reviewing or approving?*

Then, perhaps, block-chains can help you.

I will go over how block-chains work and cryptocurrencies work, without going into much detail, and then come back to your game.

## How do the block-chains work?

The block-chain has blocks. These are published over Internet for anybody to download.

Each block in the block-chain points to the previous block, which allows to organize the blocks chronologically (hence, "chain"). In addition, each block has a body (some data being stored, will come back to this) and a proof of work based on the hash of the rest of data of block (including the reference to the previous block) and a difficulty parameter.

A notable characteristic of the block-chain system is that the longest chain is considered the valid one. If, temporally, there are multiple branches of the block-chain (that happens when you have various blocks pointing back to the same previous block) that are the same length, eventually one will come ahead and considered the official one.

In fact, that is how the block-chain can enforce a contract. Assuming the rules to verify a contract are encoded in the software that creates the blocks, the nodes will be able to read the body of the blocks and decide if they are ok according to those rules. If the majority agrees that a block is invalid, then any branch that includes that block will die out as the nodes choose to continue adding blocks only to valid branches, making them longer.

You could try to create a rogue node with modified software that considers valid whatever crazy transaction you want to allow. However, the collective of the others nodes will produce blocks faster than your node. As a result, your branch will lag behind, and nobody will consider it valid (except, perhaps, you).

## How cryptocurrencies work?

For cryptocurrencies, the body is a public ledger. That is, a list of transactions. For example something similar to "the wallet x pays the wallet y, z amount". *Of course, we need to figure out a binary format for what we will be storing in the block-chain.*

To ensure that I cannot just put that “scranley” pays seven quadrillion coins to “theraot” and publish it somewhere in the ledger, the transaction will require a digital signature with the key of the source wallet. This allows the nodes to verify that the person who pays authorized it (unless somebody stole the key to your wallet).

The nodes will also make sure that nobody pays more than they have. How do they know how much do you have? Well, it is in the ledger.

In cryptocurrencies, the incentive to contribute blocks (that is, to compile the data, do the proof of work and publish it to the rest of the network) is to be able to earn some cryptocurrency as a reward for providing that service. We call it “mining”.

Now, the first way miners earn cryptocurrency is by adding a transaction that pays the miner some amount. With the particularity that they are being in an special transaction that does not come from any wallet. The network can set a maximum amount the miners can get by these means by simply ignoring any blocks that go beyond the maximum.

The second way miners earn cryptocurrency is by having people paying an extra ammount. When this happens the miner takes it as a transaction fee. Doing this the person making payments can provide an incentive for miners to include their transactions into the block.

**Note**: What I have said above about miners applies to miner pools. The miner pool will build blocks and give them to the miners in the pool to complete their proof of work. That allows the pool to distribute the work across various miners. In addition, of course, the pool will add the payments to the miners in the blocks it builds (according to whatever payment policy the pool has).

---

## How to build the game?

For the premise of the game, I will say that there are tiles, and each tile has…

> a small x,y grid. In the grid they place objects... After the grid is made they share it via block-chain with others

This poses the problem of ownership: Who has the right to public the contents of a particular tile or set of tiles?

**Option 1: Nobody owns the land**

*Option 1.1: Nobody own the land, and the game is instantiated.*

In this scenario, somebody updates the contents of a tile, and then a few moments later somebody overwrites what the first person did. There is no real value. Skip.

---

*Option 1.2: Nobody owns the land, but the block-chain is the game.*

I suppose you could build a game around this concept if you have some strong contracts about what updates are valid.

For instance, I can imagine a turn based strategy game where you put the actions you do on your turn to the block chain, and the nodes verify that:

* You only move on your turn.
* You only move your units, and they move only as much as it is valid.
* You do not multiply your units without paying resources.
* Etc.

It would be impossible to have a fog of war or to keep moves secret. Now, considering that each turn requires a proof of work, the game would be slow. However, it could be interesting for a reasonable number people to play a match, and have then make alliances and plans over email or social media… and some player backstabs them allies, etc…

*For abstract, I think this could be a gimmicky way to play Diplomacy.*

I won't expect such game to be very popular. But, that is just my opinion.

**Option 2: People own tiles**

*Option 2.1: People own tiles, and the game is instantiated.*

In this case, you can only specify the contents of a tile that you own. The nodes would hold the contract that you can only update your tile.

Then, how do you earn/buy a tile? Short answer: currency.

A miner completes a block; allow them to take currency. You can make the tile the currency, or allow to buy tiles using the currency. Aside from that, the body includes these kinds of operations are:

* Wallet x gives the tile z to the wallet y.
* Wallet x updates the contents of the tile z.

Now, if I want to get a tile, I need to:

* Buy it from somebody who owns it - for whatever currency, goods or services they want from it - and thus, these tiles would have some real world value.
* Contribute to the mining process and earn it that way.

If you can manage to make owning tiles intrinsically rewarding by gameplay, then the values of these tiles would never fall below the utility of the game. *Using the word utility here in a very loose sense.*

Now, sure, making your own maps and having other people play them can be intrinsically rewarding. However, I am talking about owning these tiles.

As I said at the start of the answer, you could make a game that includes a map editor, and then people can create their own maps, and share them. Why not do that? **What is the value of owning a tile?**

If you want my suggestion, I would say that the value is creating a large map where everybody owns a chunk. Then the value not only comes from creating and sharing, and does not only comes from saying “I made this”, it also comes from being a part of something bigger, and furthermore… it comes from the particular position of a tile respect to the others. I can imagine people organizing themselves to acquire adjacent tiles to make massive projects (assuming the game is good).

*And some of the massive projects will be depictions of human genitalia, because Internet.*

Do not forget to make the game engaging. You can make a bad game, despite – or perhaps because of – the block-chain.

---

*Option 2.2: People own the tiles, and the block-chain is the game.*

In this case, what you put on the tiles needs to have some synergy with what is in the other tiles. Moreover, you need to introduce other resources that players can exchange aside from the tiles themselves (and whatever main currency you have).

I would suggest making the game cooperative – or at least partially cooperative – such that I set up agreements with my neighbors, and trade with them. For example, I could put a mine in my tile, and doing so would allow me expend ten gold (*that is a block added to the block-chain*). And then I can give five gold to my neighbor in exchange for one diamond (*that is a block added to the block-chain*). Then, expending the diamond may allow me to build something else… etc. In addition, the nodes block-chain network would verify that I do not cheat in any of these turns.

Furthermore, this can be a meta-game for the instantiated version. Consider, for example, that the game is a city simulator, and it mainly played offline. When you earn your tile, it grants you x money that you expend in the game (offline). Then you update your city to the block-chain after your play session (or when you run out resources), and depending on what you build (which the nodes can verify it matches the resources you had) you earn more resources. Furthermore, you could make agreements with your neighbors via the blockchain. And so on…

---

## Final note

*Oh, what if each tile is a dungeon and we pay people some currency when they beat it?*

Well, for that to work. The network needs to be able to verify that you did actually beat it. And they are not taking your claim of it.

We could consider publishing your steps to beat it, that way the network can verify if those steps will in fact lead to the dungeon being completed. And then do a proof of work overthat.

However, that means that it is easier to have a software beat the dungeon and claim the currency. Now, either people want the currency more than playing the game. In which case, the game fails. people rather play the game and to get the currency. In which case this reward system is pointless.

However, I am not saying that a game where people build dungeons and put them in the block-chain for others to play cannot work… but you still need to solve the problem of why it is valuable to own tiles in the block chain (instead of just having a map editor and a way to share maps with other people).
> 1 votes

# Answer
Honestly, using block chain is probably overkill, but yes. Any decent modern encryption method applied to shared content, whilst not preventing outright tampering, would render tampered data useless (as it wouldn't decrypt properly).

A simpler method is to take your example grid, break it into "labelled" chunks, and apply something simple like SHA256 to each chunk, if you really feel the need to encrypt.

Then(and this is the weak part of encryption) figure out a secure way to share the encryption key with other users. You could embed it into your source code, but if you are using javascript it might not be very secure.

Once you have a mechanism for sharing keys and encrypted data, in theory, the shared content should be secure from tampering. In practice, however, if someone is determined enough, they'll manage it.
> 0 votes

---
Tags: node.js, game-theory
---


# Question
Title: How can I calculate the new vector of an object trying to push into (move along) the ground?
Say I have a sphere (planet). If I have object on the surface, I want to limit movement so that it can only travel in directions along or above the surface.

Imagine a coin on a table. If I were to push the coin from up above at an angle, the table would cancel out any downward vector component and the coin would move in 2 dimensions across the table. This is what I would like to achieve.

In the case of a planet (sphere) then I can calculate the cancelling vector to some extent (this is just the line from the centre of the sphere to the point on the surface).

Now I struggle - how do I calculate the magnitude of the opposing vector such that it is sufficient to stop the object falling through the surface but not too big that it starts to launch the object away from the surface?

# Answer
This is called a "normal force" because it acts along the surface's normal (perpendicular) direction.

If you know the net forces acting on the object \\$\vec F\_{Net}\\$, and have a unit (length = 1) normal vector \\$\vec n\\$ pointing out of the surface, then...

$$\vec F\_{Normal} = max\left( 0, -\vec F\_{Net} \cdot \vec n \right) \cdot \vec n$$

or in pseudo-code:

```
F_normal = max(0f, -Dot(F_net, n)) * n

```

This gives a vector pointing out from the surface with exactly enough length to cancel out the component of the net force pushing into the surface (or zero, if the net force is pushing parallel/outward from the surface)
> 1 votes

---
Tags: 3d, mathematics, vector
---


# Question
Title: Strange warping/shimmering effect with Unity Tilemap and Cinemachine
I'm using a Cinemachine Virtual Camera in a 2D project to follow around a target. The ground / background is a Unity Tilemap GameObject.

As you can see in the gif above (or on Imgur), when following around the player (a 24x24 sprite), the background tiles seem to warp or shimmer a bit.

I've tried to script all types of solutions to adjust the Virtual Camera transform position and hopefully snap/move it "correctly" to no avail.

I don't even know for sure that the source of the issue is with the camera setup. I'm running out of solutions to something that seems like a pretty straightforward and very common scenario. I've created a sample project illustrating the issue which can be downloaded here.

Using Unity 2017.3.1f1 Personal. The background sprites are 32x32, with a PPU of 32. No compression, Point (no filter), rendered using a material with Shader: Sprites/Default, and Pixel snap.

Cinemachine Virtual Cam is set to Ortho lens size 16, Body: Framing Transposer with default settings.

Thank you so much for any suggestions or tips!!!

It feels similar to what's being described here with sub-pixel movement but I don't know for sure, and the solution in that blog post seems like it should be unnecessary (but again - maybe not).

I've created camera scripts and attached them to the virtual camera as follows:

```
float maxPixelHeight = 32;
CinemachineVirtualCamera vcam;

public void Awake()
    {
        float scale = Screen.height / maxPixelHeight;
        float orthographicSize = (Screen.height / scale) / 2f;
        vcam = GetComponent<CinemachineVirtualCamera>();
        vcam.m_Lens.OrthographicSize = orthographicSize;
}

    public void Update()
    {
        Vector3 tempPos = vcam.transform.position;
      Vector3 newPos = new Vector3(Mathf.RoundToInt(tempPos.x), Mathf.RoundToInt(tempPos.y), Mathf.RoundToInt(tempPos.z));
        vcam.transform.position = tempPos;
    }

```

I've also tried:

```
public void Update()
    {
        Vector3 tempPos = vcam.transform.position;
Vector3 newPos = new Vector3((float)System.Math.Round((decimal)tempPos.x, 2) , (float)System.Math.Round((decimal)tempPos.y, 2), (float)System.Math.Round((decimal)tempPos.z, 2));
        vcam.transform.position = newPos;
    }

```

and something like:

```
public void Update()
    {
        Vector3 tempPos = vcam.transform.position;
        vcam.transform.position = new Vector3(RoundToNearestPixel(tempPos.x), RoundToNearestPixel(tempPos.y), RoundToNearestPixel(tempPos.z));
    }

    public float RoundToNearestPixel(float unityUnits)
    {
        float valueInPixels = unityUnits * maxPixelHeight;
        valueInPixels = Mathf.Round(valueInPixels);
        float roundedUnityUnits = valueInPixels * (1 / maxPixelHeight);
        return roundedUnityUnits;
    }

```

# Answer
Note that Cinemachine now has a Pixel Perfect extension that automates the kind of camera calculations I describe further down in this answer. Consider using that, and check the rest of this answer for some intuition about what it's doing and how it fixes the problem.

---

This is something a lot of people get wrong about pixel art rendering, and you'll find a lot of bad advice online - saying the problem is snapping, that you need to adjust the positions of objects to eliminate shimmering.

That's not actually the problem or solution for **this particular warping artifact**. Nearest neighbour / point sampling *already* snaps display positions to the nearest sprite texel for you. So if you're seeing shimmering or warping within a single sprite, it's not snapping that's to blame.

> (Snapping sprite or camera positions *can* help with a different effect: when you have a sprite as a whole that jitters between adjacent pixel positions, or two sprites that appear to vibrate relative to one another, because nearest neighbour filtering decides to snap one whole sprite to the left and the other whole sprite to the right. But that's a topic for another question...)

See this blown up example: even when the mushroom moves smoothly to non-snapped pixel positions, nearest neighbour sampling steps the whole sprite in full-pixel increments, with no shimmer/warping.

The problem is **scale**.

Here's the same sprite, stretched from 16x16 texels in the sprite sheet to cover 17x17 pixels in the screen grid. Nearest neighbour filtering still snaps each pixel to the closest texel sample from the sprite, but because the scale is no longer an integer, this snapping sometimes snaps left in one part of the image, while snapping right in another part of the image, creating localized stretching & compression of doubled/skipped lines of texels.

Here's another example. Both Mario sprites are moving at the same rate, occupying the same sub-pixel positions (no extra snapping script applied). But the one on top has been scaled 1% larger than its native size, creating these warping/rippling artifacts.

So, where does this scaling come from?

If your PPU setting is 32, and your orthographic camera size is 16, then you're showing 32 (16x2) units of the world vertically, 32 sprite texels apiece, for 32x32 = 1024 texels vertically.

So if your window is exactly 1024 pixels tall (or 2048, or 3072, or 4096...), then each texel in your sprite will map to exactly 1 screen pixel (or 2, or 3, or 4...)

If your window is any other size, you'll have a fractional number of screen pixels per sprite pixel, leading to these fractional scaling artifacts.

To solve this, you need to do some combination of:

* Changing the orthographic size of your camera

(eg. 11.25 @ 720p or 16.875 @ 1080p will give 1:1 scaling with 32 PPU, larger screens will see more of the world)
* Adding padding / letterboxing / pillarboxing to the edges of your screen

(eg. Using the above, but cropping the scene in 1080p so that the amount of the scene displayed is the same. The extra space can be filled with UI or decorative borders)
* Rendering at a lower resolution and scaling up by different integer ratios depending on your display size

(eg. rendering to a 360p render target with an orthographic height of 5.625, then scaling it up 2x for 720p, or 3x for 1080p)

* Swapping your assets for alternates at a different resolution

(eg. Drawing an alternate set of sprites at 48x48, 48 PPU, and swapping to them when rendering to a 1080p screen so you see the same area as in 720p)

The goal is to use some combination of settings so that each sprite texel maps to an integer number of screen pixels for your target resolution.

I'm borrowing from a few previous answers I've written on this topic, so you might find those useful for some further details & links:
> 8 votes

---
Tags: unity, tilemap, pixel-art
---


# Question
Title: How can I use 9+ vertices with CollisionPolygon2D?
I am using `CollisionPolygon2D` to implement collision detection for polygons with 3-16 vertices. It works for polygons with 3-8 vertices, but additional vertices (9+) don't seem to register at all.

This is how I implement collision detection for a nonagon in C#:

```
var unit = 256f / 96f;

_collisionShape2D = _node.CreateComponent<CollisionPolygon2D>();
_collisionShape2D.As<CollisionPolygon2D>().VertexCount = 9;
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(0, new Vector2(-0.3515625f, -1.000000f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(1, new Vector2(+0.3515625f, -1.000000f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(2, new Vector2(+0.8593750f, -0.515625f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(3, new Vector2(+1.0000000f, +0.140625f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(4, new Vector2(+0.6250000f, +0.750000f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(5, new Vector2(0000000000f, +1.000000f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(6, new Vector2(-0.6250000f, +0.750000f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(7, new Vector2(-1.0000000f, +0.140625f) / 2 * unit);
_collisionShape2D.As<CollisionPolygon2D>().SetVertex(8, new Vector2(-0.8593750f, -0.515625f) / 2 * unit);

```

Note, the nonagon is a `Sprite2D` with a width and height of exactly 256 pixels. In my project, 1 world unit equals 96 pixels; hence, why I multiply by `unit`.

If this were an octagon, it would work as expected; however, that ninth vertex doesn't seem to register. What actually happens is the eight vertex connects with the first vertex and the ninth is ignored entirely. The same applies to polygons with any number of additional vertices (decagon, hendecagon, and so forth). This leads me to believe `CollisionPolygon2D` simply does not work for polygons with 9+ vertices.

According to the official documentation:

> Polygon shapes are solid convex polygons. A polygon is convex when all line segments connecting two points in the interior do not cross any edge of the polygon. A polygon must have 3 or more vertices.
>
> Polygons vertices winding doesn't matter.

The nonagon in question *is* convex as far as I am aware. This is what it looks like:

*Courtesy of Wikipedia*.

As you can see, *none* of the angles exceed 180, indicating it is indeed convex. The following demonstrates the collision produced in my example:

I tried replacing `CollisionPolygon2D` with `CollisionChain2D` using the exact same vertices to see if that would work instead, but I get really weird collision behavior (as if the size is either very small or just nonexistent; for instance, the object does not rotate as you'd expect when it falls and hits other objects).

For craps and giggles, I decided to add a tenth vertex, which equals the first, thinking maybe I needed to "close" the shape; that theory didn't play out well either...

I did get `CollisionChain2D` to work for *some concave polygons with \<=6 vertices*, but it doesn't appear to work at all for *convex polygons with any number of vertices*.

What am I missing here?

# Answer
> 1 votes
It appears I've found the answer to my own question! After mulling through the source of `Urho3D`, I finally came upon this. On line 58:

```
#define b2_maxPolygonVertices   8

```

Which basically confirms my suspicions. The developers further note:

> Polygons have a maximum number of vertices equal to *b2\_maxPolygonVertices*. In most cases you should not need many vertices for a convex polygon.

Shame this isn't mentioned in the official documentation.

---
Tags: collision-detection, urho3d
---


title: Algorithm for creating spheres?

text:
# Question
Title: Algorithm for creating spheres?
Does anyone have an algorithm for creating a sphere proceduraly with `la` amount of latitude lines, `lo` amount of longitude lines, and a radius of `r`? I need it to work with Unity, so the vertex positions need to be defined and then, the triangles defined via indexes (more info).

---

**EDIT**

I managed to get the code working in unity. But I think I might have done something wrong. When I turn up the `detailLevel`, All it does is add more vertices and polygons without moving them around. Did I forget something?

---

**EDIT 2**

I tried scaling the mesh along its normals. This is what I got. I think I'm missing something. Am I supposed to only scale certain normals?

# Answer
To get something like this:

Create an icosahedron (20-sided regular solid) and subdivide the faces to get a sphere (see code below).

The idea is basically:

* Create a regular n-hedron (a solid where every face is the same size and every edge is the same length). I use an icosahedron because it's the regular solid with the greatest number of faces. (There's a proof for that somewhere out there. Feel free to Google if you're really curious.) This will give you a sphere where nearly every face is the same size, making texturing a little easier.

* Subdivide each face into four equally-sized faces. Each time you do this, it'll quadruple the number of faces in the model.

```
///      i0
///     /  \
///    m02-m01
///   /  \ /  \
/// i2---m12---i1

```

`i0`, `i1`, and `i2` are the vertices of the original triangle. (Actually, indices into the vertex buffer, but that's another topic). `m01` is the midpoint of the edge `(i0,i1)`, m12 is the midpoint of the edge `(i1,12)`, and `m02` is, obviously, the midpoint of the edge `(i0,i2)`.

Whenever you subdivide a face, make sure that you don't create duplicate vertices. Each midpoint will be shared by one other source face (since the edges are shared between faces). The code below accounts for that by maintaining a dictionary of named midpoints that have been created, and returning the index of a previously created midpoint when it's available rather than creating a new one.

* Repeat until you've reached the desired number of faces for your cube.
* When you're done, normalize all of the vertices to smooth out the surface. If you don't do this, you'll just get a higher-res icosahedron instead of a sphere.
* Voila! You're done. Convert the resulting vector and index buffers into a `VertexBuffer` and `IndexBuffer`, and draw with `Device.DrawIndexedPrimitives()`.

Here's what you'd use in your "Sphere" class to create the model (XNA datatypes and C#, but it should be pretty clear):

```
        var vectors = new List<Vector3>();
        var indices = new List<int>();

        GeometryProvider.Icosahedron(vectors, indices);

        for (var i = 0; i < _detailLevel; i++)
            GeometryProvider.Subdivide(vectors, indices, true);

        /// normalize vectors to "inflate" the icosahedron into a sphere.
        for (var i = 0; i < vectors.Count; i++)
            vectors[i]=Vector3.Normalize(vectors[i]);

```

And the `GeometryProvider` class

```
public static class GeometryProvider
{

    private static int GetMidpointIndex(Dictionary<string, int> midpointIndices, List<Vector3> vertices, int i0, int i1)
    {

        var edgeKey = string.Format("{0}_{1}", Math.Min(i0, i1), Math.Max(i0, i1));

        var midpointIndex = -1;

        if (!midpointIndices.TryGetValue(edgeKey, out midpointIndex))
        {
            var v0 = vertices[i0];
            var v1 = vertices[i1];

            var midpoint = (v0 + v1) / 2f;

            if (vertices.Contains(midpoint))
                midpointIndex = vertices.IndexOf(midpoint);
            else
            {
                midpointIndex = vertices.Count;
                vertices.Add(midpoint);
                midpointIndices.Add(edgeKey, midpointIndex);
            }
        }

        return midpointIndex;

    }

    /// <remarks>
    ///      i0
    ///     /  \
    ///    m02-m01
    ///   /  \ /  \
    /// i2---m12---i1
    /// </remarks>
    /// <param name="vectors"></param>
    /// <param name="indices"></param>
    public static void Subdivide(List<Vector3> vectors, List<int> indices, bool removeSourceTriangles)
    {
        var midpointIndices = new Dictionary<string, int>();

        var newIndices = new List<int>(indices.Count * 4);

        if (!removeSourceTriangles)
            newIndices.AddRange(indices);

        for (var i = 0; i < indices.Count - 2; i += 3)
        {
            var i0 = indices[i];
            var i1 = indices[i + 1];
            var i2 = indices[i + 2];

            var m01 = GetMidpointIndex(midpointIndices, vectors, i0, i1);
            var m12 = GetMidpointIndex(midpointIndices, vectors, i1, i2);
            var m02 = GetMidpointIndex(midpointIndices, vectors, i2, i0);

            newIndices.AddRange(
                new[] {
                    i0,m01,m02
                    ,
                    i1,m12,m01
                    ,
                    i2,m02,m12
                    ,
                    m02,m01,m12
                }
                );

        }

        indices.Clear();
        indices.AddRange(newIndices);
    }

    /// <summary>
    /// create a regular icosahedron (20-sided polyhedron)
    /// </summary>
    /// <param name="primitiveType"></param>
    /// <param name="size"></param>
    /// <param name="vertices"></param>
    /// <param name="indices"></param>
    /// <remarks>
    /// You can create this programmatically instead of using the given vertex
    /// and index list, but it's kind of a pain and rather pointless beyond a
    /// learning exercise.
    /// </remarks>

    /// note: icosahedron definition may have come from the OpenGL red book. I don't recall where I found it.
    public static void Icosahedron(List<Vector3> vertices, List<int> indices)
    {

        indices.AddRange(
            new int[]
            {
                0,4,1,
                0,9,4,
                9,5,4,
                4,5,8,
                4,8,1,
                8,10,1,
                8,3,10,
                5,3,8,
                5,2,3,
                2,7,3,
                7,10,3,
                7,6,10,
                7,11,6,
                11,0,6,
                0,1,6,
                6,1,10,
                9,0,11,
                9,11,2,
                9,2,5,
                7,2,11
            }
            .Select(i => i + vertices.Count)
        );

        var X = 0.525731112119133606f;
        var Z = 0.850650808352039932f;

        vertices.AddRange(
            new[]
            {
                new Vector3(-X, 0f, Z),
                new Vector3(X, 0f, Z),
                new Vector3(-X, 0f, -Z),
                new Vector3(X, 0f, -Z),
                new Vector3(0f, Z, X),
                new Vector3(0f, Z, -X),
                new Vector3(0f, -Z, X),
                new Vector3(0f, -Z, -X),
                new Vector3(Z, X, 0f),
                new Vector3(-Z, X, 0f),
                new Vector3(Z, -X, 0f),
                new Vector3(-Z, -X, 0f)
            }
        );

    }

}

```
> 31 votes

# Answer
Let us consider the parametric definition of a sphere:

where theta and phi are two incrementing angles, that we will refer to as `var t` and `var u` and Rx, Ry and Rz are the independent radii (radiuses) in all three cartesian directions, which, in the case of a sphere, will be defined as one single radius `var rad`.

Let us now consider the fact that the `...` symbol indicates an iteration which hints the use of a loop. The concept of `stacks` and `rows` is "how many times will you iterate". Since each iteration adds the the value of t or u, the more iterations, the smaller the value is, therefore the more precise the curvature of the sphere is.

The 'sphere drawing' function's precondition is to have the following given parameters: `int latitudes, int longitudes, float radius`. The post conditions (output) is to return, or apply the calculated vertices. Depending on how you intend to use this, the function could return an array of `vector3` (three dimensional vectors) or, if you are using some sort of simple OpenGL, prior to version 2.0, you might want to apply the vertices to the context directly.

N.B. Applying a vertex in openGL is calling the following function `glVertex3f(x, y, z)`. In the case where we would store the vertices, we would add an new `vector3(x, y, z)` for easy storage.

Also, the way you requested the latitude and longitude system to work needed an adjustment to the definition of the sphere (basically switching z and y), but this just shows that the definition is very malleable, and that you are free to switch around the x, y and z parameters to alter the direction in which the sphere is drawn (where the latitudes and longitudes are).

Now let us look at how we are going to do the latitudes and longitudes. Latitudes are represented by the variable `u`, they iterate from 0 to 2π radians (360 degrees). We can therefore code its iteration like so:

```
float latitude_increment = 360.0f / latitudes;

for (float u = 0; u < 360.0f; u += latitude_increment) {
    // further code ...
}

```

Now the longitudes are represented by the variable `t` and iterates for 0 to π (180 degrees). therefore the following code looks similar to the previous one:

```
float latitude_increment = 360.0f / latitudes;
float longitude_increment = 180.0f / longitudes;

for (float u = 0; u <= 360.0f; u += latitude_increment) {
    for (float t = 0; t <= 180.0f; t += longitude_increment) {
        // further code ...
    }
}

```

(Note that loops are **Inclusive** of there terminal condition, because the interval for parametric integration is from 0 to 2π **Inclusive**. you will get a partial sphere if your conditions are non-inclusive.)

Now, following the simple definition of the sphere we can derive the variable definition as follows (assume `float rad = radius;`):

```
float x = (float) (rad * Math.sin(Math.toRadians(t)) * Math.sin(Math.toRadians(u)));
float y = (float) (rad * Math.cos(Math.toRadians(t)));
float z = (float) (rad * Math.sin(Math.toRadians(t)) * Math.cos(Math.toRadians(u)));

```

One more important warning! In most cases you will be using some form of OpenGL, and even if not so, the you might still need to do this. An object in three dimensional needs several vertices to be defined. This is generally achieved by providing the next vertex that is computable.

Just how in the figure above the different coordinates are `x+∂` and `y+∂`, we can easily generate three other vertices for any desired use. The other vertices are (assume `float rad = radius;`):

```
float x = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.sin(Math.toRadians(u)));
float y = (float) (rad * Math.cos(Math.toRadians(t + longitude_increment)));
float z = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.cos(Math.toRadians(u)));

float x = (float) (rad * Math.sin(Math.toRadians(t)) * Math.sin(Math.toRadians(u + latitude_increment)));
float y = (float) (rad * Math.cos(Math.toRadians(t)));
float z = (float) (rad * Math.sin(Math.toRadians(t)) * Math.cos(Math.toRadians(u + latitude_increment)));

float x = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.sin(Math.toRadians(u + latitude_increment)));
float y = (float) (rad * Math.cos(Math.toRadians(t + longitude_increment)));
float z = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.cos(Math.toRadians(u + latitude_increment)));

```

Finally, here is a working full function that would return all vertices of a sphere, and the second one shows a working OpenGL implementation of the code (this is C-style syntax and not JavaScript, this should work with all C-style languages, including C# when using Unity).

```
static Vector3[] generateSphere(float radius, int latitudes, int longitudes) {

    float latitude_increment = 360.0f / latitudes;
    float longitude_increment = 180.0f / longitudes;

    // if this causes an error, consider changing the size to [(latitude + 1)*(longitudes + 1)], but this should work.
    Vector3[] vertices = new Vector3[latitude*longitudes];

    int counter = 0;

    for (float u = 0; u < 360.0f; u += latitude_increment) {
        for (float t = 0; t < 180.0f; t += longitude_increment) {

            float rad = radius;

            float x = (float) (rad * Math.sin(Math.toRadians(t)) * Math.sin(Math.toRadians(u)));
            float y = (float) (rad * Math.cos(Math.toRadians(t)));
            float z = (float) (rad * Math.sin(Math.toRadians(t)) * Math.cos(Math.toRadians(u)));

            vertices[counter++] = new Vector3(x, y, z);

        }
    }

    return vertices;

}

```

OpenGL code:

```
static int createSphereBuffer(float radius, int latitudes, int longitudes) {

    int lst;

    lst = glGenLists(1);

    glNewList(lst, GL_COMPILE);
    {

        float latitude_increment = 360.0f / latitudes;
        float longitude_increment = 180.0f / longitudes;

        for (float u = 0; u < 360.0f; u += latitude_increment) {

            glBegin(GL_TRIANGLE_STRIP);

            for (float t = 0; t < 180.0f; t += longitude_increment) {

                float rad = radius;

                float x = (float) (rad * Math.sin(Math.toRadians(t)) * Math.sin(Math.toRadians(u)));
                float y = (float) (rad * Math.cos(Math.toRadians(t)));
                float z = (float) (rad * Math.sin(Math.toRadians(t)) * Math.cos(Math.toRadians(u)));

                vertex3f(x, y, z);

                float x1 = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.sin(Math.toRadians(u + latitude_increment)));
                float y1 = (float) (rad * Math.cos(Math.toRadians(t + longitude_increment)));
                float z1 = (float) (rad * Math.sin(Math.toRadians(t + longitude_increment)) * Math.cos(Math.toRadians(u + latitude_increment)));

                vertex3f(x1, y1, z1);

            }

            glEnd();

        }

    }
    glEndList()

    return lst;

}

// to render VVVVVVVVV

// external variable in main file
static int sphereList = createSphereBuffer(desired parameters)

// called by the main program
void render() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glCallList(sphereList);

    // any additional rendering and buffer swapping if not handled already.

}

```

P.S. You may have noticed this statement `rad = radius;`. This allows the radius to be modified in the loop, based on the location or the angle. This means that you can apply noise to the sphere to roughen it, making it look more natural if the desired effect is a planet-like one. E.g. `float rad = radius * noise[x][y][z];`

Claude-Henry.
> 6 votes

# Answer
I created something like this a while back to make a sphere of cubes, for fun and science. It's not too hard. Basically, you take a function that creates a circle of vertices, then step through the height increments you want creating circles at each height at the radius required to make a sphere. Here I've modified the code to not be for cubes:

```
public static void makeSphere(float sphereRadius, Vector3f center, float heightStep, float degreeStep) {
    for (float y = center.y - sphereRadius; y <= center.y + sphereRadius; y+=heightStep) {
        double radius = SphereRadiusAtHeight(sphereRadius, y - center.y); //get the radius of the sphere at this height
        if (radius == 0) {//for the top and bottom points of the sphere add a single point
            addNewPoint((Math.sin(0) * radius) + center.x, y, (Math.cos(0) * radius) + center.z));
        } else { //otherwise step around the circle and add points at the specified degrees
            for (float d = 0; d <= 360; d += degreeStep) {
                addNewPoint((Math.sin(d) * radius) + center.x, y, (Math.cos(d) * radius) + center.z));
            }
        }
    }
}

public static double SphereRadiusAtHeight(double SphereRadius, double Height) {
    return Math.sqrt((SphereRadius * SphereRadius) - (Height * Height));
}

```

Now this code would just create points for the latitude. However, you can almost use the same code to make the longitude lines. Except you'll need to rotate between each iteration and make a full circle at each `degreeStep`.

Sorry this is not a complete answer or Unity specific, but hopefully it'll get you started.
> 4 votes

# Answer
Couldn't you just start with a simple shape, could be a box with r distance from center to corner. To make a more detailed sphere, subdivide all the polygons and then move the vertices out to r distance from the center, having the vector going through their current position.

Keep repeating until spherical enough for your tastes.
> 3 votes

# Answer
Do you actually need the 3D geometry or just the shape?

You can make a 'fake' sphere using a single quad. Just put a circle on it and shade it correctly. This has the advantage that it will have exactly the resolution required regardless of the distance to the camera or resolution.

There's a tutorial here.
> 2 votes

# Answer
here is some code for any number of equally spaced vertices of a sphere, its like an orange peel it winds a line of dots around a sphere in a spiral. afterwards, how you join the vertices is up to you. you can use neighbour dots in the loop as 2 of each triangle and then find the third would be a proportional one twist around the sphere higher up or lower down... you can also do triangles by loop and nearest neighbour on it, does someone know a better way?

```
var spherevertices = vector3 generic list...

public var numvertices= 1234;
var size = .03;

function sphere ( N:float){//<--- N is the number of vertices i.e 123

var inc =  Mathf.PI  * (3 - Mathf.Sqrt(5));
var off = 2 / N;
for (var k = 0; k < (N); k++)
{
    var y = k * off - 1 + (off / 2);
    var r = Mathf.Sqrt(1 - y*y);
    var phi = k * inc;
    var pos = Vector3((Mathf.Cos(phi)*r*size), y*size, Mathf.Sin(phi)*r*size);

    spherevertices   add pos...

}

```

};
> 0 votes

# Answer
Although David is absolutely correct in his answer, I want to offer a different perspective.

For my assignment for procedural content generation, I looked at (among other things) icosahedron versus more traditional subdivided spheres. Look at these procedurally generated spheres:

Both look like perfectly valid spheres, right? Well, let's look at their wireframes:

Wow, what happened there? The wireframe version of the second sphere is *so dense* that it looks textured! I'll let you in on a secret: the second version is an icosahedron. It's an almost perfect sphere, but it comes at a high price.

Sphere 1 uses 31 subdivisions on the x-axis and 31 subdivisions on the z-axis, for a total of **3,844** faces.

Sphere 2 uses 5 recursive subdivisions, for a total of **109,220** faces.

But okay, that's not really fair. Let's scale down the quality considerably:

Sphere 1 uses 5 subdivisions on the x-axis and 5 subdivisions on the z-axis, for a total of 100 faces.

Sphere 2 uses 0 recursive subdivisions, for a total of 100 faces.

They use the same amount of faces, but in my opinion, the sphere on the left looks better. It looks less lumpy and a lot more round. Let's take a look at how many faces we generate with both methods.

Icosahedron:

* Level 0 - 100 faces
* Level 1 - 420 faces
* Level 2 - 1,700 faces
* Level 3 - 6,820 faces
* Level 4 - 27,300 faces
* Level 5 - 109,220 faces

Subdivided sphere:

* YZ: 5 - 100 faces
* YZ: 10 - 400 faces
* YZ: 15 - 900 faces
* YZ: 20 - 1,600 faces
* YZ: 25 - 2,500 faces
* YZ: 30 - 3,600 faces

As you can see, the icosahedron increases in faces at an exponential rate, to a third power! That is because for every triangle, we must subdivide them into three new triangles.

The truth is: you don't *need* the precision an icosahedron will give you. Because they both hide a much harder problem: texturing a 2D plane on a 3D sphere. Here's what the top looks like:

On the top-left, you can see the texture being used. Coincidentally, it's also being generated procedurally. (Hey, it was a course on procedural generation, right?)

It looks terrible, right? Well, this is as good as it's going to get. I got top marks for my texture mapping, because most people don't even get it this right.

So please, consider using cosine and sine to generate a sphere. It generates a lot less faces for the same amount of detail.
> -1 votes

# Answer
The below script will create an Icosahedron with n Polygons...base 12. It will also subdivide the polygons into separate meshes, and calculate the total verts-duplicates and polygons.
I couldn't find anything similar so I created this. Just attach the script to a GameObject, and set the subdivisions in the Editor. Working on noise modification next.

```
/* Creates an initial Icosahedron with 12 vertices...
 * ...Adapted from https://medium.com/@peter_winslow/creating-procedural-icosahedrons-in-unity-part-1-df83ecb12e91
 * ...And a couple other Icosahedron C# for Unity scripts
 *
 * Allows an Icosahedron to be created with multiple separate polygon meshes
 * I used a dictionary of Dictionary<int, List<Vector3>> to represent the
 * Polygon index and the vertice index
 * polygon[0] corresponds to vertice[0]
 * so that all vertices in dictionary vertice[0] will correspond to the polygons in polygon[0]
 *
 * If you need help understanding Dictionaries
 * https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx
 *
 * --I used dictionaries because I didn't know what programming instrument to use, so there may be more
 * elegant or efficient ways to go about this.
 *
 * Essentially int represents the index, and
 * List<Vector3> represents the actual Vector3 Transforms of the triangle
 * OR List<Vector3> in the polygon dictionary will act as a reference to the indice/index number of the vertices
 *
 * For example the polygon dictionary at key[0] will contain a list of Vector3's representing polygons
 * ... Vector3.x , Vector3.y, Vector3.z in the polygon list would represent the 3 indexes of the vertice[0] list
 * AKA the three Vector3 transforms that make up the triangle
 *    .
 *  ./_\.
 *
 * Create a new GameObject and attach this script
 *  -The folders for the material and saving of the mesh data will be created automatically
 *    -Line 374/448
 *
 * numOfMainTriangles will represent the individual meshes created
 * numOfSubdivisionsWithinEachTriangle represents the number of subdivisions within each mesh
 *
 * Before running with Save Icosahedron checked be aware that it can take several minutes to
 *   generate and save all the meshes depending on the level of divisions
 *
 * There may be a faster way to save assets - Line 430 - AssetDatabase.CreateAsset(asset,path);
 * */

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class UnityIcosahedronGenerator : MonoBehaviour {
    IcosahedronGenerator icosahedron;
    public const int possibleSubDivisions = 7;
    public static readonly int[] supportedChunkSizes = { 20, 80, 320, 1280, 5120, 20480, 81920};

    [Range(0, possibleSubDivisions - 1)]
    public int numOfMainTriangles = 0;
    [Range(0,possibleSubDivisions - 1)]
    public int numOfSubdivisionsWithinEachTriangle = 0;
    public bool saveIcosahedron = false;

    // Use this for initialization
    void Start() {
        icosahedron = ScriptableObject.CreateInstance<IcosahedronGenerator>();

        // 0 = 12 verts, 20 tris
        icosahedron.GenBaseIcosahedron();
        icosahedron.SeparateAllPolygons();

        // 0 = 12 verts, 20 tris - Already Generated with GenBaseIcosahedron()
        // 1 = 42 verts, 80 tris
        // 2 = 162 verts, 320 tris
        // 3 = 642 verts, 1280 tris
        // 5 = 2562 verts, 5120 tris
        // 5 = 10242 verts, 20480 tris
        // 6 = 40962verts, 81920 tris
        if (numOfMainTriangles > 0) {
            icosahedron.Subdivide(numOfMainTriangles);
        }
        icosahedron.SeparateAllPolygons();

        if (numOfSubdivisionsWithinEachTriangle > 0) {
            icosahedron.Subdivide(numOfSubdivisionsWithinEachTriangle);
        }

        icosahedron.CalculateMesh(this.gameObject, numOfMainTriangles,numOfSubdivisionsWithinEachTriangle, saveIcosahedron);
        icosahedron.DisplayVertAndPolygonCount();
    }
}

public class Vector3Dictionary {
    public List<Vector3> vector3List;
    public Dictionary<int, List<Vector3>> vector3Dictionary;

    public Vector3Dictionary() {
        vector3Dictionary = new Dictionary<int, List<Vector3>>();
        return;
    }

    public void Vector3DictionaryList(int x, int y, int z) {
        vector3List = new List<Vector3>();

        vector3List.Add(new Vector3(x, y, z));
        vector3Dictionary.Add(vector3Dictionary.Count, vector3List);

        return;
    }

    public void Vector3DictionaryList(int index, Vector3 vertice) {
        vector3List = new List<Vector3>();

        if (vector3Dictionary.ContainsKey(index)) {
            vector3List = vector3Dictionary[index];
            vector3List.Add(vertice);
            vector3Dictionary[index] = vector3List;
        } else {
            vector3List.Add(vertice);
            vector3Dictionary.Add(index, vector3List);
        }

        return;
    }

    public void Vector3DictionaryList(int index, List<Vector3> vertice, bool list) {
        vector3List = new List<Vector3>();

        if (vector3Dictionary.ContainsKey(index)) {
            vector3List = vector3Dictionary[index];
            for (int a = 0; a < vertice.Count; a++) {
                vector3List.Add(vertice[a]);
            }
            vector3Dictionary[index] = vector3List;
        } else {
            for (int a = 0; a < vertice.Count; a++) {
                vector3List.Add(vertice[a]);
            }
            vector3Dictionary.Add(index, vector3List);
        }

        return;
    }

    public void Vector3DictionaryList(int index, int x, int y, int z) {
        vector3List = new List<Vector3>();

        if (vector3Dictionary.ContainsKey(index)) {
            vector3List = vector3Dictionary[index];
            vector3List.Add(new Vector3(x, y, z));
            vector3Dictionary[index] = vector3List;
        } else {
            vector3List.Add(new Vector3(x, y, z));
            vector3Dictionary.Add(index, vector3List);
        }

        return;
    }

    public void Vector3DictionaryList(int index, float x, float y, float z, bool replace) {
        if (replace) {
            vector3List = new List<Vector3>();

            vector3List.Add(new Vector3(x, y, z));
            vector3Dictionary[index] = vector3List;
        }

        return;
    }
}

public class IcosahedronGenerator : ScriptableObject {
    public Vector3Dictionary icosahedronPolygonDict;
    public Vector3Dictionary icosahedronVerticeDict;
    public bool firstRun = true;

    public void GenBaseIcosahedron() {
        icosahedronPolygonDict = new Vector3Dictionary();
        icosahedronVerticeDict = new Vector3Dictionary();

        // An icosahedron has 12 vertices, and
        // since it's completely symmetrical the
        // formula for calculating them is kind of
        // symmetrical too:

        float t = (1.0f + Mathf.Sqrt(5.0f)) / 2.0f;

        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(-1, t, 0).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(1, t, 0).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(-1, -t, 0).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(1, -t, 0).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(0, -1, t).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(0, 1, t).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(0, -1, -t).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(0, 1, -t).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(t, 0, -1).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(t, 0, 1).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(-t, 0, -1).normalized);
        icosahedronVerticeDict.Vector3DictionaryList(0, new Vector3(-t, 0, 1).normalized);

        // And here's the formula for the 20 sides,
        // referencing the 12 vertices we just created.
        // Each side will be placed in it's own dictionary key.
        // The first number is the key/index, and the next 3 numbers reference the vertice index
        icosahedronPolygonDict.Vector3DictionaryList(0, 0, 11, 5);
        icosahedronPolygonDict.Vector3DictionaryList(1, 0, 5, 1);
        icosahedronPolygonDict.Vector3DictionaryList(2, 0, 1, 7);
        icosahedronPolygonDict.Vector3DictionaryList(3, 0, 7, 10);
        icosahedronPolygonDict.Vector3DictionaryList(4, 0, 10, 11);
        icosahedronPolygonDict.Vector3DictionaryList(5, 1, 5, 9);
        icosahedronPolygonDict.Vector3DictionaryList(6, 5, 11, 4);
        icosahedronPolygonDict.Vector3DictionaryList(7, 11, 10, 2);
        icosahedronPolygonDict.Vector3DictionaryList(8, 10, 7, 6);
        icosahedronPolygonDict.Vector3DictionaryList(9, 7, 1, 8);
        icosahedronPolygonDict.Vector3DictionaryList(10, 3, 9, 4);
        icosahedronPolygonDict.Vector3DictionaryList(11, 3, 4, 2);
        icosahedronPolygonDict.Vector3DictionaryList(12, 3, 2, 6);
        icosahedronPolygonDict.Vector3DictionaryList(13, 3, 6, 8);
        icosahedronPolygonDict.Vector3DictionaryList(14, 3, 8, 9);
        icosahedronPolygonDict.Vector3DictionaryList(15, 4, 9, 5);
        icosahedronPolygonDict.Vector3DictionaryList(16, 2, 4, 11);
        icosahedronPolygonDict.Vector3DictionaryList(17, 6, 2, 10);
        icosahedronPolygonDict.Vector3DictionaryList(18, 8, 6, 7);
        icosahedronPolygonDict.Vector3DictionaryList(19, 9, 8, 1);

        return;
    }

    public void SeparateAllPolygons(){
        // Separates all polygons and vertex keys/indicies into their own key/index
        // For example if the numOfMainTriangles is set to 2,
        // This function will separate each polygon/triangle into it's own index
        // By looping through all polygons in each dictionary key/index

        List<Vector3> originalPolygons = new List<Vector3>();
        List<Vector3> originalVertices = new List<Vector3>();
        List<Vector3> newVertices = new List<Vector3>();
        Vector3Dictionary tempIcosahedronPolygonDict = new Vector3Dictionary();
        Vector3Dictionary tempIcosahedronVerticeDict = new Vector3Dictionary();

        // Cycles through the polygon list
        for (int i = 0; i < icosahedronPolygonDict.vector3Dictionary.Count; i++) {
            originalPolygons = new List<Vector3>();
            originalVertices = new List<Vector3>();

            // Loads all the polygons in a certain index/key
            originalPolygons = icosahedronPolygonDict.vector3Dictionary[i];

            // Since the original script was set up without a dictionary index
            // It was easier to loop all the original triangle vertices into index 0
            // Thus the first time this function runs, all initial vertices will be
            // redistributed to the correct indicies/index/key

            if (firstRun) {
                originalVertices = icosahedronVerticeDict.vector3Dictionary[0];
            } else {
                // i - 1 to account for the first iteration of pre-set vertices
                originalVertices = icosahedronVerticeDict.vector3Dictionary[i];
            }

            // Loops through all the polygons in a specific Dictionary key/index
            for (int a = 0; a < originalPolygons.Count; a++){
                newVertices = new List<Vector3>();

                int x = (int)originalPolygons[a].x;
                int y = (int)originalPolygons[a].y;
                int z = (int)originalPolygons[a].z;

                // Adds three vertices/transforms for each polygon in the list
                newVertices.Add(originalVertices[x]);
                newVertices.Add(originalVertices[y]);
                newVertices.Add(originalVertices[z]);

                // Overwrites the Polygon indices from their original locations
                // index (20,11,5) for example would become (0,1,2) to correspond to the
                // three new Vector3's added to the list.
                // In the case of this function there will only be 3 Vector3's associated to each dictionary key
                tempIcosahedronPolygonDict.Vector3DictionaryList(0, 1, 2);

                // sets the index to the size of the temp dictionary list
                int tempIndex = tempIcosahedronPolygonDict.vector3Dictionary.Count;
                // adds the new vertices to the corresponding same key in the vertice index
                // which corresponds to the same key/index as the polygon dictionary
                tempIcosahedronVerticeDict.Vector3DictionaryList(tempIndex - 1, newVertices, true);
            }
        }
        firstRun = !firstRun;

        // Sets the temp dictionarys as the main dictionaries
        icosahedronVerticeDict = tempIcosahedronVerticeDict;
        icosahedronPolygonDict = tempIcosahedronPolygonDict;
    }

    public void Subdivide(int recursions) {
        // Divides each triangle into 4 triangles, and replaces the Dictionary entry

        var midPointCache = new Dictionary<int, int>();
        int polyDictIndex = 0;
        List<Vector3> originalPolygons = new List<Vector3>();
        List<Vector3> newPolygons;

        for (int x = 0; x < recursions; x++) {
            polyDictIndex = icosahedronPolygonDict.vector3Dictionary.Count;
            for (int i = 0; i < polyDictIndex; i++) {
                newPolygons = new List<Vector3>();
                midPointCache = new Dictionary<int, int>();
                originalPolygons = icosahedronPolygonDict.vector3Dictionary[i];

                for (int z = 0; z < originalPolygons.Count; z++) {
                    int a = (int)originalPolygons[z].x;
                    int b = (int)originalPolygons[z].y;
                    int c = (int)originalPolygons[z].z;

                    // Use GetMidPointIndex to either create a
                    // new vertex between two old vertices, or
                    // find the one that was already created.
                    int ab = GetMidPointIndex(i,midPointCache, a, b);
                    int bc = GetMidPointIndex(i,midPointCache, b, c);
                    int ca = GetMidPointIndex(i,midPointCache, c, a);

                    // Create the four new polygons using our original
                    // three vertices, and the three new midpoints.
                    newPolygons.Add(new Vector3(a, ab, ca));
                    newPolygons.Add(new Vector3(b, bc, ab));
                    newPolygons.Add(new Vector3(c, ca, bc));
                    newPolygons.Add(new Vector3(ab, bc, ca));
                }
                // Replace all our old polygons with the new set of
                // subdivided ones.
                icosahedronPolygonDict.vector3Dictionary[i] = newPolygons;
            }
        }
        return;
    }

    int GetMidPointIndex(int polyIndex, Dictionary<int, int> cache, int indexA, int indexB) {
        // We create a key out of the two original indices
        // by storing the smaller index in the upper two bytes
        // of an integer, and the larger index in the lower two
        // bytes. By sorting them according to whichever is smaller
        // we ensure that this function returns the same result
        // whether you call
        // GetMidPointIndex(cache, 5, 9)
        // or...
        // GetMidPointIndex(cache, 9, 5)

        int smallerIndex = Mathf.Min(indexA, indexB);
        int greaterIndex = Mathf.Max(indexA, indexB);
        int key = (smallerIndex << 16) + greaterIndex;

        // If a midpoint is already defined, just return it.
        int ret;
        if (cache.TryGetValue(key, out ret))
            return ret;

        // If we're here, it's because a midpoint for these two
        // vertices hasn't been created yet. Let's do that now!
        List<Vector3> tempVertList = icosahedronVerticeDict.vector3Dictionary[polyIndex];

        Vector3 p1 = tempVertList[indexA];
        Vector3 p2 = tempVertList[indexB];
        Vector3 middle = Vector3.Lerp(p1, p2, 0.5f).normalized;

        ret = tempVertList.Count;
        tempVertList.Add(middle);
        icosahedronVerticeDict.vector3Dictionary[polyIndex] = tempVertList;

        cache.Add(key, ret);
        return ret;
    }

    public void CalculateMesh(GameObject icosahedron, int numOfMainTriangles, int numOfSubdivisionsWithinEachTriangle, bool saveIcosahedron) {
        GameObject meshChunk;
        List<Vector3> meshPolyList;
        List<Vector3> meshVertList;
        List<int> triList;

        CreateFolders(numOfMainTriangles, numOfSubdivisionsWithinEachTriangle);
        CreateMaterial();

        // Loads a material from the Assets/Resources/ folder so that it can be saved with the prefab later
        Material material = Resources.Load("BlankSphere", typeof(Material)) as Material;

        int polyDictIndex = icosahedronPolygonDict.vector3Dictionary.Count;

        // Used to assign the child objects as well as to be saved as the .prefab
        // Sets the name
        icosahedron.gameObject.name = "Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle;

        for (int i = 0; i < polyDictIndex; i++) {
            meshPolyList = new List<Vector3>();
            meshVertList = new List<Vector3>();
            triList = new List<int>();
            // Assigns the polygon and vertex indices
            meshPolyList = icosahedronPolygonDict.vector3Dictionary[i];
            meshVertList = icosahedronVerticeDict.vector3Dictionary[i];

            // Sets the child gameobject parameters
            meshChunk = new GameObject("MeshChunk");
            meshChunk.transform.parent = icosahedron.gameObject.transform;
            meshChunk.transform.localPosition = new Vector3(0, 0, 0);
            meshChunk.AddComponent<MeshFilter>();
            meshChunk.AddComponent<MeshRenderer>();
            meshChunk.GetComponent<MeshRenderer>().material = material;
            meshChunk.AddComponent<MeshCollider>();
            Mesh mesh = meshChunk.GetComponent<MeshFilter>().mesh;

            // Adds the triangles to the list
            for (int z = 0; z < meshPolyList.Count; z++) {
                triList.Add((int)meshPolyList[z].x);
                triList.Add((int)meshPolyList[z].y);
                triList.Add((int)meshPolyList[z].z);
            }

            mesh.vertices = meshVertList.ToArray();
            mesh.triangles = triList.ToArray();
            mesh.uv = new Vector2[meshVertList.Count];

            /*
            //Not Needed because all normals have been calculated already
            Vector3[] _normals = new Vector3[meshVertList.Count];
            for (int d = 0; d < _normals.Length; d++){
                _normals[d] = meshVertList[d].normalized;
            }
            mesh.normals = _normals;
            */

            mesh.normals = meshVertList.ToArray();

            mesh.RecalculateBounds();

            // Saves each chunk mesh to a specified folder
            // The folder must exist
            if (saveIcosahedron) {
                string sphereAssetName = "icosahedronChunk" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle + "_" + i + ".asset";
                AssetDatabase.CreateAsset(mesh, "Assets/Icosahedrons/Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle + "/" + sphereAssetName);
                AssetDatabase.SaveAssets();
            }
        }

        // Removes the script for the prefab save
        // Saves the prefab to a specified folder
        // The folder must exist
        if (saveIcosahedron) {
            DestroyImmediate(icosahedron.GetComponent<UnityIcosahedronGenerator>());
            PrefabUtility.CreatePrefab("Assets/Icosahedrons/Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle + "/Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle + ".prefab", icosahedron);
        }

        return;
    }

    void CreateFolders(int numOfMainTriangles, int numOfSubdivisionsWithinEachTriangle){
        // Creates the folders if they don't exist
        if (!AssetDatabase.IsValidFolder("Assets/Icosahedrons")) {
            AssetDatabase.CreateFolder("Assets", "Icosahedrons");
        }
        if (!AssetDatabase.IsValidFolder("Assets/Icosahedrons/Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle)) {
            AssetDatabase.CreateFolder("Assets/Icosahedrons", "Icosahedron" + numOfMainTriangles + "Recursion" + numOfSubdivisionsWithinEachTriangle);
        }
        if (!AssetDatabase.IsValidFolder("Assets/Resources")) {
            AssetDatabase.CreateFolder("Assets", "Resources");
        }

        return;
    }

    static void CreateMaterial() {
        if (Resources.Load("BlankSphere", typeof(Material)) == null) {
            // Create a simple material asset if one does not exist
            Material material = new Material(Shader.Find("Standard"));
            material.color = Color.blue;
            AssetDatabase.CreateAsset(material, "Assets/Resources/BlankSphere.mat");
        }

        return;
    }

    // Displays the Total Polygon/Triangle and Vertice Count
    public void DisplayVertAndPolygonCount(){
        List<Vector3> tempVertices;
        HashSet<Vector3> verticeHash = new HashSet<Vector3>();

        int polygonCount = 0;
        List<Vector3> tempPolygons;

        // Saves Vertices to a hashset to ensure no duplicate vertices are counted
        for (int a = 0; a < icosahedronVerticeDict.vector3Dictionary.Count; a++) {
            tempVertices = new List<Vector3>();
            tempVertices = icosahedronVerticeDict.vector3Dictionary[a];
            for (int b = 0; b < tempVertices.Count; b++) {
                verticeHash.Add(tempVertices[b]);
            }
        }

        for (int a = 0; a < icosahedronPolygonDict.vector3Dictionary.Count; a++) {
            tempPolygons = new List<Vector3>();
            tempPolygons = icosahedronPolygonDict.vector3Dictionary[a];
            for (int b = 0; b < tempPolygons.Count; b++) {
                polygonCount++;
            }
        }

        Debug.Log("Vertice Count: " + verticeHash.Count);
        Debug.Log("Polygon Count: " + polygonCount);

        return;
    }
}

```
> -1 votes

---
Tags: unity, procedural-generation, 3d-meshes
---


title: Triangle mesh smoothing

text:
# Question
Title: Triangle mesh smoothing
I have a grid in terms of two arrays:

`points`: contains 3D coordinates of points.

`triangles`: contains 3 indices per line for each triangle of the grid.

I would like to interpolate the grid to make it smoother, i.e. add extra points and triangles in such a way that the grid is smoother than it is at the moment. But I found that `scipy.interpolate` only works if the xy-points are regular, which is not the case here. Any suggestions?

# Answer
1. Create another array parallel to your points array to store normal vectors. Initialize it to zero vectors.
2. For each triangle in your mesh, compute a triangle normal as the cross product of two of its edges. Don't normalize it — its length is proportional to the triangle area, which helps with uniformity in places where you have uneven triangle density.
3. Add this triangle normal to the normal array entries for each of the participating vertices.
4. Once you've summed up all of the normals, normalize every normal in the array (averaging the effects where multiple triangles share a vertex).
5. For each triangle, decompose it into additional triangles using this local curvature data as a guide. There are lots of different methods you could use here, for instance...

* For each edge of the triangle, from each vertex in that edge, calculate a vector in that vertex's local tangent plane (perpendicular to the vertex normal) that points toward the opposite end of the edge.
    * With these two endpoints and tangent vectors, compute an interpolated point halfway between, using your favourite spline formula.
    * Connect the three new edge-bisecting points formed this way to split the original triangle into 4, in a triforce pattern.
> 1 votes

# Answer
Measure each triangles square or non-smoothness, and if it is not small enough - then add a new vertex in its center (Centroid) and reaplace the triangle with 3 smaller trangles using that new vertex.

Update: Typically new Z value is an average between other Z values, just like with X and Y axis. If you have an underlying height map - take values from it. Afterwards you could apply a smoothing pass - measure curvature between polys in each vertex and shift it accordingly to decrease it.
> 0 votes

---
Tags: python, 3d-meshes, mesh
---