# Question
Title: Why do I get "the object you want to instantiate is null" when I can see the prefab reference in the Inspector?
I read the solution in this post but still not able to understand it. I have a script (`AdvanceWayPoint`) attached to a game object ("Cube", with tag "Cube") in my scene, and this script instantiates a prefab ("1K ohm waypoint"), and in that prefab I have attached the script `WayPointPosition` as shown below.

AdvanceWayPoint:

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

public class AdvanceWayPoint : MonoBehaviour
{
    public Transform player;
    public bool CreateResistor;
    int RandNum;
    public GameObject myprefab;
    public GameObject FloatingText;
    public GameObject[] Resistor;
    public GameObject[] way1;
    Vector3[] ExactResistorSpawnPoint;
    public int[] ResistorBand;
    public float[] ResistorValue;
    public float ChoosenResistorValue;
    public int Ammo;

    void Start()
    {
        ResistorBand = new int[36];
        ResistorValue = new float[9];
        Random.InitState(System.DateTime.Now.Millisecond);
        CreateResistor = true;
        player = new GameObject().transform;
        ExactResistorSpawnPoint = new Vector3[9];
    }

    void Update()
    {

        if (CreateResistor == true)
        {
            RandNum = 1;
            CreateResistor = false;
            Waypoint();
        }
    }

    public void Waypoint()
    {
        Vector3 SpawnPosition = player.transform.position;
        Vector3 ExactSpawnPoint = new Vector3(SpawnPosition.x + Random.Range(1, 4), 0, SpawnPosition.z + Random.Range(1, 4));

        if (RandNum == 1)
        {
            int i = 0;
            int y = 0;
            while (i < 35)
            {
                ExactResistorSpawnPoint[y] = new Vector3(ExactSpawnPoint.x + Random.Range(1, 10), ExactSpawnPoint.y + 7, ExactSpawnPoint.z + Random.Range(1, 10));
                ResistorBand[i] = Random.Range(1, 10);
                ResistorBand[i+1] = Random.Range(1, 10);
                while(ResistorBand[i+1]==ResistorBand[i])
                {
                    ResistorBand[i + 1] = Random.Range(1, 10);
                }
                ResistorBand[i+2] = Random.Range(1, 5);
                while(ResistorBand[i + 2]==ResistorBand[i+1]||ResistorBand[i+2]==ResistorBand[i])
                {
                    ResistorBand[i + 2] = Random.Range(1,5);
                }
                ResistorBand[i + 3] = Random.Range(1, 3);
                ResistorValue[y] = ((ResistorBand[i] * 10 + ResistorBand[i+1]) * Mathf.Pow(10, ResistorBand[i+2]) / 1000);
                i = i + 4;
                y = y + 1;
            }
            way1 = GameObject.FindGameObjectsWithTag("1K ohm");
            if (way1.Length == 0)
            {
                for (y = 0; y < 9; y++)
                {
                    Instantiate(Resistor[y], ExactResistorSpawnPoint[y], Quaternion.identity);
                }
            }
            int RandomChooseWayPointValue = Random.Range(0, 9);
            ChoosenResistorValue = ResistorValue[RandomChooseWayPointValue];
            Instantiate(myprefab, ExactSpawnPoint, Quaternion.identity);
            var go = Instantiate(FloatingText, ExactSpawnPoint, Quaternion.identity);
            go.GetComponent<TextMesh>().text = ResistorValue[RandomChooseWayPointValue].ToString() + " K ohm +/-" + ResistorBand[((RandomChooseWayPointValue+1)*4)-1].ToString() + "%";
        }
    }
}

```

WayPointPosition:

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

public class WayPointPosition : MonoBehaviour
{
    public GameObject FloatingText;

    public float ResistorValue;
    float t;
    private AdvanceWayPoint Ammo;

    void Awake()
    {
        GameObject ReadValue = GameObject.FindGameObjectWithTag("Cube");
        AdvanceWayPoint read = ReadValue.AddComponent<AdvanceWayPoint>();
        ResistorValue = read.ChoosenResistorValue;
        Debug.Log(ResistorValue);
        transform.rotation = Quaternion.Euler(-90, 0, 0);

    }

    // Update is called once per frame
    void Update()
    {
        t=t+ 5*Time.deltaTime;
        transform.position =new Vector3(transform.position.x, 2+Mathf.Abs(Mathf.Cos(t)), transform.position.z);

    }
    void OnTriggerEnter(Collider other)
    {
        float ThisResistorValue = other.gameObject.GetComponent<ReadResistorValue>().value;
        if (ThisResistorValue == ResistorValue)
        {
            Destroy(other.gameObject);
            AdvanceWayPoint ammo = FindObjectOfType<AdvanceWayPoint>();
            ammo.Ammo++;

            GameObject[] Resistor = GameObject.FindGameObjectsWithTag("Resistor");
            foreach(GameObject resistor in Resistor)
            {
                Destroy(resistor);
            }
            ammo.CreateResistor = true;
            Destroy(gameObject);

        }

    }
}

```

At runtime, the error points to the line:

```
Instantiate(myprefab, ExactSpawnPoint, Quaternion.identity);

```

and deleting these lines

```
GameObject ReadValue = GameObject.FindGameObjectWithTag("Cube");
AdvanceWayPoint read = ReadValue.AddComponent<AdvanceWayPoint>();
ResistorValue = read.ChoosenResistorValue;

```

will no longer show the error.

On instantiate, I need the prefab to retrieve value from the Cube game object in the scene, but I'm not sure why it is not working.

# Answer
This line:

```
AdvanceWayPoint read = ReadValue.AddComponent<AdvanceWayPoint>();

```

adds a new `AdvanceWayPoint` component to the `ReadValue` cube. This new component is brand new, fresh from the factory. It has NO Inspector configuration settings applied to it, because it didn't exist when you were configuring this object in the Inspector. So its `myprefab` variable is `null`.

When this new component's `Waypoint()` method is called, it will try to instantiate this `null` prefab and throw the error.

It looks to me like you don't want to create a new `AdvanceWayPoint` component at all. You probably want to read data from the *existing* `AdvanceWayPoint` component that the cube already has attached to it. To do that, you'd write this instead:

```
AdvanceWayPoint read = ReadValue.GetComponent<AdvanceWayPoint>();

```

Notice "Get" instead of "Add" - we're fetching a reference to an existing component, not adding a new one.
> 2 votes

---
Tags: unity, prefabs
---


title: Create own texture paint tool in Unity

text:
# Question
Title: Create own texture paint tool in Unity
I want create texture paint tool based not on vertex paint, but on splatmap UV. I already write simple shader:

```
o.Albedo = lerp(tex2D (_MainTex, IN.uv_MainTex), tex2D (_SecondTex, IN.uv_MainTex), tex2D (_MaskTex, IN.uv2_MaskTex).a).rgb;

```

All is simple: there is a background texture `_MainTex` for example for ground and "overlaying" texture `_SecondTex` for example for road. Both are tiled trough first UV-map `uv_MainTex`. Where second texture should appeared is determined by `_MaskTex` opacity, and this texture is not tiled but fit the surface of the mesh via `uv2_MaskTex`.

Sure, I can draw on mask texture in external image editor, save it every time, switch back to Unity and it will be updated, but it would be more fast and accurate to draw directly on mesh.

**How do I see solution**

1. Add a script to the object I need. Script should have a mouse click listener.
2. In listener I need somehow get click coordinates and convert them to second UV-map space coordinates.
3. Then, no, actually, somewhere *before* script should create a copy of mask texture, store it exactly in operative memory (not as asset in file system), and assign as parameter to the object material. And then, on step 3 draw on that image copy by given coordinates from step 2.
4. Changes should be displayed on mesh surface instantly.
5. After finishing work with tool, script should rewrite mask texture from assets with mask texture from operative memory, and reassigned it.

I have small experience on programming Unity editor, so, any help will be appreciated.

---

**Update**

Currently I am facing problem with getting click coordinates in edit mode.

I created empty script `TexturePaint` and attached it to the object I want to paint. I also created `TexturePaintEditor` script that just placed in assets folder and derrived from `Editor` instead of `MonoBehaviour`.

The code:

```
using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(TexturePaint))]
public class TexturePaintEditor : Editor {

private bool fl = false;

    void OnSceneGUI()
    {
        Event e = Event.current;

        int controlID = GUIUtility.GetControlID(FocusType.Passive);

        switch (Event.current.GetTypeForControl(controlID))
        {
            case EventType.MouseDown:
                Debug.Log("Mouse Down!");
                Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                RaycastHit hit;

                    if ( Physics.Raycast( ray, out hit, Mathf.Infinity))
                        {
                            Vector3 myPos = hit.point;
                            Debug.Log(myPos);
                            PlaceObject(myPos);
                        }

                Event.current.Use();
                break;
            case EventType.MouseUp:
                Event.current.Use();
                break;
        case EventType.KeyDown:
                break;
        }
    }

    void PlaceObject(Vector3 myPos)
    {
    }

}

```

"Mouse down!" appears always when I click, but coordinates messages not: when I click some solid regular objects appears in log, but when click another, the some regular objects - not.

**Update2** Seems raycast hits only objects with collider

**Update3** No way... I did it! For those who perhaps following this post, wait a while, I will write a complete answer.

# Answer
> 2 votes
1. In Unity create script `TexturePaint.cs` with default generated code. You don't need to change it.
2. Create `TexturePaintEditor.cs` script (do not assigned to anything, just create) and paste code below

`TexturePaintEditor.cs`

```
using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(TexturePaint))]
public class TexturePaintEditor : Editor {

private bool fl = false;
private bool fe = false;

private Texture2D tt;

    void OnSceneGUI()
    {
        Event e = Event.current;

        int controlID = GUIUtility.GetControlID(FocusType.Passive);
        switch (Event.current.GetTypeForControl(controlID))
        {
                case EventType.MouseMove:
                    if(fl || fe)
                    {
                    Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    RaycastHit hit;

                    if ( Physics.Raycast( ray, out hit, Mathf.Infinity))
                        {
                            Renderer rend = hit.transform.GetComponent<Renderer>();
                            MeshCollider meshCollider = hit.collider as MeshCollider;

                            if (rend == null || rend.sharedMaterial == null || rend.sharedMaterial.mainTexture == null || meshCollider == null)
                                return;

                            Texture2D tex = rend.material.GetTexture("_M2") as Texture2D;
                            Vector2 pixelUV = hit.textureCoord2;
                            pixelUV.x *= tex.width;
                            pixelUV.y *= tex.height;

                            if(fl)
                                tex.SetPixel((int)pixelUV.x, (int)pixelUV.y, Color.black); // draw
                            else if(fe)
                                tex.SetPixel((int)pixelUV.x, (int)pixelUV.y, Color.clear); // erase

                            tex.Apply();
                            tt = tex;
                        }
                    }
                break;
        case EventType.KeyDown:
        if(e.character == 'u') // switch to draw
        {
        fe = false;
        fl = !fl;
        Debug.Log(fl);
        if(!fl)
            SaveTexture(tt);
        }
        else if(e.character == 'y') // switch to erase
        {
        fl = false;
        fe = !fe;
        Debug.Log(fe);
        if(!fe)
            SaveTexture(tt);
        }
                break;
        }
    }

    protected void SaveTexture(Texture2D texture)
    {
     var path = AssetDatabase.GetAssetPath(texture);
     System.IO.File.WriteAllBytes(path, texture.EncodeToPNG());
     Debug.Log(path);
    }
}

```
3. For the object with prepared uv's in external software, like Blender, add as component script `TexturePaint.cs`.
4. Create new material and new shader for that material with the next code:

`Terrain.shader`

```
Shader "Custom/Terrain"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _M1 ("Albedo (RGB)", 2D) = "white" {}
        _M2 ("mask", 2D) = "white" {}
        _m1sc ("ms", Range(0,1)) = 0.5 // for scaling second texture
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _M1;
        sampler2D _M2;

        struct Input
        {
            float2 uv_MainTex : TEXCOORD0;
            float2 uv2_M2;
        };

        half _Glossiness;
        half _Metallic;
        half _m1sc;
        fixed4 _Color;

        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = lerp(tex2D (_MainTex, IN.uv_MainTex), tex2D (_M1, IN.uv_MainTex * _m1sc), tex2D (_M2, IN.uv2_M2).a);
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

```
5. In material set textures you need. First is background, second is next layer, third used as mask.
6. Go to third texture properties, `Advanced` \- check `Read/Write`.
7. Now select object, press `u` on keyboard and it will automatically draw second texture where the cursor is. To disable this mode press `u` again. `y` for erase, same logic.

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


# Question
Title: Updating chunk borders when generating new chunks
I am making an infinite voxel terrain that generates around the player. The blue boxes are the chunks that are currently loaded and the white ones are unloaded.

When building the mesh for a chunk I check if the blocks in the edges of surrounding chunks are air blocks and add a face if they are. The issue comes when the is no chunk loaded adjacent to a chunks mesh and so I don't add a face these since the player isn't going to see it (as is the case for the 8 chunks on the outside).

And so when the player moves and new chunks are generated there will be a seam because the remember the previous chunks had no way to tell if there was a block there in the first place.

One way I tried to fix this is to rebuild the meshes of chunks adjacent to the newly generated chunks which works but I feel like there is a simpler solution to this problem.

Any pointers will be super helpful. Thanks.

# Answer
> 1 votes
For every chunk mesh you have to render you need to create the chunk data of its neighbors.

And no, this does not create an endless loop since chunks have two stages of initialisation: first is generate data (for example from simplex noise of whatever algorithm) and the second stage is to create a mesh from the data. For the neighbors you only need the data. mesh is only needed when actually rendering the chunk.

I used this in my minecraft-like game and it worked well.

---
Tags: unity, procedural-generation, voxels
---


# Question
Title: How do I fill a scene with light by using real-time lights in Unity?
This is my scene:

Components of this scene:

1. Cube
2. Spotlight

This project is under URP and I am building it for android. In this scene, I want more indirect lighting so that the objects/materials nearby are at least partly visible and to get rid of the strong circular boundary of the spot light on the floor.

As a comment suggests, using Indirect Lighting might be complex, especially for mobile, so what can I do? I tried increasing the spot angle but it did not look right.

Any alternatives would also be appreciated.

# Answer
> 1 votes
You can adjust the ambient lighting of the scene from the Lighting Window in the Unity Editor. Ambient lighting is present throughout the scene and doesn't come from a specific light source; it's an inexpensive way to roughly simulate indirect lighting and ensure that all parts of a scene have a certain minimum level of brightness.

The exact steps to change the settings will vary depending on your Unity version, but here's how you do it in Unity 2020.3.x:

1. Open the Lighting window at Window \> Rendering \> Lighting
2. Select the "Environment" tab
3. Under the "Environment Lighting" section, choose your lighting source (Skybox, Gradient, or Color). "Color" is the easiest to work with but least realistic of the three options. Then adjust the settings for your selected lighting source.

---
Tags: unity, 3d, lighting, unity-urp
---


# Question
Title: Is there a simple way to check for available space on an iOS device within a Unity app?
I was trying to use `System.IO.DriveInfo.GetDrives()[0]` to retrieve available disk space but that only works on a computer. I was wondering if there was any simple way to output this information within a Unity app when running on an iOS device.

# Answer
> 2 votes
If the "simple way" you are referring to is a built-in Unity function, **no**, there isn't.

Unity provides an abstraction layer that lets you program once for many platforms. Every core library function has a platform-specific version for each supported platform.

On the other hand, some features may have limited or no support. Features not intended for game development or which developers would rarely use are usually neglected by design.

Most times, if you need such functionalities, you're likely to know what you're doing and have a good programming experience. Hence, you can implement such functionalities yourself.

### Project setup

To begin with, create a dummy function that returns mock values for the current available space, e.g.:

```
public static float getAvailableSpace() {
    return 0.6f;
}

```

This way, you can keep developing your project and test various scenarios for different amounts of free space. Change the function arguments according to your needs.

You are going to change the actual implementation another time, but you need to export your project first.

### Project export

Platform-specific functionalities can be added to a Unity game by exporting the project and extending it in an external editor, such as Android Studio or XCode.

I address this process and provide a brief overview of Android's and iOS's app architecture in this previous Q&A here on GameDev.SE.

### Feature implementation

Once you open the project in XCode, you can browse the class of interest to find the dummy function you previously implemented, and extend its functionalities to query the available space on the device. This previous Q&A from StackOverflow addresses querying available space for iOS in Swift.

---
Tags: unity, operating-system
---


# Question
Title: ZBias trouble with alternative cubemap shadow method
I find two methods to produce cubemap for shadow both using the same geometry shader to draw each of the 6 faces. The first one writes in the depth buffer only and is used like this (really I thanks the guy having posted this code elsewhere (https://community.monogame.net/t/view-matrix-for-point-light-shadows/14548)):

```
float3 txDir =  Input.WPos.xyz - LightPos[2].xyz;
float3 LtoP = normalize(txDir);
float Closet = -1;
int FIndex = 0;
for (int f = 0; f < 6; f++)
{
   float r = dot(LtoP, FDir[f]);
   if ( r > Closet )
   {
      Closet = r;
      FIndex = f;
   }
}
float4 LPos = mul(Input.WPos, LightViewProjCube[FIndex]);
LPos.z/=LPos.w;
D = txShadowCubeMap.Sample(samWrap, txDir).r;
Shadow = (D + 0.001f < LPos.z)?0:1;

```

as one can see you need some job to retrieve the correct face index and its light matrix to recalculate the position but this code works well.

the alternative solution from learngl tutorial use the same geometry shader but writes his own depth value in the depth buffer (I use a render target R16F in DX11 for this) in a 0..1 range via 1/farplane

```
float PS_CubeMap(PS_CUBEMAP_IN Input): SV_TARGET
{
   return length(Input.Pos.xyz - LightPos[2])*0.001f;//0.001 is 1/farplane
}

```

then they use it like this:

```
float3 txDir =  Input.WPos.xyz - LightPos[2].xyz; //2nd pointlight (yellow)
D = txShadowCubeMap.Sample(samClamp,  txDir ).r;
if ( D < 1 ) //rendertarget red chanel cleared to 1. So 1 means nothing was drawn.
 Shadow = (length(txDir) > D*1000)?1:0;//*1000 restores the real distance

```

My problem here is that if the second method is 5-10% faster because less pixel operations it introduces a zbias problem for object being both shadow caster and receiver I can't figure out how to solve (see picture). I've tried to "push away" the distance value when generating the map or various additional bias when using the texture, or back/front cull for rendering the shadow, various sampler. No improvements. Of note all my matrices have the same 1/1000 near/farplane values. Is there something in this learngl code adaptation I'm missing?

# Answer
Apparently using the distance from pixel to light and dividing by some arbitrary value to fit in the \[0..1\] range is not giving an accurate result. The solution I found to this is for a given pointlight to calculate the pixel to light distance and divide by the inverse of the radius of the point light (in fact 1/(r\*r) is better). This ensure the value obtained is in the \[0..1\] relative to the current light range when writing to the cubemap.

Of note: I use CPU precalculated 1/R or 1/(r\*r) passed to the constant buffer because I suppose that multiplication is faster than division on GPU as it used to be on CPU.

```
pixel = length(Input.WPos.xyz-LightPos[n].xyz)*LightPos[n].w;//w used to store 1/(r*r)

```

When using the texture the current pixel to curent pointlight distance is thus also multiplied by the reverse r\*r of the current pointlight and tested against the cubemap.r channel + some bias.

```
float3 txDir = Input.WPos.xyz - LightPos[n].xyz;
float L= txCubeMap.Sample(sampler, txDir);
if ( L < 1 ) //cubemap filled at start with value 1: value 1 means nothing drawn, calculating shadow is useless.
  Shadow = (L + bias < length(txDir)*LightPos[n].w)?0:1; //remember w used to store 1/(r*r)

```

the bias value (0.002 here ) is tuned so that all my 4 point lights produce correct shadows without self shadowing of shadow casters.
> 0 votes

---
Tags: directx11, shadow-mapping
---


title: Menu not disappearing after input

text:
# Question
Title: Menu not disappearing after input
I am having some issues with the UI and the Input system. What I am trying to do is "simply" to make a menu appear and disappear upon pressing a certain key. To do so, I created an animator attached to the Menu canvas, to which I attached the following script:

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

public class Menu : MonoBehaviour
{
    [SerializeField] Animator anim;

    [Header("Input System")]
    [SerializeField] public GameController controls;
    //[SerializeField] public Vector2 direction;

    private void Awake()
    {
        anim = GetComponent<Animator>();

        controls = new GameController();
    }

    private void OnEnable()
    {
        controls.Enable();

        if (anim.GetBool("isPaused") == false)
        {
            controls.Player.ShowMenu_Start.performed += ctx =>
            {
                anim.SetBool("isPaused", true);
                Debug.Log("Paused");
                //controls.Player.Disable();
                //controls.Menu.Enable();
            };
        }

        if (anim.GetBool("isPaused") == true)
        {
            controls.Menu.HideMenu_Start.performed += ctx =>
            {
                anim.SetBool("isPaused", false);
                Debug.Log("Resumed");
                //controls.Menu.Disable();
                //controls.Player.Enable();
            };
        }
    }
    private void OnDisable()
    {
        controls.Disable();
    }

}

```

The idea is that when I press the pause key (mapped in the ActionMap of the player i.e. in-game), the menu will be activated, the animation triggered in order to pass to the state transition 'menu activated', the in game ActionMap is disabled and the menu ActionMap enabled.

Vice versa, if the menu is already active, `(anim.GetBool("isPaused") == true)`, I will go the other way around.

So far, the activation of the menu works: I get the "Paused" message in the console, but I can't get to unpause the menu. The bool remains true and additionally upon pressing again, the "Paused" message does not appear.

I tried to comment out the enabling and disabling of the ActionMaps, and this works partially since now the "Paused" message appears every time the key is pressed, but I still cannot set the bool to false. I have also tried to use a single ActionMap but it doesn't work either.

How can I correct this?

**EDIT:**

Following on the answer by @Kevin, I managed to activate/deactivate the menu. What i intended to do initially, however, was to do so by pressing the same key, like pressing the start button to show up the screen and again, which is why I thought of creating 2 different ActionMaps, so that one would have the action pause and the other the action unpause using the same key. As it is now, the scripts calls the 2 actions at once. I tried again to disable and enable the but without results. I guess that if i disable/enable the gamecontroller, i do it for all of its action maps, is that right? Is there a workaround?

# Answer
> 1 votes
Your code is written so that only one event listener will be added. If you're not paused when the menu is enabled, the ShowMenu\_Start listener is added. If paused, the HideMenu\_Start listener is added when the menu is enabled.

It looks to me like you should just remove the `if` conditions:

```
private void OnEnable() {
    controls.Enable();

    controls.Player.ShowMenu_Start.performed += ctx =>
    {
        anim.SetBool("isPaused", true);
        Debug.Log("Paused");
        //controls.Player.Disable();
        //controls.Menu.Enable();
    };

    controls.Menu.HideMenu_Start.performed += ctx =>
    {
        anim.SetBool("isPaused", false);
        Debug.Log("Resumed");
        //controls.Menu.Disable();
        //controls.Player.Enable();
    };
}

```

Make sure you remove these event listeners in `OnDisable()`.

---
Tags: unity, input, unity-ui, menu
---


# Question
Title: Why is this shader using multiple render targets not working?
I have a webgl shader that uses multiple render targets. This one only renders to one texture for now. However, I plan that this shader shall render more. However, as soon as I add layout qualifiers, and #version 300 es, my shader stops working, because I get a message saying it is an invalid program.

```
  #version 300 es

  uniform mat4 viewProjectionMatrix;

  attribute vec3 vertex;
  attribute vec2 uv;

  varying vec2 vUv;

  void main() {
    gl_Position = viewProjectionMatrix * vec4(vertex, 1);
    vUv = uv;
  }

```

Fragment shader

```
  #version 300 es

  precision mediump float;

  layout(location = 0) out vec4 color;

  uniform sampler2D textureId;

  varying vec2 vUv;

  void main() {
    color = texture2D(textureId, vUv);
  }

```

# Answer
It seems that you have a WebGL version 1 (OpenGL ES 2.0) and that's why it does not accept OpenGL ES 3.x features.

Review the code where you request the context for WebGL

```
var gl = canvas.getContext("webgl2");   // 2!

```

If you are requesting WebGL2, check that there are no whitespaces before `#version 300 es`.

You can find additional guidance here.
> 2 votes

---
Tags: glsl, webgl
---


# Question
Title: Is there a way to not keep creating new events to spawn in my new object each time?
I have an event manager to help to communicate between two scripts. One is for the script of the object itself to pass on the message to the other one which is the spawn manager(you see below). What I'm doing is working but as I create more "bosses", I will have to create more event action which I fear would be messy in the future. Is there any tips to counter this? Like for example, I just want to use one event action and that event action will help to tell my spawn script to "hey, this event is called again. time for this NEW boss to go second phase" or "this boss died, time to enter new boss" whenever this ONE event is called. Sorry for my misunderstanding of my English. Btw below is the script which I will name it accordingly to lessen the confusion.

--Spawn Script--

```
 public class SpawnManager : MonoBehaviour
{
    [Header("First Enemy")]
    [SerializeField] GameObject _FirstFall;
    [SerializeField] GameObject _FirstFelll_secondPhase;

    [Header("Second Enemy")]
    [SerializeField] GameObject _SecondFallRight;
    [SerializeField] GameObject _SecondFallLeft;
    [SerializeField] GameObject _SecondFallLeft_Phrase;
    float SpawnBetween_SecondLeft = 1.5f;
    float _nextSpawnTime_SecondLeft;

    [Header("Spawning Shards")]
    [SerializeField] GameObject _shards;
    float SpawnBetween_shard = 1.5f;
    float _nextSpawnTime_shard;

    [Header("System")]
    Vector2 cameraScreenWrap;

    public ObjectSettings[] _spawnSettings;
    bool enteringNewBoss;
    bool SecondPhase;
    bool SecondPhaseTwo;

    void Awake()
    {
        _spawnSettings[0].NextSpawnTime = 0f;
        _spawnSettings[1].NextSpawnTime = 0f;
        _spawnSettings[2].NextSpawnTime = 0f;
        _spawnSettings[3].NextSpawnTime = 0f;
        _spawnSettings[4].NextSpawnTime = 0f;
        _spawnSettings[5].NextSpawnTime = 0f;
    }
    void Start()
    {
        cameraScreenWrap = new Vector2 (Camera.main.aspect * Camera.main.orthographicSize, Camera.main.orthographicSize);

        EventManager.FirstGone += FirstEnd;
        EventManager.GoingToPhase += TriggeringPhase;
        EventManager.GoingToPhaseTwo += TriggeringPhaseTwo;

        _FirstFall.SetActive(true);
        _FirstFelll_secondPhase.SetActive(true);

        _SecondFallLeft.SetActive(true);
        _SecondFallRight.SetActive(true);
    }

    void Update()
    {
        ShardWave();

        FirstWave();
        FirstWave_Second();

        SecondWaveLeft();
        SecondWaveRight();
        SecondWaveLeft_SecondPhase();

    }
    void FirstEnd()
    {
        enteringNewBoss = true;
    }

    void TriggeringPhase()
    {
        SecondPhase = true;
    }

    void TriggeringPhaseTwo()
    {
        SecondPhaseTwo = true;
    }
    private void OnDisable()
    {
        EventManager.GoingToPhase -= TriggeringPhase;
        EventManager.GoingToPhaseTwo -= TriggeringPhaseTwo;
        EventManager.FirstGone -= FirstEnd;
    }

    void FirstWave()
    {
        if (Time.time > _spawnSettings[0].NextSpawnTime)
        {
            _spawnSettings[0].NextSpawnTime = Time.time + _spawnSettings[0].SpawnBetween;
            Vector2 SpawnPos = new Vector2(Random.Range(-1.75f, 1.67f), cameraScreenWrap.y);
            Instantiate(_FirstFall, SpawnPos, Quaternion.identity);

        }

    }

    void FirstWave_Second()
    {
        if (SecondPhase == true)
        {
            _FirstFall.SetActive(false);
            if (Time.time > _spawnSettings[1].NextSpawnTime)
            {
                _spawnSettings[1].NextSpawnTime = Time.time + _spawnSettings[1].SpawnBetween;
                Vector2 SpawnPosFirst = new Vector2(Random.Range(-1.80f, 1.70f), cameraScreenWrap.y);
                Instantiate(_FirstFelll_secondPhase, SpawnPosFirst, Quaternion.identity);
            }
        }

    }

    //----------------------------------------FIRST ENEMY END-----------------------------------------------------------

    void SecondWaveLeft()
    {
        if (enteringNewBoss == true)
        {
            Debug.Log("second spawn");
            _FirstFelll_secondPhase.SetActive(false);
            if (Time.time > _spawnSettings[2].NextSpawnTime)
            {
                _spawnSettings[2].NextSpawnTime = Time.time + _spawnSettings[2].SpawnBetween;
                Vector2 SpawnPosLeft = new Vector2(cameraScreenWrap.x, Random.Range(4.58f, 2.14f));
                Instantiate(_SecondFallRight, SpawnPosLeft, Quaternion.identity);
            }
            SecondPhase = false;
        }
    }

    void SecondWaveRight()
    {
        if (enteringNewBoss == true)
        {
            if (Time.time > _spawnSettings[3].NextSpawnTime)
            {
                _spawnSettings[3].NextSpawnTime = Time.time + _spawnSettings[3].SpawnBetween;
                Vector2 SpawnPosRight = new Vector2(-cameraScreenWrap.x, Random.Range(4.58f, 2.14f));
                Instantiate(_SecondFallLeft, SpawnPosRight, Quaternion.identity);

            }
        }
    }

    void SecondWaveLeft_SecondPhase()
    {
        if (enteringNewBoss == true)
        {
            if (SecondPhaseTwo == true)
            {
                if (Time.time > _nextSpawnTime_SecondLeft)
                {
                    _nextSpawnTime_SecondLeft = Time.time + SpawnBetween_SecondLeft;
                    Vector2 SpawnPosLeftphrase = new Vector2(cameraScreenWrap.x, Random.Range(4.58f, 2.14f));
                    Instantiate(_SecondFallLeft_Phrase, SpawnPosLeftphrase, Quaternion.identity);
                }
            }
        }

    }

    //----------------------------------------------SECOND ENEMY END---------------------------------------------------------------------------------------

```

-----Event Manager Script-----

```
public class EventManager : MonoBehaviour
{
    public static event Action GoingToPhase;
    public static event Action GoingToPhaseTwo;

    public static event Action FirstGone;
    public static event Action SecondGone;

    public static void SecondPhaseTriggered()
    {
        GoingToPhase?.Invoke();
    }

    public static void SecondPhaseTriggeredTwo()
    {
        GoingToPhaseTwo?.Invoke();
    }

   public static void PassOn()
    {
        FirstGone?.Invoke();
    }

    public static void PassOnSecond()
    {
        SecondGone?.Invoke();
    }
}

```

----- Boss Script (which tells my spawn manager in a way that this boss has spawn or to go to second phase)----

```
 public class Firstboss : MonoBehaviour
{

    [SerializeField] int healthPoints = 1;
    Rigidbody2D rb;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "circle")
        {
            healthPoints--;
            if(healthPoints <= 2)
            {
                EventManager.SecondPhaseTriggered();
            }

            if(healthPoints <= 0)
            {
                EventManager.PassOn();
                Destroy(gameObject);
            }
        }
    }
}

```

---Second boss---- (similar like above but different event input)-----

```
 public class SecondBoss : MonoBehaviour
{
    [SerializeField] int healthPoints = 3;
    Rigidbody2D rb;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    private void OnTriggerEnter2D(Collider2D collisions)
    {
        if (collisions.gameObject.tag == "circle")
        {
            healthPoints--;
            if (healthPoints <= 2)
            {
                EventManager.SecondPhaseTriggeredTwo();
            }

            if (healthPoints <= 0)
            {
                Destroy(gameObject);
            }
        }
    }
}

```

# Answer
The SpawnManager you have here is not very scalable. The more content you add to your game, the longer and messier it is going to get.

A better solution could be to create a separate SpawnManager for each phase. Put them all in your scene, each on a separate game object. Deactivate them all but the first one. When one SpawnManager detects that its phase it over, have it deactivates itself and activate the next one in line.

The best part of this pattern is that you can easily test your game from any point in the phase sequence. Just pick a different SpawnManager to be active in the scene and press the Play button.

You *could* make each of them a separate script, but I would see if I can unify as much as possible so that many phases can be handled by the same script with different values in its variables. And when I still end up with a lot of scripts which share a lot of code, I would probably try to either break it up into multiple components or move the reduntant functionality to an abstract base-class and have all the other SpawnManagers inherit from it.
> 0 votes

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


# Question
Title: Unity stops receiving input from gamepad when game is started
**Update:** I originally thought that it was more or less random whether the controller input works or not. I have now found out that it stops working once the game has been started for the first time. Also, the problem is not specific to the Switch Pro Controller.

I can ~~sometimes~~ receive input from my Nintendo Switch Pro Controller after starting unity, but it stops working ~~quickly and most of the time it won't even work at all~~ the moment I start my game for the first time. I use Unity 2021.2 on a Windows 11 machine (but I had the same issue before updating from Windows 10 to 11). I use the new input system in my project, but then I tried with another project based on the same Unity version that does not use the new input system and the exact same issue occured. I tried a SNES style USB gamepad and I get the same results as with the Pro Controller.

What I mean be "receive input" is that I can go to the Input debugger window and see events from the controller. In addition to that, I am able to assign a button to an action in an Input Action Asset using the "Listen" functionality before the game is started.

Outside of Unity the controller works perfectly (e.g. in the Windows menu). I have reinstalled my bluetooth drivers today, which did solve connectivity problems that I was having, too, but the problem described here remained.

Here are screenshots of the windows where I would expect to see my inputs:

When I click on "Record Frames" I start seeing events in the bottom pane, but they appear to be from a different device (Device ID is 0, not 4).

And this is the "Listen" button I was talking about:

I scratched out the keyboard keys, because those were triggered by me making a screenshot. When pressing a button on the gamepad nothing shows up.

I haven't used the new input system before, neither have I ever successfully used a controller with Unity - so, don't assume I have tried the "obvious", since it might not be obvious to me :-) Thanks for taking the time to read!

# Answer
This is a common issue with the new Input System. Several users have already reported this problem, which apparently has not been resolved. Although reading the documentation, it seems that many of these problems have more to do with the drivers themselves rather than the Input System.

Note that the documentation about Switch controller states the following:

> This support does not currently work for Switch Pro controllers connected via wired USB. Instead, the Switch Pro controller *must* be connected via Bluetooth. This is due to the controller using a proprietary communication protocol on top of HID which does not allow treating the controller like any other HID.

New Input System Gamepad Documentation

Some users say that the problem can be fixed by restarting the computer, but this is not certain. It may or may not work for you, I guess it's worth a try.

Since you mentioned that your Bluetooth driver is buggy, we can't rule out that this could also be the problem, but that would already be out of the question...kind of.
> 1 votes

---
Tags: unity, controllers
---


# Question
Title: How can I avoid tight script coupling in Unity?
Some time ago I started working with Unity and I still struggle with the issue of tightly coupled scripts. How can I structure my code to avoid this problem?

**For example:**

I want to have health and death systems in separate scripts. I also want to have different interchangeable walking scripts that allow me to change the way the player character is moved (physics-based, inertial controls like in Mario versus tight, twitchy controls like in Super Meat Boy). The Health script needs to hold a reference to the Death script, so that it can trigger the Die() method when the players health reaches 0. The Death script should hold some reference to the walking script used, to disable walking on death (I'm tired of zombies).

I would *normally* create interfaces, like `IWalking`, `IHealth` and `IDeath`, so that I can change these elements at a whim without breaking the rest of my code. I would have them set up by a separate script on the player object, say `PlayerScriptDependancyInjector`. Maybe that script would have public `IWalking`, `IHealth` and `IDeath` attributes, so that the dependencies can be set by the level designer from the inspector by dragging and dropping appropriate scripts.

That would allow me to simply add behaviors to game objects easily and not worry about hard-coded dependencies.

**The problem in Unity**

The *problem* is that in Unity I can't expose interfaces in the inspector, and if I write my own inspectors, the references wont get serialized, and it's a lot of unnecessary work. That's why I'm left with writing tightly-coupled code. My `Death` script exposes a reference to an `InertiveWalking` script. But if I decide I want the player character to control tightly, I cant just drag and drop the `TightWalking` script, I need to change the `Death` script. That sucks. I can deal with it, but my soul cries every time I do something like this.

Whats the preferred alternative to interfaces in Unity? How do I fix this problem? I found this, but it tells me what I already know, and it does not tell me how to do that in Unity! This too discusses what should be done, not how, it does not address the issue of tight coupling between scripts.

All in all I feel those are written for people who came to Unity with a game design background who just learn how to code, and there is very little resources on Unity for regular developers. Is there any standard way to structure your code in Unity, or do I have to figure out my own method?

# Answer
There are a few ways you can work to avoid tight script coupling. Internal to Unity is a SendMessage function that when targetted at a Monobehaviour's GameObject sends that message to everything on the game object. So you might have something like this in your health object:

```
[SerializeField]
private int _currentHealth;
public int currentHealth
{
    get { return _currentHealth;}
    protected set
    {
        _currentHealth = value;
        gameObject.SendMessage("HealthChanged", value, SendMessageOptions.DontRequireReceiver);
    }
}

[SerializeField]
private int _maxHealth;
public int maxHealth
{
    get { return _maxHealth;}
    protected set
    {
        _maxHealth = value;
        if (currentHealth > _maxHealth)
        {
            currentHealth = _maxHealth;
        }
    }
}

public void ChangeHealth(int deltaChange)
{
    currentHealth += deltaChange;
}

```

This is really simplified but should show precisely what I'm getting at. The property throwing the message like you would an event. Your death script would then intercept this message (and if nothing is there to intercept it, SendMessageOptions.DontRequireReceiver will guarantee you don't receive an exception) and perform actions based on the new health value after it's been set. Like so:

```
void HealthChanged(int newHealth)
{
    if (newHealth <= 0)
    {
        Die();
    }
}

void Die ()
{
    Debug.Log ("I am undone!");
    DestroyObject (gameObject);
}

```

There is no guarantee of order in this, however. In my experience it always goes from top most script on a GameObject to bottom most script, but I wouldn't bank on anything you can't observe for yourself.

There is other solutions you could investigate which is building a custom GameObject function that gets Components and only returns those components that have a specific interface instead of Type, it would take a bit longer but could serve your purposes well.

Additionally, you can write a custom editor that checks an object being assigned to a position in the editor for that Interface before actually committing the assignment (in this case you would be assigning the script as normal allowing it to be serialized, but throwing an error if it didn't use the correct interface and denying the assignment). I've done both of these before and can produce that code but will need some time to find it first.
> 14 votes

# Answer
I personally NEVER use SendMessage. There's still a dependency between your components with SendMessage, it's just very poorly shown and easy to break. Using interfaces and/or delegates really removes the need to use SendMessage ever( which is slower, although that shouldn't be a concern until it needs to be ).

http://forum.unity3d.com/threads/free-vfw-full-set-of-drawers-savesystem-serialize-interfaces-generics-auto-props-delegates.266165/

Use this guy's stuff. It provides a heap of editor stuff like exposed interfaces, AND delegates. There are heaps of stuff out there like this, or you can even make your own. Whatever you do, DO NOT compromise your design because of Unity's lacking script support. These things should be in Unity by default.

If this isn't an option, drag and drop monobehaviour classes instead and dynamically cast them to the required interface. It's more work, and less elegant, but it gets the job done.
> 7 votes

# Answer
A Unity-specific approach that occurs to me would be to initially `GetComponents<MonoBehaviour>()` to get a list of scripts, and then cast those scripts into private variables for the specific interfaces. You'd want to do this in Start() on the dependency injector script. Something like:

```
MonoBehaviour[] list = GetComponents<MonoBehaviour>();
for (int i = 0; i < list.Length; i++) {
    if (list[i] is IHealth) {
        Debug.Log("Found it!");
    }
}

```

In fact, with this method you could even have the individual components tell the dependency injection script what their dependencies are, using the typeof() command and 'Type' type. In other words, the components give the dependency injector a list of types, and then the dependency injector returns a list of objects of those types.

---

Alternatively, you could just use abstract classes instead of interfaces. An abstract class can accomplish pretty much the same purpose as an interface, and you can reference that in the Inspector.
> 6 votes

# Answer
From my own experience, game dev traditionally involves a more pragmatic approach than industrial dev (with less abstraction layers). Partly because you want to favour performance over maintainability, and also because you're less likely to reuse your code in other contexts (there's usually an strong intrinsic coupling between the graphics and the game logic)

I totally understand your concern, especially because performance concern is less critical with recent devices, but my feeling is that you'll have to develop your own solutions if you want to apply industrial OOP best practices to Unity game development (such as dependency injection, etc...).
> 5 votes

# Answer
Have a look at IUnified (http://u3d.as/content/wounded-wolf/iunified/5H1), which lets you expose interfaces in the editor, just like you mention. There is a little bit more wiring up to do compared to normal variable declaration, that's all.

```
public interface IPinballValue{
   void Add(int value);
}

[System.Serializable]
public class IPinballValueContainer : IUnifiedContainer<IPinballValue> {}

public class MyClassThatExposesAnInterfaceProperty : MonoBehaviour {
   [SerializeField]
   IPinballValueContainer value;
}

```

In addition, as another answers mention, using SendMessage doesn't remove the coupling. Instead it makes it not error out at compile time. Very bad - as you scale up your project it can become a nightmare to maintain.

If you are further looking to decouple your code without using interface in the editor, you can use a strongly typed event-based system (or even a loosely-typed one actually, but again, harder to maintain). I have based mine on this post, which is super convenient as a starting point. Be mindful of creating a bunch of events as it could trigger the GC. I worked around the problem with an object pool instead, but that's mostly because I work with mobile.
> 2 votes

# Answer
Source: http://www.udellgames.com/posts/ultra-useful-unity-snippet-developers-use-interfaces/

```
[SerializeField]
private GameObject privateGameObjectName;

public GameObject PublicGameObjectName
{
    get { return privateGameObjectName; }
    set
    {
        //Make sure changes to privateGameObjectName ripple to privateInterfaceName too
        if (privateGameObjectName != value)
        {
            privateInterfaceName = null;
            privateGameObjectName = value;
        }
    }
}

private InterfaceType privateInterfaceName;
public InterfaceType PublicInterfaceName
{
    get
    {
        if (privateInterfaceName == null)
        {
            privateInterfaceName = PublicGameObjectName.GetComponent(typeof(InterfaceType)) as InterfaceType;
        }
        return privateInterfaceName;
    }
    set
    {
        //Make sure changes to PublicInterfaceName ripple to PublicGameObjectName too
        if (privateInterfaceName != value)
        {
            privateGameObjectName = (privateInterfaceName as Component).gameObject;
            privateInterfaceName = value;
        }

    }
}

```
> 1 votes

# Answer
I use a few different strategies to get around the limitations you mention.

One of those that I don't see mentioned is using a `MonoBehavior` that exposes access to the different implementations of a given interface. For example, I have an interface that defines how Raycasts are implemented named `IRaycastStrategy`

```
public interface IRaycastStrategy
{
    bool Cast(Ray ray, out RaycastHit raycastHit, float distance, LayerMask layerMask);
}

```

I then implement it in different classes with classes like `LinecastRaycastStrategy` and `SphereRaycastStrategy` and implement a MonoBehavior `RaycastStrategySelector` that exposes a single instance of each type. Something like `RaycastStrategySelectionBehavior`, which is implemented something like:

```
public class RaycastStrategySelectionBehavior : MonoBehavior
{

    private readonly Dictionary<RaycastStrategyType, IRaycastStrategy> _raycastStrategies
        = new Dictionary<RaycastStrategyType, IRaycastStrategy>
        {
            { RaycastStrategyType.Line, new LineRaycastStrategy() },
            { RaycastStrategyType.Sphere, new SphereRaycastStrategy() }
        };

    public RaycastStrategyType StrategyType;

    public IRaycastStrategy RaycastStrategy
    {
        get
        {
            IRaycastStrategy raycastStrategy;
            if (!_raycastStrategies.TryGetValue(StrategyType, out raycastStrategy))
            {
                throw new InvalidOperationException("There is no registered implementation for the selected strategy");
            }
            return raycastStrategy;
        }
    }
}

```

If the implementations are likely to reference Unity functions in their constructions (or just to be on the safe side, I just forgot this when typing up this example) use `Awake` to avoid issues with calling constructors or referencing Unity functions in the editor or outside the main thread

This strategy does have some drawbacks, especially when you have to manage many different implementations that are rapidly changing. Issues with the lack of compile-time checking can be helped by using a custom editor, since the enum value can be serialized without any special work (although I usually forgo this, since my implementations don't tend to be that numerous).

I use this strategy because of the flexibility it affords you by being based on MonoBehaviors without actually forcing you to implement the interfaces using MonoBehaviors. This gives you "the best of both worlds" since the Selector can be accessed using `GetComponent`, the serialization is all handled by Unity and the Selector can apply logic at run-time to automatically switch implementations based on certain factors.
> 0 votes

# Answer
Consider using events? There are lots of good assets on the asset store that utilise unity's scriptable object to act as a pub-sub system.. try searching for "observer pattern"
> 0 votes

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


# Question
Title: Unity Editor workspace buttons missing icons
In my Unity Editor, workspace buttons (top toolbar and sceneview) do not show icons

Any idea how to fix this?

OS: Windows 7, Unity Editor: 2021.2.18f1

# Answer
Looks similar to the regression error documented here.

The posted workaround is to reset the layout to default.

Alternatively, you could try a different version.

If you can easily reproduce the problem on your version, I encourage you to submit a bug report.
> 1 votes

---
Tags: unity
---


# Question
Title: How to change which monitor is fullscreening a game player at runtime?
I have a Gameplayer window running Unity2020.3.32f1.

I'm making an options window to fullscreen the game. I'm trying pull up the list of available monitors to fullscreen the game to. However, when I run the following bit of code, as found on the Unity tutorial regarding Multi-display.

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

public class ChangeActiveScreen : MonoBehaviour
{

    public int currentMonitor;

    private List<monitorItem> monitors = new List<monitorItem>();

    public Text monitorsLabel;

    // Start is called before the first frame update
    void Start()
    {
        // Obtain a list of possible monitor targets:
        //monitors = Display.displays.Select(t => new monitorItem { monitor = t.ind }).ToList();

        for (int i = 0; i < Display.displays.Length; i++)
        {
           Display.displays[i].Activate();
           monitors.Add(new monitorItem { monitor = i });
        }

        //resolutions = Screen.resolutions.Select(t => new resItem { horizontal = t.width, vertical = t.height }).ToList();

        // Which monitor is activate? Set it to that monitor?
        for (int i = 0; i < Display.displays.Length; i++)
        {
            if (Display.displays[i].active) currentMonitor = i;
        }

        UpdateMonitorLabel();
    }

    // Update is called once per frame
    void Update()
    {

    }

    public void ChangeDisplay(Camera camera)
    {
        camera.targetDisplay = monitors[currentMonitor].monitor;

    }

    public void MonitorLeft()
    {
        currentMonitor--;

        if (currentMonitor < 0) currentMonitor = Display.displays.Length - 1;

        UpdateMonitorLabel();
    }

    public void MonitorRight()
    {
        currentMonitor++;

        if (currentMonitor > Display.displays.Length - 1) currentMonitor = 0;

        UpdateMonitorLabel();
    }

    public void UpdateMonitorLabel()
    {
        monitorsLabel.text = "Display # " + (currentMonitor + 1).ToString();
    }
}

public class monitorItem
{
    public int monitor;
}

```

The 2nd monitor does "activate" but it comes up as a black fullscreen which is not my intention. I only want to move the game player window into the second monitor and fullscreen the game into the second display. NOT stretch the one window into multiple monitors.

I've looked into other functions but they seem to rely on the resolution and the toggle of fullscreen. Nothing of the sort regarding screen location and so on.

I know that you can toggle the fullscreen option off, drag and move it into the second window and fullscreen the game and it will apply there. I'm more or less looking for a way to do this programmatically. (Additionally, running this code seems to do something with the unfullscreen title bar and not given an option to drag it.)

# Answer
Looking at Unity's tutorial, one sentence caught my eyes:

> Once you activate a display, you can’t deactivate it.

And here's the part of your code the problem is:

```
for (int i = 0; i < Display.displays.Length; i++)
{
    if (Display.displays[i].active) currentMonitor = i;
}

```

And according to what unity said, `currentMonitor` will be always `1` So your camera's target will never be the second monitor.

What you can do is use a drop-down list in your game/app settings and let the player change the current monitor manually or if you know that you're going to always use the first two monitors then you can use a switch-like method every time you want to go between monitors:

```
void FlipCamera()
{
    camera.targetDisplay = (currentMonitor + 1) % 2;
}

```

or a more functional one:

```
void FlipCamera(int num)
{
    if (currentMonitor + num < 0)
        num = -currentMonitor;
    camera.targetDisplay = (currentMonitor + num) % Display.displays.Length; // num can be negative too
}

```
> 1 votes

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


title: Custom directional shadow map from sun

text:
# Question
Title: Custom directional shadow map from sun
Due to some material features, I need to create my own directional shadow map.

Everything seems to work ok, until the moment where I compare depths.

First I add a camera component to the directional light with a RenderTexture:

Then in code, I set this texture and the camera projection matrix as global variables for shaders:

```
Camera shadowCaptureCamera = GetComponent<Camera>();
Shader.SetGlobalTexture("_CustomShadowsTex", shadowCaptureCamera.targetTexture, UnityEngine.Rendering.RenderTextureSubElement.Depth);

Matrix4x4 worldToClipMatrix = shadowCaptureCamera.projectionMatrix * shadowCaptureCamera.worldToCameraMatrix;
Shader.SetGlobalMatrix("_CustomShadowsMatrix", worldToClipMatrix);

```

Then in shaders I do this:

```
v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);

    float4 worldPos = mul( unity_ObjectToWorld, float4( v.vertex.xyz, 1.0f) );
    float4 shadowPosition = mul( _CustomShadowsMatrix, worldPos );
    shadowPosition.xyz /= shadowPosition.w;
    shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
    o.shadowMapUV = shadowPosition;
    return o;
}

fixed4 frag(v2f i) : SV_Target
{

    ......

    float shadowDepth = tex2D( _CustomShadowsTex, i.shadowMapUV.xy ).r;
    float atten = shadowDepth > abs(i.shadowMapUV.z) ? 1.0f : 0.0f;
    return atten;
}

```

But everything gets a value of `1.0f`.

Any idea what's wrong? It samples the shadow map at the correct place, but something is wrong with the values. I'm also not sure why `i.shadowMapUV.z` is \<0.f. Looking at the matrix's values, it shouldn't be.

# Answer
> 2 votes
Ok, I got it. `i.shadowMapUV.z` is \< 0.f because it's mapped to -1;1 between near;far. Forward is also at -Z, so correct way to calculate `shadowPosition` is:

```
float4 shadowPosition= mul( _CustomShadowsMatrix, float4(worldPos, 1.f) );
shadowPosition.xyz /= shadowPosition.w;
shadowPosition.xy = shadowPosition.xy * 0.5f + 0.5f;
shadowPosition.z = -shadowPosition.z * 0.5f + 0.5f;

```

# Answer
> 1 votes
It's not a good method.Because there are different projection matrix with different platforms. So you should use:

```
Matrix4x4 posToUV = new Matrix4x4();
posToUV.SetRow(0, new Vector4(0.5f, 0, 0, 0.5f));
posToUV.SetRow(1, new Vector4(0, 0.5f, 0, 0.5f));
posToUV.SetRow(2, new Vector4(0, 0, 1, 0));
posToUV.SetRow(3, new Vector4(0, 0, 0, 1));
Matrix4x4 projectionMatrix = GL.GetGPUProjectionMatrix(_camera.projectionMatrix, false);
Matrix4x4 matrixVP = posToUV * projectionMatrix * _camera.worldToCameraMatrix;

```

instead of:

```
Matrix4x4 worldToClipMatrix = shadowCaptureCamera.projectionMatrix * shadowCaptureCamera.worldToCameraMatrix;

```

it will apply vp matrix and correct the uv from \[-1,1\] to \[0,1\].
and you should handle the map manually in receive shadow shader's fragment:

```
float depth = i.shadowCoord.z / i.shadowCoord.w;
#if defined (SHADER_TARGET_GLSL)
    depth = depth * 0.5 + 0.5; //(-1, 1)-->(0, 1)
#elif defined (UNITY_REVERSED_Z)
    depth = 1 - depth;       //(1, 0)-->(0, 1)
#endif

```

---
Tags: unity, shaders, fragment-shader, projection, shadow-mapping
---


title: How do I cast a float4 to a float[4]?

text:
# Question
Title: How do I cast a float4 to a float[4]?
I've a RGBA16F texturecube for 4 pointlights shadows rendered in one pass. Each color channel stores the object to light distance for one pointlight shadow (e.g red channel is for light 0 and so on). Everything works fine but I'm obliged to do some testing to fill the output color correctly when writing to the texture and the reverse when reading from it. I would like to cast float4 to float\[4\] to simplify this part of my shaders but it seems casting like this is not possible. I've seen some workaround for glsl but it does not really match the union keyword in C++. Any suggestion welcome

# Answer
> 2 votes
From AMD's Dark Secrets of Shader Development or What Your Mother Never Told You About Shaders, I learned you can just write

```
float L[4] = (float[4])Tex.rgba

```

to read rgba as an array of floats. So simple in fact!

---
Tags: hlsl, data-structure
---


# Question
Title: Besides 3d, why would I need to use a canvas instead of using plain css and html?
Purely speaking for the use of 2d.

First off, redrawing the canvas on every frame seems quite inefficient. Even when you can create multiple to not redraw everything etc. CSS animations to move objects work really well, why deviate?

What are the benefits of using the html canvas instead of just creating 'divs' in a 'body' to move and/or create objects on? What am I missing?

# Answer
* **The CanvasRenderingContext2D API is working in a way that is more familiar to game developers.** Game developers who worked with other 2d graphics APIs before are used to having a function which says "draw this sprite on these pixel coordinates". Which the canvas2d API offers. Yes, I guess you *could* build a tilemap with ordered sprites on top using a couple hundred `<img>` elements positioned with CSS. But that can get pretty cumbersome. I don't know anyone who ever bothered doing that. People wanting to create 2d web games usually used Flash. And when Flash died, people switched to canvas (or to game engines using canvas).
* **CanvasRenderingContext2D can do things you just can't do with CSS**. People who have more expertise than me at CSS 3 and all its official and unofficial features might be able to prove me wrong on specific examples, but fact is that CSS was not designed to do pixel-level graphics filtering and manipulation. Something you can do with canvas.
* **CanvasRenderingContext2D output can be cached and reused**. A canvas does not need to be visible or even part of the DOM tree in order to draw on it. And a canvas can be used as an image source for the DrawImage function. That means that if you have elements in your game which require some time to create but then don't need any more changes, then you can just draw them once to an offscreen canvas and then draw that canvas (or parts of it) to the main canvas each frame. One use-case are character sprites using paper-dolling and palette swapping. When you have a 2d character with multiple equipment customization options which also use expensive recoloring algorithms, then you can just draw the whole spritesheet with all its equipment to an off-screen canvas. You can then use that off-screen canvas with the customized character as the spritesheet that appears on the on-screen canvas. So all that character customization doesn't eat more FPS than a regular sprite would.
* **Browsers usually have erase-and-redraw render loops anyway**. What do you think will happen in the browsers rendering engine when you make visible changes to the DOM? HTML rendering engines aren't magic. The engine will also erase the whole render of the website and recreate it. Perhaps it can use techniques like dirty rectangles to avoid redrawing *everything*, but so can you when you use the canvas API. Sure, browser rendering engines often have countless hours of development and amazing optimization. But the use-case they are optimized for is rendering *websites*. Games usually don't behave in the way regular websites do.
* **Canvas and DOM can be used in combination**. One argument for DOM you might hear is "Have you tried building an UI in canvas? It's either super annoying or requires a huge library which basically reinvents HTML+CSS". Well, you don't have to, because HTML and canvas can easily coexist within the same application. When I create a web-game, then I usually use canvas for rendering the game but create the UI using HTML+CSS and place it on top of the game canvas. I've also occasionally put *another* transparent canvas on top of the UI to draw things like particle effects which appear to come from HTML elements.

Although it is possible to use canvases in a HTML dom tree, it is unfortunately not possible to do the reverse and render HTML directly to a canvas. Although there is a hack which allows to do that with certain restrictions by embedding HTML in an SVG object.
> 3 votes

---
Tags: javascript, html, css
---


# Question
Title: How can I implement the player being able to place tiles on a 1d array grid?
Tell me if I need to provide more info.

My tile-based sandbox game needs to allow the Player to place tiles He has collected. But the problem is, I do not know how I can place the tile based on the Player's location on a 1d array, I have tried doing this MRE:

```
let mut player_index: usize = 5000 * 2500; // This is the center of the 5000 x 5000 map on the 1d array, where the player starts
let mut player_index_counter_x: isize = 0;
let mut player_index_counter_y: isize = 0;

let mut ftime: f32 = get_frame_time();
let mut fps: f32 = get_fps() as f32;
let mut speed: f32 = 350.0 * ftime;

loop {
    if player_index_counter_x >= 32 {
        player_index += 1;
        player_index_counter_x = 0;
    }

    if player_index_counter_x <= -32 {
        player_index -= 1;
        player_index_counter_x = 0;
    }

    if is_key_down(KeyCode::Q) {
        layers[player_z - 1][player_index] = '#'; // This places a wooden plank where the player is standing
    }

    if is_key_down(KeyCode::D) {
        player_index_counter_x += speed as isize;
    }
    // And so on..
}

```

But the tile placement by the player is off by hundreds of tiles.

The game uses 32x32 pixel tiles.

# Answer
> 1 votes
If the tile width size is 32 pixels, the inner area will be between 0-31

**0..31 0..31 0..31 0..31**

So you change the tile index (player\_index) in two situations:

1. player\_index\_counter\_x \> 31
2. player\_index\_counter\_x \< 0

---

```
if player_index_counter_x > 31 {
    player_index += 1;  // one tile right
    //player_index += player_index_counter_x % 32; // if speed is fast enough to move more than one tile in one frame
    //player_index_counter_x = 0;  // if you move 1 by 1 pixel
    player_index_counter_x = player_index_counter_x - 32;  // because speed could be greater than 1
}

if player_index_counter_x < 0 {
    player_index -= 1;  // one tile left
    //player_index_counter_x = 31;  // if you move 1 by 1 pixel
    player_index_counter_x = 32 + player_index_counter_x;  // because speed could be greater than 1
}

```

For the vertical movement, you need to know the number of the tiles in one row.

```
let nTilesInOneRow = 100;
if player_index_counter_y < 0 {
    player_index -= nTilesInRow;  // going up one full row
    player_index_counter_y = 32 + player_index_counter_y;  // because speed could be greater than 1
}
if player_index_counter_y > 31 {
    player_index += nTilesInRow;  // going down one full row
    player_index_counter_y = player_index_counter_y - 32;  // because speed could be greater than 1
}

```

I suppose that you use (player\_index\_counter\_x, player\_index\_counter\_y) to draw the tile of the player. In the above code, player\_index\_counter\_x, player\_index\_counter\_y is the center of the player tile. The player is just a point. If you need the top left corner to draw it, just calculate the top-left position:

```
player_index_counter_topleft_x = player_index_counter_x - player_tile_width/2.0;
player_index_counter_topleft_y = player_index_counter_y - player_tile_height/2.0;

```

**TODO:** you need to add more conditions to check that you do not move beyond the map limits.

**DISCLAIMER** I have never used Rust, review the code/pseudocode.

---
Tags: tilemap, rust
---


# Question
Title: How to not create a new event every time I introduce a new "boss"
I have to create a new event when I'm going to enter a new boss phase when the current boss dies.

This works, but I can see this being messy when I'm going to create a new boss each time. Below is the script I use now:

```
public class EventManager : MonoBehaviour
{
    public static event Action GoingToPhase;
    public static event Action GoingToPhaseTwo;

    public static event Action FirstGone;
    public static event Action SecondGone;

    public static void SecondPhaseTriggered()
    {
        GoingToPhase?.Invoke();
    }

    public static void SecondPhaseTriggeredTwo()
    {
        GoingToPhaseTwo?.Invoke();
    }

   public static void PassOn()
    {
        FirstGone?.Invoke();
    }

    public static void PassOnSecond()
    {
        SecondGone?.Invoke();
    }
}

```

# Answer
> 2 votes
Anytime you start putting "One" and "Two" into your variable names, that's a good sign that what you really want is a collection type like an array or a list.

```
public class BossManager : MonoBehaviour {

    [System.Serializable]
    public struct BossPhase {
        public UnityEvent OnPhaseEnter;
        public UnityEvent OnPhaseComplete;
    }

    public List<BossPhase> phases;

    // Start at -1, so calling TryTriggerNextPhase begins at phase [0].
    int _currentPhase = -1;

    public bool TryTriggerPhase(int index) {
        if (index < 0 || index >= phases.Count) return false;
        phases[index].OnPhaseEnter?.Invoke();
        _currentPhase = index;
        return true;
    }

    public bool TryTriggerNextPhase() {
        return TryTriggerPhase(_currentPhase + 1);
    }

    public void CompleteCurrentPhase() {
        phases[_currentPhase].OnPhaseComplete?.Invoke();
    }
}

```

This gives you a flexible sequence of phases you can set up in data in the Inspector:

Or if you prefer, you can also populate the list of phases and their listeners in code. The good thing is that you don't need new functions to trigger each phase - the three here allow you to complete the current phase, trigger the next phase, and jump to an arbitrary phase, no matter how many phases you add.

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


title: Second texture is black

text:
# Question
Title: Second texture is black
I want to use two png pictures as textures. Then I want to set textureId as attribute to each vertex. My vertex shader:

```
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 transformMatrix;
attribute vec2 aPosition;
attribute vec2 aTexPos;
attribute float aTexIdPos;
varying vec2 vTexPos;
varying float vTexIdPos;
void main() {
    vTexPos = aTexPos;
    vTexIdPos = aTexIdPos;
    gl_Position = projectionMatrix * viewMatrix * transformMatrix *
    vec4(aPosition.xy, 0.0, 1.0);
}

```

Then this is the way, I load textures:

```
public void addTextures(Resources resources, int... resIds){
    GLES20.glGenTextures(resIds.length, textureIds, 0);
    numTextures = resIds.length;

    for(int i = 0 ; i < resIds.length ; i++){
        if (textureIds[i] == GLES20.GL_FALSE)
            throw new RuntimeException("Error loading texture");

        // bind the texture and set parameters
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIds[i]);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        // Load a bitmap from resources folder and pass it to OpenGL
        // in the end, we recycle it to free unneeded resources
        Bitmap b = BitmapFactory.decodeResource(resources, resIds[i]);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, b, 0);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

        b.recycle();
    }

    int uTexture = GLES20.glGetUniformLocation(programHandle, "uTexture");
    GLES20.glUniform1iv(uTexture, numTextures, textureIds, 0);
}

```

When I use this fragment shader, it renders texture that was last baund with glBindTexture:

```
precision mediump float;
uniform sampler2D uTexture[16];
varying vec2 vTexPos;
varying float vTexIdPos;
void main(){
    gl_FragColor = texture2D(uTexture[0] , vTexPos);
}

```

But if I change it to:

```
precision mediump float;
uniform sampler2D uTexture[16];
varying vec2 vTexPos;
varying float vTexIdPos;
void main(){
    gl_FragColor = texture2D(uTexture[1] , vTexPos);
}

```

It renders black rectangles. I dont understand why binding texture changes what uTexture\[0\] contains. It should contain my first picture and uTexture\[1\] should contain the second one.

# Answer
> 0 votes
I think that the problem is the data provided in glUniform1iv call

```
int uTexture = GLES20.glGetUniformLocation(programHandle, "uTexture");
GLES20.glUniform1iv(uTexture, numTextures, **textureIds**, 0);

```

You are assigning to the uniform "uTexture" location, and the following numTextures locations, the values of the textureIds generated by

```
GLES20.glGenTextures(resIds.length, textureIds, 0);

```

But sampler2D uniforms expect the values of the "GLES20.GL\_TEXTURE0 + i", basically \[0, 1, 2, 3, 4, ...\]

```
int[] textureOffset = new int[]{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
int uTexture = GLES20.glGetUniformLocation(programHandle, "uTexture");
GLES20.glUniform1iv(uTexture, numTextures, **textureOffset** , 0);

```

Note: A black texture is shown when you provide a textureOffset not activated. And if there is no active texture, the tests that I have run shown that texture 0 points to the last bound texture.

---
Tags: opengl-es2
---


# Question
Title: Google's Play Asset Delivery Build aab File in Unity too large
I want to upload an aab file from my unity project to my play console account, but unfortunately, my file was rejected because it's size is larger than the 150MB threshold limit for aab on google play store.

Then while looking for a solution, I found out that obb files are now made obsolete and I could use google's Play Asset Delivery system to upload my file. So then I followed the "not so clear" instructions on how to use the PAD system in Unity, I made an asset bundle that contains all my font asset(because that was what increased my aab from 120MB to 260MB), and added it to the Asset Delivery Settings in Unity and selected "Separate Base APK Asset". Then I built the aab file using PAD(by clicking Google \> Build Android App Bundle), and my generated aab went from 260MB to 680MB.

Why did the size increase enormously? Isn't the point of it to reduce the size on the aab so that it can be accepted by play? Am I missing something or have I done something wrong?

# Answer
This is a workaround: https://killertee.wordpress.com/2021/09/04/unity-play-asset-delivery-and-addressable-assets/

It uses unity's addressables package with google's play asset delivery and not asset bundles.
> 1 votes

# Answer
If you're relying on Unity only to use PAD (Play Asset Delivery), Unity's solution has problems and doesn't assemble the AAB properly, basically, it will get everything you have in your StreamingAssets folder and that will be packed in an asset pack + it will keep the StreamingAssets stuff in the base.apk archive, making your final AAB and APKS at least double the size it should be or more. In order to use PAD properly, you should follow up on Google's explanations about it here https://developer.android.com/guide/playcore/asset-delivery and come up with your own version of what Google suggests, I say it because I just finished our own PAD solution in my company and I ended up writing stuff for Runtime, Editor and Build on Unity. It's all working as expected for us. Google's plain solution for Unity is no silver-bullet either, it will probably just work for a fraction of projects out there.
> 0 votes

---
Tags: unity, google-play, google-play-services, build-process, build
---


# Question
Title: Draw 2D circles/squares efficiently with Unity
I'm doing a lot of 2D simulations using Unity, and I usually instantiate a lot of squares/circles sprite. When the number of sprites reaches 1k or higher, the FPS usually reduces to 10-20, which makes everything really slow/unusable.

So my question is, how can I draw 2D squares/circles with less impact on frame rate (maybe using some other methods as well)? The only requirements are that the color, position and scale of individual squares/circles must be changeable (for the simulation), and the squares/circles must be filled (with that color).

# Answer
I'd second Zibelas's recommendation in the comments to use a particle system.

You can create an array to hold the information about all of your shapes:

```
const int MAX_SHAPES = 5000;
ParticleSystem.Particle[] _shapeBuffer = new ParticleSystem.Particle[MAX_SHAPES];

```

Then iterate over that array to update the positions / rotations / shapes / colours / etc. of the shapes you want to draw.

```
for (int i = 0; i < currentShapeCount; i++) {
    var particle = _shapeBuffer[i];

    particle.position   = UpdateShapePosition(particle, i);
    particle.startColor = UpdateShapeColor(particle, i);
    particle.startSize  = UpdateShapeSize(particle, i);
    particle.rotation   = UpdateShapeAngle(particle, i);

    // Keep this particle alive forever.
    particle.startLifetime = float.MaxValue;
    particle.remainingLifetime = float.MaxValue;

    _shapeBuffer[i] = particle;
}
for (i = currentShapeCount; i < MAX_SHAPES; i++) {
    var particle = _shapeBuffer[i];

    // This kills the particle. ;)
    particle.remainingLifetime = -1;

    _shapeBuffer[i] = particle;
 }

```

Then write your changed buffer back to the particle system to be drawn:

```
particleSystem.SetParticles(_shapeBuffer, MAX_SHAPES, 0);

```

If your shapes should move in predictable ways and only a few of them need custom updates, you can delegate that to the particle system by assigning particles a velocity / angular velocity, and using `GetParticles` to read its updates back into your C#-side buffer when you want to intervene.

You can even use the flipbook feature to draw both your circles and squares with a single buffer, without any shader magic, by using the `randomSeed` or `remainingLifetime` parameters to control which flipbook page this particle uses.

The job system is also great for big batch work like this, but it's a bigger commitment with a steeper learning curve and initial development cost than a quick-and-dirty abuse of the particle renderer.
> 1 votes

# Answer
The existing answers are constructive. Here are some other suggestions:

First of all, it is necessary to clarify what caused the program slow. There are many reasons for it such as **code logic**, **draw calls**, **rendering**.

1. Use Profiler to get performance information. Find out which line of code cost most cpu time and rewrite it more efficiently.
2. Check your Draw call on Game tab -\> Stats -\> Batches. If the number of draw call is high, Ensure Dynamic Batching is taking effect.

The condition of batching is:

1. All sprites are in the same SpriteAtlas.
    2. All sprites share a same Material. You can set different color to material at runtime.
    3. Batching option is open.
3. Usually the CPU is the performance bottleneck in small project. But if you suspect it is the problem of GPU rendering, go check FrameDebugger.

Before using JobSystem, Make sure your code is thread-safe at the functional level. For example, If the behaviour of an object depends on another, they can not run Parallel.
> 2 votes

---
Tags: unity, sprites, frame-rate, efficiency
---


title: Unity3D UFO controls

text:
# Question
Title: Unity3D UFO controls
As a fairly new Unity programmer I'm working on a small game which involves an UFO *insert X-files theme*

Following YouTube-blogger Brackey's tutorial for 3rd person controls I've come this far, but when it comes to ascending and descending my UFO I can't wrap my head around how to do so.

```
    public CharacterController controller;
public Transform cam;

public float speed = 6f;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;

// Update is called once per frame
void Update()
{
    float horizontal = Input.GetAxisRaw("Horizontal");
    float vertical = Input.GetAxisRaw("Vertical");
    Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;

    if (direction.magnitude >= 0.1f)
    {
        float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
        float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
        transform.rotation = Quaternion.Euler(0f, angle, 0f);

        Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
        controller.Move(moveDir.normalized * speed * Time.deltaTime);
    }

    if (Input.GetKeyDown("x"))
    {
        // Decend UFO
        transform.Translate(0, -1, 0);
    }

    if (Input.GetKeyDown("e"))
    {
        // Ascend UFO
    }

```

Can anyone point me in the right direction?

Kind regards

# Answer
> 0 votes
I assume you are talking about this code here:

```
if (Input.GetKeyDown("x"))
{
    // Decend UFO
    transform.Translate(0, -1, 0);
}

```
* `Input.GetKeyDown` detects a key*tap*, not a key*hold*. It is only `true` during the first frame the player started pressing the key and is `false` while they keep holding it. What you probably want to do is lower the UFO while the player is holding the key and stop moving it when they release it. You would do that with `Input.GetKey`. I would also recommend to not refer to keys by a string literal containing its name but use the constants in `KeyCode` instead. So `if (Input.GetKey(KeyCode.X))`
* Remember that you do not know how long ago the last Update was. The time between updates can change depending on the framerate. So if you move objects by a distance, then you should always multiply that distance with `Time.deltaTime`. And while you are on it, you might want to also add another Inspector-exposed variable `public float descendSpeed` which allows you to adjust how fast you want the ufo to ascend and descend. So `transform.Translate(0, -descendSpeed * Time.deltaTime, 0)`.

# Answer
> 0 votes
Try lerping the z-value from position A (start point) to position B (end point).

You can alternatively lerp the whole 3D vector. May be easier.

"Lerp" is an informal verb meaning to "linearly interpolate" a value. Non-linear interpolations look more organic and are also possible, but this should do what you want for now.

---
Tags: unity
---


# Question
Title: Move camera when dragging right and left
I am making a 2D game using Unity, and in the game you see the world from the side like in the first Super Mario games. But instead of moving the camera by walking, I want to move the camera by dragging with the mouse cursor. So basically move the cursor to the right of the screen click and hold and then move the cursor to the middle should move the camera to the right, and then vice versa to move left (So the camera is only moved on the x-axis). The game also has a feature to drag and drop objects and I used this tutorial for that: https://youtu.be/HfqRKy5oFDQ

And I am now trying to implement this by adding to the code from that tutorial with the help of this tutorial: https://youtu.be/Qd3hkKM-UTI. I have this code:

```
    private Camera mainCamera;
    private Transform camTransform;
    private Vector3 origin;
    private Vector3 difference;
    private Vector3 resetCamera;

    private void Awake()
    {
        mainCamera = Camera.main;
        camTransform = mainCamera.transform;
    }

    private IEnumerator DragCameraUpdate()
    {
        while (mouseClick.ReadValue<float>() != 0)
        {
            //print("Mouse " + Time.deltaTime);
            difference = (mainCamera.ScreenToWorldPoint(Mouse.current.position.ReadValue())) - camTransform.position;
            //print("difference " + difference);
            origin = mainCamera.ScreenToWorldPoint(Mouse.current.position.ReadValue());
            //print(camTransform.position);
            camTransform.position = origin - difference;
            //print(camTransform.position);
            yield return null;
        }
    }

```

So the loop itself works just as expected it loops through when the mouse is pressed and stopps when its not clicked anymore. The code to change the camera position, however, does not work. I tried printing out the position before and after it was supposed to change but it didn't change at all. I don't get any errors either. How can I fix this code so it moves the camera first of all and then also add code so it can only be moved on the x-axis?

Thanks in advance.

# Answer
Let's do some algebra! You have three equations like this:

```
difference = mouseWorldPosition - oldCameraWorldPosition

origin = mouseWorldPosition

newCameraWorldPosition = origin - difference

```

We can substitute the definitions for `origin` and `difference` into the last equation and simplify:

```
newCameraWorldPosition = (mouseWorldPosition) - (mouseWorldPosition - oldCameraWorldPosition)
newCameraWorldPosition = mouseWorldPosition - mouseWorldPosition + oldCameraWorldPosition
newCameraWorldPosition = oldCameraWorldPosition

```

Congratulations. You've told the camera "stay where you were" with extra steps.

You probably want something more like this:

```
Vector3 GetMousePositionInWorld() {
    Vector3 screenPosition = Mouse.current.position.ReadValue();

    // If you're using a perspective camera for parallax,
    // be sure to assign a depth to this point.
    // screenPosition.z = 1f;

    return mainCamera.ScreenToWorldPoint(screenPosition);
);

private IEnumerator DragCameraUpdate()
{
    Vector3 initialMousePosition = GetMousePositionInWorld();

    while (mouseClick.ReadValue<float>() != 0)
    {
        Vector3 currentMousePosition = GetMousePositionInWorld();
        Vector3 travel = currentMousePosition - initialMousePosition;

        // Remove any vertical travel to lock the motion to the horizontal plane.
        travel.y = 0;

        mainCamera.transform.Translate(-travel, Space.World);

        yield return null;
    }
}

```
> 2 votes

---
Tags: unity, 2d, input, mouse
---


# Question
Title: How to efficiently do one-to-many collision checks?
Scenario: 4 players, each can have from 1 to 100 pawns.

I want to be able to efficiently check if Player 1's pawns collides with Player 2, 3, and 4.

Currently I have an AABB check, done first on Player 1's side where it checks against Player 2's pawns. Now I realized I have to do this for the rest of the players.

This is done on a NodeJS server. If a collision is detected, it sends a message to each player, which in turn kills the pawn in question

// aabbCheck
var aabbCheck = function (aabb1, aabb2) {
    if (aabb1.x + aabb1.w > aabb2.x &&
        aabb1.x < aabb2.x + aabb2.w &&
        aabb1.y + aabb1.h > aabb2.y &&
        aabb1.y < aabb2.y + aabb2.h) {
        return true;
    }
    return false;
};
// make the pawns move based on the angle the player targets
var marchPawn = function (pawn) {
    var speed = 90;
    pawn.aabb.x += speed * (Math.cos(pawn.angle) * (Date.now() - pawn.spawnTime) * 0.001);
    pawn.aabb.y += speed * (Math.sin(pawn.angle) * (Date.now() - pawn.spawnTime) * 0.001);
    pawn.spawnTime = Date.now();
};
// check if pawn collides with another entity
var checkPawnCollision = function (pawn, other) {
    var aabb1 = {};
    aabb1.x = pawn.aabb.x;
    aabb1.y = pawn.aabb.y;
    aabb1.w = pawn.aabb.w;
    aabb1.h = pawn.aabb.h;

    var aabb2 = {};
    aabb2.x = other.aabb.x;
    aabb2.y = other.aabb.y;
    aabb2.w = other.aabb.w;
    aabb2.h = other.aabb.h;

    if (aabbCheck(aabb1, aabb2)) {
        // console.log('pawn collides with other');
        return true;
    }
    return false;
};

var playerPawn = {
    player1: [],
    player2: [],
    player3: [],
    player4: []
};

// Check if player 1 have pawns on the field
if (playerPawn.player1.length > 0) {
    for (var i = 0; i < playerPawn.player1.length; i++) {
        var pawn = playerPawn.player1[i];
        if (pawn) {
            // make the pawn move
            marchPawn(pawn);

            // Check if player 1 pawn collides with player 2 pawn
            if (playerPawn.player2.length > 0) {
                for (var j = 0; j < playerPawn.player2.length; j++) {
                    var p2pawn = playerPawn.player2[j];
                    if (p2pawn) {
                        if (checkPawnCollision(pawn, p2pawn)) {
                            // console.log('Pawn Collision');
                            playerPawn.player1.splice(i, 1);
                            playerPawn.player2.splice(j, 1);
                        }
                    }
                }
            }
        }
    }
}
// NOT YET DONE
// Check if player 2 have pawns on the field
if (playerPawn.player2.length > 0) {
    for (var i = 0; i < playerPawn.player2.length; i++) {
        var pawn = playerPawn.player2[i];
        if (pawn) {
            marchPawn(pawn);
        }
    }
}
// NOT YET DONE
// Check if player 3 have pawns on the field
if (playerPawn.player3.length > 0) {
    for (var i = 0; i < playerPawn.player3.length; i++) {
        var pawn = playerPawn.player3[i];
        if (pawn) {
            marchPawn(pawn);
        }
    }
}
// NOT YET DONE
// Check if player 4 have pawns on the field
if (playerPawn.player4.length > 0) {
    for (var i = 0; i < playerPawn.player4.length; i++) {
        var pawn = playerPawn.player4[i];
        if (pawn) {
            marchPawn(pawn);
        }
    }
}

```
</code></pre>

# Answer
There is a big error in your code that will have you pull you hair until you're bald.

When you `playerPawn.player1.splice(i, 1);` you effectively change the size of the array, which is not bad per se, but the objects that were *after* this index are shifted *and* you still increment the index, so you'll effectively skip the object that was right after the one you just removed. To fix this, increment your index (i or j) *only* if no item was removed. FWIW, changing an array like this in a loop is typically seen as inefficient (because of all the shifts).

I think there might be a couple of game design issues too, based on the algorithm that you currently use. I'm assuming that all four players play against each other, and no player should be favoured.

1. If you call `marchPawn(pawn);`, then check right away for collisions, some pawns will not have the chance to move, so the concept of "chase" will never happen in your game (P1 pawn moved one step toward x+, and P2 pawn moved at the same time, in the same direction).
2. If you start to check for collisions between Player1 pawns and Player2 pawns, and remove them right away, there are situations that a Player1 pawn could hit a Player2 pawn *and* a Player3 pawn during the same frame. That's okay for P1 and P2, but P3 is the winner here because the algorithm did not even check for the collision with their pawn.

Here is a piece of pseudocode that tries to get around these issues.

```
pawnArrays[4][100] // four players, each 100 pawns

// Move everyone first; this makes sure that all the Pawns have a chance to move
// every frame, makes "chase" possible.
for ( p : [0..3] )
{
  for( pPawnIndex : [0..pawnArrays[p].length-1] )
    marchPawn(pawnArrays[p][pPawnIndex]);
}

// Then check for collisions
for ( pA : [0..2] )
{
  for( pB : [pA + 1..3] )
  {
    for( pApawnIndex : [0..pawnArrays[pA].length-1 )
    {
      for( pBpawnIndex : [0..pawnArrays[pB].length-1 )
      {
        // Note that we do check collisions even with those that are "dead"
        // to allow "three way" collisions.
        if ( checkPawnCollision(pawnArrays[pA][pApawnIndex], pawnArrays[pB][pBpawnIndex]) )
        {
          pawnArrays[pA][pApawnIndex].dead = true
          pawnArrays[pB][pBpawnIndex].dead = true
        }
      }
    }
  }
}

// Then react to collisions
for ( p : [0..3] )
{
  // We "push" via copy all the "dead" objects at the end of the array. We "swap" a
  // dead pawn from the beginning of the array with a pawn from the end of the
  // array, so at the end, all the dead ones are at the end, and we can easily
  // splice them all at once. This avoid multiple array shifts.
  // Note that this will shuffle the order of the Pawns in the arrays, but AFAIK,
  // it does not appear to be an issue for your situation.
  goodIndex = 0
  placeBadIndex = pawnArrays[p].length
  while( goodIndex != placeBadIndex )
  {
    if ( pawnArrays[p][goodIndex].dead )
    {
      temp = pawnArrays[p][goodIndex]
      pawnArrays[p][goodIndex] = pawnArrays[p][placeBadIndex-1]
      pawnArrays[p][placeBadIndex-1] = temp
      --placeBadIndex
    }
    else
    {
      ++goodIndex
    }
  }

  // then we delete them
  pawnArrays[p].splice(placeBadIndex)
}

```

Note that this algorithm here takes care of suggestion #3 from the other answer. You could go ahead and improve this further once you profile your game and realize it's a bottle neck by using the other more generic suggestions provided in that answer.
> 1 votes

# Answer
It sounds like you are looking for collision detection

It's a common problem with game engines: how to efficiently check if an object collides with the other(when there are hundreds of objects in the scene).

In your particular case (single shape, no triangles), here are some strategies:

1. **Exploiting temporal coherence:** Cache last collision result. If the two objects for checking did not move, just use the old result.
2. **Spatial partitioning:** If the two objects for checking are far away, they absolutely have no chance to collide, no need to check them. Spatial partitioning is a good way to do it. Basically, we need to divide the game scene into cells and create a manager of all cells. When an object is created/destroyed/moved, tell the manager the new position. For each object just check the objects only in the same cell and cells nearby. You can simply use an array, or an octree.
3. **Same collision avoiding**: while Player 1 is already checked(with other players), no need to check Player 1 again when you check Player 2.
> 1 votes

---
Tags: collision-detection, javascript, node.js
---