# Question
Title: Why players who join late can't see other people data?
I want to show the name of the players above their head but I have a problem where people joining late doesn't get other players' name.

For example:

* Player 1 joins to the server with the name Peter.
* Player 2 joins to the server with the name Josh.
* Peter (Player 1) sees Josh's name perfectly, but when Josh joins Peter's name is not synchronized correctly.

My sync code looks something like this:

```
[SyncVar] private string NAME;
public override void OnStartClient(){
    if(networkPlayerData is null)
    {
        networkPlayerData = BTNetworkController.Controller.playerData;
        NAME = BTNetworkController.Controller.playerData.Name;
    }
    SendPlayerNameToServer(NAME);
}
[Command]
private void SendPlayerNameToServer(string name)
{
    RpcSetPlayerName(name);
}

[ClientRpc]
void RpcSetPlayerName(string name)
{

    gameObject.GetComponentInChildren<TMP_Text>().text = name;
}

```

So my question is how can I sync data to newly joined players and refresh player names accordingly.

# Answer
> 1 votes
Do not use `NAME` and `name`, it makes things confusing and you might write to the wrong variable at times. Give it more fitting names, like playerName, localName, nameToUpdate or similar. All caps is usually used for constants.

Your `SendPlayerNameToServer` is using wrong naming, since it is a Command, it has to start with Cmd for Mirror to work correctly. Therefore `CmdSendPlayerNameToServer` is the correct name. Command docu

`[SyncVar]` does not need a `ClientRpc`, you can set them on the server and they get synced automatically. In case you want to react to a change of the name, you could use a hook that reacts to the change. Hook docu

```
[SyncVar(hook = nameof(SetPlayerName))]
private string playerName;

void SetPlayerName(string oldName, string newName)
{
    gameObject.GetComponentInChildren<TMP_Text>().text = newName;
}

```

Since your code contains a OnClientStart(), which should be part of the NetworkManager and not the Player, here is a small example for a player script that you can add to the Player Pref and add it to the NetworkManager under Player.

```
public class Player: NetworkBehaviour
{
    [SyncVar] public string playerName;

    void Start()
    {
        //we are only setting the name from the place that owns the player.
        if (hasAuthority)
        {
            CmdRegisterPlayer();
        }
    }

    [Command]
    private void CmdRegisterPlayer(){
        playerName = "Player " + Random.Range(0, 100);
    }
}

```

---
Tags: unity, networking, synchronization, mirror-networking
---


# Question
Title: Press and hold camera movement with mouse in new Input System?
I am transitioning to the new movement system and am having trouble figuring out how to move the camera when a mouse button is pressed and held.

Here's how I did it before:

```
private void Update()
{
    // Get the position of the mouse when a middle click occurs
    if (Input.GetMouseButtonDown(2))
    {
        _dragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
    }

    // If the MMB is still held down, calculate the distance and move the camera
    if (Input.GetMouseButton(2))
    {
        Vector3 difference = _dragOrigin - cam.ScreenToWorldPoint(Input.mousePosition);
        cam.transform.position += difference;
    }
}

```

I have tried doing something similar in the new input system but it doesn't work:

```
public void OnMMB(InputAction.CallbackContext context)
{
    if (context.phase != InputActionPhase.Started)
    {
        // Get the position of the mouse when a middle click occurs
        dragOrigin = cam.ScreenToWorldPoint(Mouse.current.position.ReadValue());
    }
    else
    {
        // If the MMB is still held down, calculate the distance and move the camera
        Vector2 newPosition = cam.ScreenToWorldPoint(Mouse.current.position.ReadValue());
        Vector3 difference = dragOrigin - newPosition;
        cam.transform.position += difference;
    }
}

```

Here is how I set this up inside the Input editor:

The `Action Type` of the action is `Button`.

# Answer
> 1 votes
You seem to want to detect middle mouse events and then check the mouse position.

In my current project I did it the other way around. I subscribed to the standard `Point` action of the pre-configured `UI` action map in order to catch mouse moves (or other pointy devices). Then I check the status of my own `MiddleClick` action within that event handler.

```
// mouse location on last update
private Vector2 lastPoint;

private void Awake() {
    // create instance of the class auto-generated from the InputActions asset
    inputActions = new MyInputActions();
    // subscribe to pointer move events
    inputActions.UI.Point.performed += OnPoint;
    // enable the bindings
    inputActions.Enable();
}

private void OnPoint(InputAction.CallbackContext ctx) {
    // obtain current mouse position from context
    Vector2 screenPoint = ctx.ReadValue<Vector2>();
    // convert it from screen to world coordinates
    Vector2 worldPoint = cam.ScreenToWorldPoint(screenPoint);
    // check if middle mouse button is being held.
    if (inputActions.UI.MiddleClick.ReadValue<float>() > 0) {
        // calculate difference between current and previous mouse location
        Vector2 delta = lastPoint - worldPoint;
        // use that difference to move your camera
        transform.Translate(delta);
        // adjust the worldPoint accordingly, because after the scroll it's now somewhere else
        worldPoint += delta;
    }
    // update lastPoint for the next frame
    lastPoint = worldPoint;
}

```

---
Tags: unity, 2d, camera, input, events
---


title: Sphere - AABOX Edge detection

text:
# Question
Title: Sphere - AABOX Edge detection
I am trying to implement a particle-AABOX edge collision, the below images represent, two timesteps(dt) where the spherical particle is accelerated by gravity.

I have the particle center C and its radius r, along with AABOX coordinates as B\_min and Bmax.

I have to check if the particle collides with any edges, and then bounce back, if a collision happens.

If I use Arvo's AABB vs Sphere collision algorithm, then I can find if there is an intersection within the radius, but I can't get the hitpoint and hitdistance.

And after getting the hitpoint and hitdistance, how to reflect it back? (for every timestep, I will have the current position C, and also the previous position P).

I tried to calculate it by implementing,

```
BOX_N[0] = make_vector(-1, 0, 0);// x-min;
BOX_P[0] = make_point(bb_min.x, bb_min.y + (bb_max.y - bb_min.y) / 2.0f , bb_min.z + (bb_max.z - bb_min.z) / 2.0f);

BOX_N[1] = make_vector(1, 0, 0); // x-max
BOX_P[1] = make_point(bb_max.x, bb_min.y + (bb_max.y - bb_min.y) / 2.0f , bb_min.z + (bb_max.z - bb_min.z) / 2.0f);

BOX_N[2] = make_vector(0, -1, 0);// y-min;
BOX_P[2] = make_point(bb_min.x + (bb_max.x - bb_min.x) / 2.0f, bb_min.y, bb_min.z + (bb_max.z - bb_min.z) / 2.0f);

BOX_N[3] = make_vector(0, 1, 0); // y-max
BOX_P[3] = make_point(bb_min.x + (bb_max.x - bb_min.x) / 2.0f, bb_max.y, bb_min.z + (bb_max.z - bb_min.z) / 2.0f);

BOX_N[4] = make_vector(0, 0, -1);// z-min;
BOX_P[4] = make_point(bb_min.x + (bb_max.x - bb_min.x) / 2.0f, bb_min.y + (bb_max.y - bb_min.y) / 2.0f , bb_min.z);

BOX_N[5] = make_vector(0, 0, 1); // z-max
BOX_P[5] = make_point(bb_min.x + (bb_max.x - bb_min.x) / 2.0f, bb_min.y + (bb_max.y - bb_min.y) / 2.0f , bb_max.z);

__device__ int box_collision(const Point& previous_position, const Point& current_position, const Vector& direction, const float& radius, Point& hitPoint, Vector& normal, float& hit_distance) {
    Point boxPoint;
    int index;

         if (current_position.x < (bb_min.x + radius)) { index = 1; normal = BOX_N[0]; boxPoint = BOX_P[0]; boxPoint.x += radius;}
    else if (current_position.x > (bb_max.x - radius)) { index = 1; normal = BOX_N[1]; boxPoint = BOX_P[1]; boxPoint.x -= radius;}

    else if (current_position.y < (bb_min.y + radius)) { index = 2; normal = BOX_N[2]; boxPoint = BOX_P[2]; boxPoint.y += radius;}
    else if (current_position.y > (bb_max.y - radius)) { index = 2; normal = BOX_N[3]; boxPoint = BOX_P[3]; boxPoint.y -= radius;}

    else if (current_position.z < (bb_min.z + radius)) { index = 3; normal = BOX_N[4]; boxPoint = BOX_P[4]; boxPoint.z += radius;}
    else if (current_position.z > (bb_max.z - radius)) { index = 3; normal = BOX_N[5]; boxPoint = BOX_P[5]; boxPoint.z -= radius;}
    else return 0;

    auto denom = vdot(direction, normal);
    if (denom < 1e-6) return 0;

    hit_distance = vdot(normal, boxPoint - previous_position) / denom;
    if (hit_distance < 0) return 0;

    hitPoint = previous_position + hit_distance * direction;

    return index;
}

inline __device__ bool compute_box_collision(Point& previous_position, Point& current_position, const float& radius) {
    Point hitPoint;
    Vector normal;
    float hit_distance;

    Vector direction = vnormalize(current_position - previous_position);

    int collision = box_collision(previous_position, current_position, direction, radius, hitPoint, normal, hit_distance);

    if (!collision) return true;

    Vector damping{1, 1, 1};
    if (collision == 1) damping.x = bounce_factor;
    else if (collision == 2) damping.y = bounce_factor;
    else if (collision == 3) damping.z = bounce_factor;

    float relection_length = vlength(hitPoint - current_position);

    Vector R = vnormalize(direction - 2.0f * vdot(normal, direction) * normal) * damping;

    current_position = hitPoint + R * relection_length;
    previous_position = hitPoint - R * hit_distance;

    return false;
}

```

by calling the 2nd function to check for collision,

```
inline __device__ bool compute_box_collision(Point& previous_position, Point& current_position, const float& radius)

```

In the above code, I used the ray-plane interesection, and then use reflection of the direction to get the bounce direction, but after 500-550 timesteps, the solution deviates and becomes numerically unstable(possibly they settle at the bottom and collides continously). Is there something, I am missing here? Or am I doing something wrong?

Note: I am using simiulating 10k particles, so the solution deviation compounds by a large amount.

# Answer
You're in a very simple case here. You can simply shrink the disc by its radius to make it a point, and shrink the box by the same radius on each side to make it a smaller box. Now you can test for collisions of this point against the smaller box, and extract from those the equivalent collisions of the disc versus the original box.

Instead of doing a sphere versus box check, now you can perform a raycast against the box (or against each side as a line segment), which is significantly simpler.

When you get a hit with the raycast, you can determine the point and normal of the collision. That's the yellow dot and arrow where the red displacement vector crosses the inner yellow box.

The normal will be the same for both the raycast hit and the disc hit (the blue arrow points in the same direction as the yellow one).

To convert the collision point from the raycast to the disc (the red point of contact in the diagram above), subtract the (unit) normal times the disc radius.

Since it looks like you're using Verlet integration, what you want to do next is reflect the start and end positions across the line of collision - the yellow line segment the ray collided with.

You can compute this by expressing your begin/end positions as offsets from the yellow point where the ray hits the shrunken box. Take the dot product of that offset vector with your normal vector, and subtract twice the result times the normal vector from the offset, and add it back to the collision point. In pseudo-code it would look a bit like...

```
Vector2 ReflectAcrossCollision(Vector2 position, Vector2 collisionPoint, Vector2 collisionNormal) {
    Vector2 offset = position - collisionPoint;
    Vector2 dot = offset.x * collisionNormal.x + offset.y * collisionNormal.y;
    offset -= 2 * dot * collisionNormal;
    return collisionPoint + offset;
}

```

Note that after doing this reflection in this example, our new reflected path also crosses the box. So you'll want to repeat your collision checks with the new start and end points (disregarding places where the ray "enters" the box, and counting only places where it exits)
> 0 votes

---
Tags: collision-detection, simulations, collider
---


# Question
Title: Mirror Create Player From Client and Change Scene
I'm very new to Mirror in Unity but I have a lot of experience in Network-programing.

I'm currently trying to create a Game, where the Player's data is stored on the client, and can join different games (not concurrent) with his/her character. (Likely to Terraria)

So I can't use the automatic Player creation of the default NetworkManager class. After clicking "Join/Host" in our Main-Menu I want to change to the scene the player has played in, Hosting/joining a server and create the player on the server with the specific position...

I have tried now multiple attempts to do this, but none of mine seemed to work. Am I the even possible to have the players in different scenes with ease? Where/When should I create the Player so isn't null on the Server?

# Answer
You will need a custom NetworkManager and just handle the spawning/ setting there. But keep in mind if you trust the client with the players data, it is open to manipulation.

```
public class BasicNetwork: NetworkManager
{
    public override void OnServerAddPlayer(NetworkConnection conn)
    {
        Transform startPos = GetStartPosition();
        GameObject player = startPos != null
            ? Instantiate(playerPrefab, startPos.position, startPos.rotation)
            : Instantiate(playerPrefab);
        player.GetComponent<Player>().playerName = "Player " + Random.Range(0, 1000);
        //Gives the client authority
        NetworkServer.AddPlayerForConnection(conn, player);
    }
}

```

In the Room Example from Mirror you can find another example for passing data from the Roomplayer to the Player located in the `OnRoomServerSceneLoadedForPlayer` (which could be used if I understand your question correctly). Your RoomPlayer is like a Lobby and you could make a custom loading from your local clients data there - even if it is like a 1 Personlobby to get ready.
> 1 votes

---
Tags: unity, multiplayer, mirror-networking
---


# Question
Title: finding the angle of rotation of a 3d line
I have a line segment joining two 3D points AB, and a vector V which is normal to it.

I need to know the angle of AB in the plane described with V as the plane normal, that is: in the plane of the two vectors (AB) and (AB cross-product V)

EDIT: Much more information...

The points A and B (red dots) have x,y coordinates in the camera image, and an extrapolated depth (z) from the camera itself. The vector V (white line) is calculated from two more points with the same process. I have successfully matched rotation around the Z axis (camera view direction) so a (Unity) 3D object will track the wrist angle as it 'waves' (rotation in that single plane). Now I want to also include twisting motion defined as rotation around the wrist bone (blue ellipse attempting to represent rotation in a plane) like tipping a cup. This image is from a fixed webcam, but I would like the process to also work from a mobile phone (moving camera, with translation and rotation potentially) and one of my assumptions has been that if everything is camera relative via the screen projection, this will be automatically included.

By using a 'dumb as bricks' approach I have it working when the arm is horizontal... I can't work out how to make it work at other angles e.g. vertical:

```
            Vector3 AB = (B - A);
            return -Mathf.Atan2(AB.z, AB.y) * Mathf.Rad2Deg;

```

UPDATE3: This question now seems to have two parts:

* what can I use as a fixed reference direction when the plane can be orientated in any direction?
* how do I get an angle between that fixed reference and the line in that plane?

In searching I've come across both Rogrigues' Rotation Formula and this answer about rotating planes, but I haven't been able to work out how to apply either of them to this particular problem (I do feel like I'm missing a really obvious trick!)

Edit: My first idea is to rotate A and B so that V is aligned with the cartesian X axis and (ABxV) is aligned with Y, then use atan2(dy, dz). I have just started to look for a working solution to performing that rotation. Edit2: It's been pointed out referring to a cartesian X axis is ambiguous... I'm not sure but I think camera axis (horizontal/vertical in the image plane plus depth) might serve?

*An alternative description of the geometry is that I have a cylinder with its long axis aligned with V, and the points A,B are opposite sides of the end-cap circumference... and I need to know the rotation of the cylinder around its long axis described by AB (relative to any arbitrary consistent 0 angle).*

UPDATE: In case it breaks assumptions, my values are all measurements from a live camera, so the 'normal' vector V may not be exactly normal to AB... it should always be pretty close though (within a few degrees).

# Answer
> 1 votes
The bad news is the Hairy Ball Theorem says there's no perfect way to do this.

Whenever we try to assign one standard reference direction to a particular plane, that will always be the same for any parallel plane (equivalently, for a given normal vector V), then our mapping must have a discontinuity somewhere. There will be a critical angle where, as we smoothly rotate our plane, the reference direction suddenly snaps to a point a different way, and our AB angle from the previous frame will no longer correspond to the angle from the new reference direction.

But for something that usually moves about gradually, you can carry your reference vector from the previous frame into the next one, something like this...

```
// Member variables.
private Vector3 _referenceUp = new Vector3(0, 1, 0);

// ...
// Then later, in Update or a similar method:

Vector3 right = Vector3.Cross(_referenceUp, V).normalized;
Vector3 up = Vector3.Cross(V, right).normalized;

float angle = Mathf.Atan2(Dot(AB, up), Dot(AB, right));

// Store for next frame's use.
_referenceUp = up

```

This avoids the Hairy Ball Theorem problem, by allowing us to pick more than one reference direction for a given plane, depending on the journey we took to get there. We enforce consistency over time, rather than consistency for a given input orientation.

If you want to keep `_referenceUp` somewhat aligned with world up when feasible, you can lerp it a small distance toward (0, 1, 0) after each frame.

---
Tags: 3d, mathematics, geometry
---


# Question
Title: Why does Animator component prevent the player from facing left?
I'm making a 2D platformer with Unity. A few days ago, I was testing the game; the player could face right and left based on its moving direction and animations were playing correctly. I exited playmode because I had to assign the player position into a slot in inspector for the checkpoints. After assigning that, I entered the playmode again and surprisingly, I encountered a strange problem. The animations were working but the player was not able to face left when it was moving to the left side. I still have this problem. This is very strange to me because I didn't change anything neither from the code nor the inspector. So I believe this is a random Unity bug. After testing the game many times, I found out these:

1. If I disable Animator component, the player can flip again but obviously the animations won't play.
2. I can have both Animator and flipping working at the same time only when I check or uncheck root motion in playmode. But when I exit, the problem returns. So the previous unchecked or checked root motion will not work in the next playtest, so I can just check or uncheck it while the game is playing; otherwise it won't work.

These are the reasons why I think the Animator component prevents the player from flipping but I have no idea why this is happening because this component has nothing to do with the facing code. Thanks in advance.

This is the code I use for flipping the protagonist:

```
bool isFacingLeft;

void Update()
    {
        //Move the player.
        //Target velocity is defined in another script and is not important in this context.
        targetVelocity = new Vector2(Input.GetAxis("Horizontal") * maxSpeed, 0);

       //Flip the player's localScale.x if the move speed is greater than .01 or less than -.01.
       if (isFacingLeft == true)
       {
          transform.localScale = new Vector2(Mathf.Abs(transform.localScale.x) * -1, transform.localScale.y);
       }
       else
       {
          transform.localScale = new Vector2(Mathf.Abs(transform.localScale.x), transform.localScale.y);
       }

       if (targetVelocity != Vector2.zero)
          isFacingLeft = targetVelocity.x < 0 ? true : false;
    }

```

# Answer
> 2 votes
Usually when something like this happens it's because the keyframe animation is overriding the changes that you're trying to make in code. In this case, that could mean that the animation has keyframes for scale that are overriding the changes you apply to the scale in your code. The first thing you should do is look for and delete any scale keyframes in the animation.

---
Tags: unity, c#, animation, animator
---


# Question
Title: Where in Unity do I put a goal/objective detection script?
How do I make a Goal system in unity that must be completed before the level can be passed.

Goals may be: pick up a block, get the red flag, go to a certain position.

Here is sample code -

```
class Goal : Monobehaviour
{
 public event System.Action completed;
 protected void GoalCompleted()
 {
    if(completed!=null)
       completed();
 }
}

class CollectCoins : Goal
{
   ...
}
...

```

But I don't know where to put the script or what to do with it ?

# Answer
It's not unusual in Unity to have an invisible "Manager" game object in the scene which holds any such scripts which can not be considered a behavior of any particular gameObject appearing in the game. This allows such manager-scripts to use Unity events like `Update`.

But when your manager doesn't need any Unity events and you don't need the luxury of being able to see and change its values in the Unity inspector, then you can also implement it as a plain old C# class not inheriting from MonoBehaviour. But because Unity does not have a "main" method as a central entry point into the application (at least not one you can see), you need to instantiate these classes from other MonoBehaviours and store their instances somewhere (within MonoBehaviours or in `static` variables).
> 1 votes

---
Tags: unity
---


# Question
Title: Rotation on one object affects all others
I am making a game using LWJGL. I have encountered a problem with rotation, looked it up, found a solution, and added it, but it doesn't entirely work.

In the code below, the bottom section is rotating well, but when the top one is rotating the other direction, the same direction, or anything else relating to rotation, the bottom sprite seems to move with it, or cancel out the rotation altogether.

```
            GL11.glPushMatrix();
            GL11.glTranslatef(0.0f, 0.0f, -300f);
            GL11.glRotatef(i+=0.5f, 0.0f, 0.0f, 1.0f );
            drawStar2(0, 0, 0);
            GL11.glLoadIdentity();
            GL11.glPopMatrix();

            GL11.glLoadIdentity();

            GL11.glPushMatrix();
            GL11.glTranslatef(0.0f, 50.0f, -300f);
            GL11.glRotatef(i-=0.5f, 0.0f, 0.0f, 1.0f);
            drawStar0(0, 0, 0);
            GL11.glLoadIdentity();
            GL11.glPopMatrix();

```

How can I make the rotation of the object in the code on the bottom insensitive to the rotation of the object in the code at the top?

I am also using Slick-Utils, if this is also causing a problem I haven't heard of.

# Answer
> 0 votes
Your matrix operations look okay. (You don't need to call `glLoadIdentity` at all, but it won't do any harm.) The problem looks to be here:

```
GL11.glRotatef(i+=0.5f, 0.0f, 0.0f, 1.0f );
...
GL11.glRotatef(i-=0.5f, 0.0f, 0.0f, 1.0f);

```

If you want independently spinning objects, you must give them separate fields/variables to store each one's current rotation.

```
// in your class or whatever
private float star2Rot;
private float star0Rot;

...

GL11.glRotatef(star2Rot += 0.5f, 0.0f, 0.0f, 1.0f );
drawStar2(0, 0, 0);

...

GL11.glRotatef(star0Rot -= 0.5f, 0.0f, 0.0f, 1.0f);
drawStar0(0, 0, 0);

```

---

Some further advice: When animating rotations, it's a good idea to remove multiples of a full rotation to avoid losing floating-point precision with unnecessarily large values.

That is, put this sort of thing somewhere (it doesn't matter where as long as it gets run while the animation is running):

```
if (star2Rot >= 360.0) {
  star2Rot -= 360.0;
}

```

This may help avoid glitches when your app is running for a long time.

---
Tags: java, rotation, lwjgl
---


# Question
Title: How can I create a GraphQL query with nested {}
I am using GraphQL plugin from https://github.com/Gazuntype/graphQL-client-unity. I have a long query from which I am parsing it to JSON to get individual values. It all works fine. Unfortunately the problem appears when using SetArgs() in a nested {}. For example, here is my query:

```
{
  System(ID: "1") {
    model {
      type {
        SystemModel{
          CreationModel(isModelCreated: true) {
          name
          }
         }
        }
     }
   }
}

```

And here is my Unity code:

```
public async void GetSystemID () {
        GraphApi.Query query = Graph.GetQueryByName ("System", GraphApi.Query.Type.Query);
        query.SetArgs (new { ID= "1", isModelCreated = true }); //How do I provide isModelCreated here

        UnityWebRequest request = await NestedQuery.Post (query);
        JSONNode itemsData = JSON.Parse (request.downloadHandler.text);
        var parseJSON = JSON.Parse (request.downloadHandler.text);

    }

```

So in SetArgs, I have to provide a list of arguments, for example ID: "1" and isModelCreated: true. I am able to provide the first argument, but unfortunately the nested query's argument - isModelCreated is not getting recognized as it treats it as:

```
System(ID: "1", isModelCreated: true) {}

```

Do I have to add multiple {} so that it comes in right order or is there a cleaner way to achieve this?

# Answer
> 0 votes
Based on the example in the docs, it looks like you want something like:

```
query.SetArgs (new { ID= "1",
    model = new {
        type = new {
            SystemModel = new {
                CreationModel = new {
                    isModelCreated = true
                }
            }
        }
    }
});

```

If this didn't work for you, you should edit your question to include the exact code you used and the exact error message, unwanted output, or other problem symptoms you observed.

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


# Question
Title: How to develop a GameMaker game for both desktop and mobile
For a few months I have been creating a game using GameMaker Studio 2 Desktop.

It turns out that I would like to launch it also for cell phones, and for that I bought GameMaker Studio 2 Mobile.

That's when my doubt arises.

In GameMaker Studio 2 Mobile, you have the option to open the projects made in GameMaker Studio 2 Desktop, and its interface is the same as in GameMaker Studio 2 Desktop.

**There are 2 shortcuts on my computer:**

Now I don't know if GameMaker Studio 2 is a new program, or works only as a license that allows me to launch the game on another platform (like a plugin extension).

I remember that in GameMaker Studio 1.4, there was just one version of the editing software, and each version of the game (desktop or mobile) had its own code.

I basically had to copy the game project and edit the copy with its equivalent features.

I remember that one of the adaptations is at the time of clicking on the screen, because on the cell phone you don't use `mouse_x` or `mouse_y`.

**What I would like to know is if I will need to adapt the code for this mobile version or, when exporting the game for the mobile platform, will the code be adapted automatically?**

---

**Before coming here I looked for solutions in these links:**

https://www.reddit.com/r/gamemaker/comments/dgmkld/cross\_platform/

https://www.reddit.com/r/gamemaker/comments/5mn0p5/crossplatform\_online\_multiplayer\_with\_or\_without/

https://www.reddit.com/r/gamemaker/comments/5g2ej2/cross\_platform/

---

At one point I realized that maybe I was using the wrong term in the search, because the results I was finding revealed different things than what I was looking for: stuff about whether desktop and mobile players can play together, which is not useful for me since the game I am producing is not online.

# Answer
Going to the official engine forum I got some clarification.

Below I will test a summary of all the recommendations, tips and clarifications that have been presented to me.

The user **curato**, informed me that the mouse click commands are automatically replaced by the touch command, something that did not happen in version 1.4.

I tested it and it really does happen, no code changes are necessary in this sense.

**Important points:**

* Take into account that when using the cell phone, interruptions are more common (calls, battery discharging). For this it is interesting that the game has an automatic saving system and that saves with a certain frequency.
* Simplification of graphics, due to the lower graphic potential of cell phones in relation to computers (this is not the case with my game).
* Add keyboard commands in some way (if necessary), usually add a clickable button on the screen.
* How the game behaves in different resolutions.

The bad part is that exporting the apk requires some design changes.

**So, every time you update the game:**

* You will have to make the modifications in the version you started making the game (in my case for the computer)
* Copy the project
* Make adaptations for the mobile version (buttons, back button compatibility, resizing some text or sprite)
* After that, export.

Not to mention the SDK version issues, the app build, cell phone models it will be compatible, etc.

This can be even more problematic if your game, in the mobile version, has two versions (free and paid). Because everything that is limited in this free version, you will have to redo (assuming that the paid version for mobile is identical to the computer version).

An alternative would be to program each version individually. I don't think this is feasible, the chance of something going different is great. I don't see much how to escape copying and pasting.

Thanks to: kburkhart84, curato and Yal

**Link to my forum post:**

https://forum.yoyogames.com/index.php?threads/how-to-develop-a-gamemaker-game-for-both-desktop-and-mobile.83426/#post-497667
> 0 votes

---
Tags: game-maker, mobile, cross-platform
---


# Question
Title: How do I find an object by type and name, in Unity, using C#?
I know that in Unity you can find an object of a certain type, using `myObject = Object.FindObjectsOfType<MyType>()`, but that only returns the first object in the scene it finds of that type.

How do I make it find the object of a certain type **and** with a certain name?

# Answer
> 1 votes
There are different ways you would go about this depending on your particular circumstances.

Ultimately, you can not search for all active game objects based off both *type* and *name*, at the same time. You can easily search for all active game objects based off *type*, and search the resulting list for all game objects of *type* that use *name*. You also want to consider whether searching for game objects by *tag* would be more appropriate for your requirements.

Below, I have provided two methods for searching for game objects by *type* and *name*. One can be easily used on the fly, the other is provided as a standalone method, and can be used more dynamically.

---

### Find all GameObject(s) by *type* and *name*

To complete the search, simply search for objects based off *type*, and search through the resulting list for objects that match the *name*.

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

...

    TypeToLookFor[] firstList = GameObject.FindObjectsOfType<TypeToLookFor>();
    List<Object> finalList = new List<Object>();
    string nameToLookFor = "name of game object";

    for(var i = 0; i < firstList.Length; i++)
    {
        if(firstList[i].gameObject.name == nameToLookFor)
        {
            finalList.Add(firstList[i]);
        }
    }

```

Note that you ask to "find objects", and I interpret that to literally mean you wish to have a resulting `Object` array. Any type you can look for, in this way, will be compatible with `Object`.

You could also retain the type you originally search for, in this way. In the above example, we could change `List<Object> finalList` to `List<TypeToLookFor>` with no problems. We could also use `List<GameObject> finalList`, and find the actual `gameObject` reference with `finalList.Add(basicAIList[i].gameObject`, if we wanted a list of game objects.

---

Consider that you may want to search like this multiple times. It might be more useful to have a standalone method that can perform the required search, and take in custom types and names.

```
...

public List<Object> FindObjectsOfTypeAndName<T>(string name) where T : MonoBehaviour
{
    MonoBehaviour[] firstList = GameObject.FindObjectsOfType<T>();
    List<Object> finalList = new List<Object>();

    for(var i = 0; i < firstList.Length; i++)
    {
        if(firstList[i].name == name)
        {
            finalList.Add(firstList[i]);
        }
    }

    return finalList;
}

```

We can then call this method as `FindObjectsOfTypeAndName<TypeToLookFor>("name to look for")`.

I assume that we will always be looking for types that inherit from `MonoBehaviour`, but this will usually be the case, with custom types. If you need to change this, ensure that you also change the type of `MonoBehaviour[] firstList`.

# Answer
> 4 votes
If you know the name and type of object (as in they definitely exist), then it's a simple line of code.

For example, let's say you have a Canvas and it's called MyCanvas.

```
Canvas myCanvas = GameObject.Find("MyCanvas").GetComponent<Canvas>();

```

Or more generally:

*Type* *varName* = GameObject.Find("*ComponentName*").GetComponent\<*Type*\>();

This assumes that you do only have one object of that name, but provides a nice clean piece of code that does what is required for many use cases.

# Answer
> -4 votes
You can use GameObject.FindObjectsWithTag("tag") function instead

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


# Question
Title: Make the texture array node work with cubemaps?
I am working on a procedural interior mapping shader in Unity's Shader Graph. Ideally, I'd like to feed it a set of cubemaps it can pick from semi-randomly.

However, it seems that by default the texture array asset one can provide to a graph does not support reading cubemaps.

Does anyone have a way to use this, or perhaps a clever custom node or alternate texture mapping, so that I can read a number of cubemaps into the shader semi-randomly? Preferably an arbitrary number, but even a fixed number would be somewhat of an improvement.

# Answer
> 1 votes
We can use the Custom Function Node to work around limitations of the existing node types.

First, we'll make a new text file somewhere in our Assets folder. I called mine "CubeMapArray.cginc". Inside we can put just these nine lines of code:

```
TEXTURECUBE_ARRAY(_CubeArray);

void sample_cube_array_float(SamplerState ss, float3 coord3, float index, out float4 result) {
    result = SAMPLE_TEXTURECUBE_ARRAY(_CubeArray, ss, coord3, index);
}

void sample_cube_array_half(SamplerState ss, half3 coord3, half index, out half4 result) {
    result = SAMPLE_TEXTURECUBE_ARRAY(_CubeArray, ss, coord3, index);
}

```

You can see this defines a uniform variable `_CubeArray` that represents an array of cubemaps. Then it defines two versions of a function to sample that array - one at full float precision, and one at half precision. (I looked up the macros to use from this file)

Inside the shader graph editor, we'll create a new Custom Function Node and configure it like so:

Now unfortunately since we had to smuggle in our cubemap array texture via a uniform declared in code, we can't just assign the maps through the inspector. So we'll use a short C# script to copy our cubemaps into one texture array and assign that:

```
public class CubeMapArrayTest : MonoBehaviour
{
    public Cubemap[] maps;

    CubemapArray _array;
    Material _material;

    private void Start() {
        if (!SystemInfo.supportsCubemapArrayTextures) {
            Debug.LogError("System does not support cubemap array textures - this will not work!");
            return;
        }

        _array = new CubemapArray(maps[0].width, maps.Length, maps[0].format, true);

        for (int i = 0; i < maps.Length; i++)
            for (int j = 0; j < 6; j++)
                Graphics.CopyTexture(maps[i], j, _array, 6*i+j);

        _material = GetComponent<Renderer>().material;

        _material.SetTexture("_CubeArray", _array);
    }

    private void OnDestroy() {
        if (_material != null) {
            Destroy(_material);
            DestroyImmediate(_array);
        }
    }
}

```

On my machine this displays an error and warning in the console:

> Shader error in 'hidden/preview/CustomFunction\_DD7E970E': TextureCubeArray textures aren't supported on this target at Assets/ShaderEffects/CubeMapArray.cginc(1) (on d3d11)
>
> ⚠ Shader warning in 'hidden/preview/CustomFunction\_DD7E970E': 'TransformObjectToWorld': implicit truncation of vector type at line 85 (on d3d11)

But the shader still works correctly anyway. I'd love some insight into why that is and how to resolve or suppress those messages for peace of mind, but they don't seem to be an obstacle to solving the problem at least.

---

**Update:** Shader Graph version 10 accepts the above without complaint if it was imported from a Unity Package made in an earlier version (applying some invisible compatibility mode behind the scenes). But if you're creating this from scratch in a new shader graph in the latest version, you'll need to modify the code slightly:

```
TEXTURECUBE_ARRAY(_CubeArray);

void sample_cube_array_float(UnitySamplerState ss, float3 coord3, float index, out float4 result) {
    result = SAMPLE_TEXTURECUBE_ARRAY(_CubeArray, ss.samplerstate, coord3, index);
}

void sample_cube_array_half(UnitySamplerState ss, half3 coord3, half index, out half4 result) {
    result = SAMPLE_TEXTURECUBE_ARRAY(_CubeArray, ss.samplerstate, coord3, index);
}

```

You'll still get console errors about cube map arrays being unsupported when opening the shader graph window, but it works in play mode, even in URP (tested in 2020.3.31f).

---
Tags: unity, cubemap, unity-shader-graph
---


# Question
Title: My Earthbound-like Movement Script works in Unity Gameview, but runs differently in Gamebuild
First programming question I've ever made in my short journey. I'm trying to create a script which moves members of your party in a line behind you (think Chronotrigger or Earthbound). Here's a clip of what I want it to look like.

**Problem:** Everything looks fine in the Game window when I play, but when I build the game to test, the characters begin to stack one on top of each other. I assume it has something to do with `Update()` frames dramatically increasing the frequency with which I enqueue the positions of the leading character (although I'm not experienced enough to say for sure, clarification on this would be helpful).

* I've tried increasing the offset, but this solution is variable depending on the players computer fps so that wont work.
* I've tried running both scripts in `FixedUpdate()` but a lot of my other systems run on `Update()` and so everything stutters.
* I've tried enqueue'ing from an `IEnumerator` and waiting for .1 second between each enqueue but that stutters as well..

**What I'm doing:** The leading character has a script called `PlayerTrail` which creates a `Queue` of `Vector3`s. In `Update` the game object's `transform.position` is enqueued. The following character has a script called `PlayerFollower` which looks at the Queue and `Vector3.MoveTowards` the position, then dequeues that position and repeats. Each character only looks at the trail of the character in front of it.

Everything seemingly works fine and well in the Unity program, this issue only arises once I build the actual game.

**Code Supplied Bellow:**

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

public class PlayerTrail : MonoBehaviour
{
    public Queue<Vector3> LeaderTrail;
    public Vector3 LastMovement;

    private void Start()
    {
        LeaderTrail = new Queue<Vector3>();
    }

    private void  Update()
    {
        if (this.transform.position != LastMovement)
        {
            LastMovement = transform.position;
            LeaderTrail.Enqueue(this.transform.position);
        }

    }
}

```

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

public class PlayerFollower : MonoBehaviour
{
    public GameObject leaderObject;
    public int Offset;
    public int moveSpeed;

    private PlayerTrail leaderTrail;
    private Animator animator;

    void Start()
    {
        animator = gameObject.GetComponent<Animator>();
        leaderTrail = leaderObject.GetComponent<PlayerTrail>();
    }

    void Update()
    {
        if (leaderTrail.LeaderTrail.Count < Offset)
        {
                animator.SetBool("isMoving", false);
                return;
        }
        else
        {
            Vector3 direction = (leaderTrail.LeaderTrail.Peek() - transform.position).normalized;
            this.transform.position = Vector3.MoveTowards(this.transform.position, leaderTrail.LeaderTrail.Peek(), moveSpeed * Time.deltaTime);

            animator.SetBool("isMoving", true);
            animator.SetFloat("moveX", direction.x);
            animator.SetFloat("moveY", direction.y);

            Debug.DrawRay(this.transform.position, direction);

            leaderTrail.LeaderTrail.Dequeue();
        }
    }
}

```

# Answer
Instead of a counter of how many items you have in your queue, you should only move them towards the next part when they are further than a certain distance. Removed the animator for testing purpose. They try now to catch up to you as well in case you do not move or move faster than they can. You want as well to only dequeue the position once you reached it (or when you are close to it) to not stop moving towards it in case the player moves faster or they get stuck for a second (else the distance might get bigger between the followers)

Last you wrote that the character only looks at the character in front, but from your question it sounds like that only the leading character has the playertrail script. You should rather place a playertrail on each character you want to follow, means that if you have 4 Characters, you have 3 playertrail scripts (on 1, 2, 3) and 3x Followerscript (on 2, 3, 4). This way you have better control over the distance between the characters (this might be important if the size of characters is different). And the character does not need to know how many characters are in total to calculate different offsets.

```
public class PlayerFollower: MonoBehaviour
{
    public GameObject leaderObject;
    public float keepDistance;
    public int moveSpeed;
    private PlayerTrail leaderTrail;

    void Start()
    {
        leaderTrail = leaderObject.GetComponent<PlayerTrail>();
    }

    void Update()
    {
        if (leaderTrail.LeaderTrail.Count >= 1) {
            if (Vector3.Distance(transform.position, leaderTrail.LeaderTrail.Peek()) >= keepDistance)
            {
                Vector3 direction = (leaderTrail.LeaderTrail.Peek() - transform.position).normalized;
                this.transform.position = Vector3.MoveTowards(this.transform.position, leaderTrail.LeaderTrail.Peek(),
                    moveSpeed * Time.deltaTime);
                Debug.DrawRay(this.transform.position, direction);
            }
            if (Vector3.Distance(transform.position, leaderTrail.LeaderTrail.Peek()) < keepDistance)
            {
                leaderTrail.LeaderTrail.Dequeue();
            }
        }
    }
}

```
> 1 votes

---
Tags: unity, c#, 2d, movement, transformation
---


# Question
Title: Can't connect to Steam using Blueprints in UE4.25
I'm following this tutorial by Unreal Engine itself, but I don't have a Steam overlay popup like I'm supposed to, (according to the tutorial.) And actually a lot of people have a similar issues like this.

What I have done / tried is:

* Enabling Steam overlay (in Steam settings, but it was already enabled)
* I've already edited the DefaultEngine config file
* I'm playing my game (in Unreal Engine) from the Standalone Game option
* Searching this up, re-watching tutorial, looking at tutorial's comments
* Enabled the Online Subsystem Steam plugin

And I still don't know what the issue is. I've also looked at this thread by the Unreal Engine community, but it didn't help that much.

# Answer
For me it worked when I packaged the game. You should try that.
> 0 votes

---
Tags: multiplayer, unreal-4, unreal, blueprints, steam
---


# Question
Title: Controlling roll rotation when travelling along bezier curves
I am currently working on a curve implementation for use in Unity which includes an editor:

The aim is to get an object to follow the path represented by the curve at a constant velocity. Currently you can place nodes in the curve and modify the weights of each node via handles to control the curve segments between nodes. The curve implementation is a standard Bezier curve.

It works as described except that sometimes the rotation of the object along the path is not great. For instance doing a vertical loop can cause the object to suddenly flip over at certain points. I am currently setting the rotation of the object as follows:

```
transform.LookAt(bezier(waypoints, handles, lookAhead));

```

This is computing the point in the curve slightly ahead of the current point and setting the object to "look at" that point. The pitch and yaw of the object will therefore be correct but the roll cannot be easily controlled.

I am currently trying to implement a way to control the roll as the object travels along the path but my maths skills are failing me once again. In the editor I am thinking of placing "roll" nodes along the path which represent the desired roll angle of the object when it reaches that node and interpolating between these nodes for the points in between. My questions are as follows:

1. How would you determine the yaw and pitch manually at each point? My objects are airplanes so they will always be facing "forward".
2. How would you know the direction to turn towards to get to the next nodes roll angle? It could be anticlockwise or clockwise I assume. Would I need to also add a control to say which way to turn?
3. How would I determine what is "up" to orientate myself when controlling the roll angle of the objects along the path?

EDIT:

Example: https://www.youtube.com/watch?v=0BHGoKOIQa0&feature=youtu.be

The linked youtube video shows the problem I am experiencing with using

```
 transform.LookAt(bezier(waypoints, handles, lookAhead));

```

alone to control the rotation Quaternion. Watch the plane object rotate when looping vertically. The box sticking out is on the top of the plane object.

When the object reaches the point when it should be "upside down" in the loop it spins quickly to be the facing upwards again. If I can make it so that the up vector of the object along the path follows the "natural" rotation along the curve I can then apply Quaternion control points to properly control rotation. Sorry if this is not entirely clear, I don't know the proper terminology for a lot of this stuff.

# Answer
> 2 votes
### Edit: New Solution

Edit: I have found a solution that works for me (as mentioned in the comments):

Use an iterative approach. Start with a reference frame at the start of the bezier. Then, for each new point, use the orientation of the previous frame to orient the next one:

```
forwardOnCurve = DeriveCubic(p[0], p[1], p[2], p[3], Mathf.Clamp01(t)).normalized;
normalOnCurve = Vector3.Cross(forwardOnCurve, Vector3.Cross(normalOnCurve, forwardOnCurve)).normalized;

```

As you can see, I calculate the right vector from the new forwards vector and the previous normal. Then I calculate the new normal.

The problem with this approach is that while it is locally continuous, it ignores the orientation of all control points but the first.

To solve this, I rotate all points along the forwards vector between each control point, linearly interpolating the error angle to be correctly oriented at the next control point. Also, I treat each segment individually, always starting correctly oriented at each control point.

What should be the starting normal at each control point? Well you want to decide that for yourself, right? I use the control handles in addition to a normal for each control point. This way, the user can rotate the bezier at each control point to point the way they want.

The correction looks something like this:

```
segmentLength += Vector3.Distance(previousPointOnCurve, p[3]);
lineLength += segmentLength;

forwardOnCurve = DeriveCubic(p[0], p[1], p[2], p[3], 1).normalized;
normalOnCurve = Vector3.Cross(forwardOnCurve, Vector3.Cross(normalOnCurve, forwardOnCurve)).normalized;
float angleError = Vector3.SignedAngle(normalOnCurve, _normals[segment + 1], forwardOnCurve);

// Iterate over evenly spaced points in this segment, and gradually correct angle error
float tStep = spacing / segmentLength;
float tStart = Vector3.Distance(esp[startIndex].position, p[0]) / segmentLength;
for (int i = startIndex; i < endIndexExclusive; ++i)
{
    float t_ = (i - startIndex) * tStep + tStart;
    // TODO: make weight non-linear, depending on handle lengths
    float correction = t_ * angleError;
    esp[i].normal = Quaternion.AngleAxis(correction, esp[i].forward) * esp[i].normal;
}

```

The full code is this: https://pastebin.com/t5LFLhL9

This can also be found in context in my unity package called "MB Road System"

### Screenshot

As you can see, this works vertically too now. The only problem is that you have to calculate the entire curve, you can't just sample the normal of the curve at any point along the bezier without calculating the entire array of points. However, since I assume your curve is not updated during run-time, this shouldn't be a problem. I personally recommend updating these points asynchronously while storing the current array in a variable, so that it can update at a slower frequency than the main loop. This is, I think, a good compromise.

### My Old solution

I'm looking into this as well. I only have a solution that works for beziers that are somewhat horizontal, the closer they get to vertical, the less it works.

I'm essentially converting the local up vector into an angle, interpolating that, and turning it back into an up vector.

Conversion from normal to angle:

You use the vector along the bezier (`p[t + 1] - p[t]`) and take the cross product with the worlds up vector. That gives you the right vector relative to the path. Then you take the cross product between that and the local forward vector, and that gives you a vector that points 90° to the bezier, upwards. You can then measure the angle of the transforms up vector to that, and you should get the local roll.

This roll is then interpolated along the path.

Generating a normal from the local angle works similarly.

This is the code that I wrote:

```
public static float AngleFromNormal(Vector3 forward, Vector3 normal)
{
    Vector3 right = Vector3.Cross(Vector3.up, forward).normalized;
    Vector3 up = Vector3.Cross(forward, right).normalized;
    return Vector3.SignedAngle(normal, up, forward);
}

public static Vector3 NormalFromAngle(Vector3 forward, float angle)
{
    Vector3 right = Vector3.Cross(Vector3.up, forward).normalized;
    Vector3 up = Vector3.Cross(forward, right).normalized;
    return Quaternion.AngleAxis(-angle, forward) * up;
}

```

Now, as I said, this only works if the path is somewhat horizontal, as it relies on the cross product of the forward vector and `Vector3.up` to return a vector that is long enough to avoid floating point error or division by `0` (when the vector is normalized)

I personally used it for a RoadSystem that lets you edit roads, connect them to intersections, and it also generates a graph for pathfinding, and can then generate a line from your position to the goal. In that use case, this approach works well enough, as roads don't really go up vertically.

# Answer
> -1 votes
You could just stare the roll value before each

```
transform.LookAt(bezier(waypoints, handles, lookAhead));

```

And then just adjust the roll value as you want in a separate algorithm and then reassign it to the airplane's roll. The Euler roll 0 is always straight and 360 = 0.

So the questions drictly:

1. Use a quaternion and do a slerp to rotate to that orientation.
2. Roll values loop at 360 so 270 = -90. You could just test if the value is larger than 180 then the other direction is faster and then do a lerp or some control algorithm.
3. Roll=0 is always up.

If this did not help pleas clarify what is unclear an I will clarify.

EDIT: One way to work around this is to store the rotation and whenever the yaw has a difference (remember the 360 looping so 5 to 355 is only 10) from the previous frame is greater than 170 (the yaw will flip 180 when the flip ocur) degreas just add 180 to the roll value.

---
Tags: unity, mathematics, movement, vector, beziers
---


# Question
Title: Which method for creating a Loot chance, int or float?
Which of these two methods for creating a loot chance is easier to maintain and update?

* The first method I'm thinking of uses an `int` going from 0 to 100000 (0,000 to 100,000).
* The second is almost the same but using a `float` value going from 0.000f to 100.000f.

Both will pass to a `Random.Next`. If the value of the Random is less than the chance to drop value, the item will drop.

For efficiency and maintenance, is one preferred over the other?

# Answer
Personally I would pick `int` over `float` for the readability. You will never hit any performance issues with just creating and comparing an int or float.

My personal loot system would look similar to this, if multiple items can drop, you would roll multiple times

First you would do a roll what kind of rarity you hit. This adds up to 100%. (if 2 items can drop at once, means in ~ 1 out of 9 times you get no item all and once every 10.000 enemies you would get 2 orange items at once)

nothing(32) \< gray(25) \< green(25) \< blue(15) \< purple(2) \< orange(1)

After that you would pull up the loot table of the monster. If you hit a group, you get with 100% chance the item from that group, now we determinate what item we get. Example for a gray group

* sock with hole (1)
* dried cheese (1)
* useless rock (3)
* rotten wood (3)
* shiny piece of glass (2)

The numbers would mean how likely you get it. You can add them all together (in this case 10), roll a number from 1 to 10 and get the corresponding item. In % it would mean you have 10% for the sock or 30% chance for the rock in case you hit the gray reward box (that is an effective chance for the sock of 2.5%). But the great benefit of it is, you can just add as many items in a group as you want and dont need to care much about how many there are, you just have to determinate how much more likely one item is to drop compared to another. If they are all at 1, you get them all with the same chance.

If you have loot deminish system, you can still use the same system. You would populate a list once and remove one of the item chances afterwards. So if you get a rock, there would be still 2 left. But if you get the sock, before the drop gets refreshed, you can't get a second sock.

And last, if your drop can drop quest items and those are countable (collect 15 spider legs), let them always drop. Nothing is more frustrating than killing 100 wolves and still wonder why they are all blind and have no eyes for collecting.
> 2 votes

# Answer
We are talking C#, so I'll assume .NET. Thus you would either use `System.Random.Next` which works with integers, or `System.Random.NextDouble` which - as the name suggest - works with double. There no method in `System.Random` that uses `float`.

---

From `System.Random` it is preferible to use `System.Random.NextDouble`. This is how it works: first generate a pseudo random number between `0` and `Int32.MaxValue` (with uniform distribution), then convert it to `double`, and scale it down to the range between `0.0` and `1.0`.

Contrast with `System.Random.Next`, which will do all those steps and then scale and shift the result to the requested range and cast back to `int`. If performance is your concern, then know that `System.Random.Next` has extra steps.

Thus, use `System.Random.NextDouble` and represent chances use values between `0.0` and `1.0`. *For example 25% is `0.25`, which I'd argue is both easy to read and correct.*

---

As per maintenance, declare a method that wraps whatever you choose to use (`System.Random.NextDouble` for example), and takes whatever is more convenient to you. Doing this, it is easier to replace `System.Random` with something else if the need arrives. In fact, you probably want the method to take a chance value and return `bool`.

As per representing the chance, both `int` and `float` are 32 bits, so no memory saved there… I'd say prefer a non-integer type, because your chances are not integer. There could, perhaps be a difference in performance if you are parsing the values from text, but unlikely to be relevant below the millions of values (profile if it is a concern).

---

Can `System.Random` be a bottle neck anyway? Yes. It happened to me while testing some voxel renderer and decided to simply pick each voxel at random (not what you want in practice), making each voxel a call to `System.Random`. Why did I do that? Because I didn't have any world generator code in place at the time, and wanted to test the renderer. It ran slow, and profiler pointed to `System.Random`. *Reminder: use a profiler.* So I replaced `System.Random` with a custom solution (which I suppose didn't have as good statistical properties - I never tested - but was faster and good enough that I didn't see patterns at a glance).
> 4 votes

---
Tags: c#, performance
---


title: I can't add script in unity

text:
# Question
Title: I can't add script in unity
I'm a beginner in unity so I got this problem. Here is the script:

```
using UnityEngine;
using System.Collections;
public class Playercontrol: MonoBehaviour {
    public float maxspeed = 10f;
    bool facingRight = true;

    void FixedUpdate () {
        float move = Input.GetAxis ("Horizontal");

        GetComponent<Rigidbody2D>().velocity
             = new Vector2(move * maxspeed, GetComponent<Rigidbody2D>().velocity.y);

        if (move > 0 && !facingRight){
            Flip ();
        } else if (move < 0 && facingRight) {
            Flip ();
        }
    }

    void Flip() {
        facingRight = !facingRight;
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

```

I don't know why but it keep saying that Can't add script component 'Player control' because the script class cannot be found.Make sure that there no compile errors and that the file name and class name match.

# Answer
Check the file name of the script and make sure it's the same as the class name. I've had this problem before after renaming a script through the editor.
> 2 votes

# Answer
Old question, but I solved this problem using the Help menu and then Reset Packages to defaults.
> 1 votes

# Answer
You either have a compile error in this script, or you have one in a different script. If this is the first time you're trying to use this script, the entire solution needs to compile before Unity knows about this new class you're introducing.

Locate your error and correct it before trying to add this script. It could be a compile error or something like a name mismatch like SanSolo suggests.
> 0 votes

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


# Question
Title: How can I make the transform to stop slowly smooth before the next waypoint?
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Waypoints : MonoBehaviour
{
    public GameObject[] waypoints;

    public GameObject player;
    public float speed;
    public float distanceFromPoint;
    public float waitTimeAtPoint;
    public LookAtCamera lookAtCam;

    private Transform currentWaypoint;

    private void Start()
    {
        // maybe refresh here?
        //RefreshWaypoints();
        StartCoroutine(RunWaypoints());
    }

    private IEnumerator RunWaypoints()
    {
        // Sanity check in case the waypoint array has length == 0
        if (waypoints.Length == 0)
        {
            Debug.Log("No Waypoints!", this);
            yield break;
        }

        // this looks dnagerous but as long as you yield somewhere it's fine ;)
        while (true)
        {
            // maybe refresh here?
            //RefreshWaypoints();

            // Sanity check in case the waypoint array was set to length == 0 between states
            if (waypoints.Length == 0)
            {
                Debug.Log("No Waypoints!", this);
                yield break;
            }

            // first select the next waypoint
            // Note that you might get the exact same waypoint again you currently had
            // this will throw two errors in Unity:
            // - Look rotation viewing vector is zero
            // - and transform.position assign attempt for 'Main Camera' is not valid. Input position is { NaN, NaN, NaN }.
            //
            // so to avoid that rather use this (not optimal) while loop
            // ofcourse while is never good but the odds that you will
            // always get the same value over a longer time are quite low
            //
            // in case of doubt you could still add a yield return null
            // than your camera just waits some frames longer until it gets a new waypoint
            Transform newWaypoint = waypoints[Random.Range(0, waypoints.Length)].transform;
            while (newWaypoint == currentWaypoint)
            {
                newWaypoint = waypoints[Random.Range(0, waypoints.Length)].transform;
            }
            currentWaypoint = newWaypoint;

            // tell camera to rotate and wait until it is finished in one line!
            yield return lookAtCam.RotateToTarget(currentWaypoint);

            // move and wait until in correct position in one line!
            yield return MoveToTarget(currentWaypoint);

            yield return new WaitForSeconds(waitTimeAtPoint);
        }
    }

    private IEnumerator MoveToTarget(Transform currentWaypoint)
    {
        var currentPosition = transform.position;
        var duration = Vector3.Distance(currentWaypoint.position, transform.position) / speed;
        var passedTime = 0.0f;

        do
        {
            // for easing see last section below
            var lerpFactor = passedTime / duration;

            transform.position = Vector3.Lerp(currentPosition, currentWaypoint.position, lerpFactor);

            passedTime += Time.deltaTime;
            yield return null;
        } while (passedTime <= duration);

        // to be sure to have the exact position in the end set it fixed
        transform.position = new Vector3(currentWaypoint.position.x - distanceFromPoint,
            currentWaypoint.position.y, currentWaypoint.position.z);
    }

    public void RefreshWaypoints()
    {
        waypoints = GameObject.FindGameObjectsWithTag("Target");
    }
}

```

I tried this :

```
transform.position = new Vector3(currentWaypoint.position.x - distanceFromPoint,
            currentWaypoint.position.y, currentWaypoint.position.z);

```

Before it was just :

```
transform.position = currentWaypoint.position;

```

but in both cases it's just moving the transform to the currentWaypoint position. it's good if I want it to be on the exact waypoint position.

but I want also to be able with a float variable to control the slow down speed before the waypoint/s. for example to set a distance like 10 and then slow down speed for example 3 so if the speed is 10 then start slowdown from distance 10 to speed 3 and then slowly smooth stop and wait at the waypoint.

but the idea is to add a slow down effect when getting closer to the next waypoint. it could be nice to add also some speed up effect from the current waypoint to the next waypoint. speed up and slow down.

This script is for the camera. Both scripts sits on the camera :

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

public class LookAtCamera : MonoBehaviour
{
    // Values that will be set in the Inspector
    public float RotationSpeed;

    public IEnumerator RotateToTarget(Transform target)
    {
        var timePassed = 0f;

        var targetDirection = (target.position - transform.position).normalized;

        var targetRotation = Quaternion.LookRotation(targetDirection);
        var currentRotation = transform.rotation;

        var duration = Vector3.Angle(targetDirection, transform.forward) / RotationSpeed;

        do
        {
            // for easing see last section below
            var lerpFactor = timePassed / duration;

            transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, lerpFactor);

            timePassed += Time.deltaTime;

            yield return null;
        } while (timePassed <= duration);

        // to be sure you have the corrcet rotation in the end set it fixed
        transform.rotation = targetRotation;
    }
}

```

The main goal is to make a fly camera around the scenes that will make some stuff at each waypoint. In some waypoint the camera will wait X seconds in another waypoint the camera will not wait at all and in another waypoint the camera will make a rotate around the waypoint object to show the whole waypoint and so on thing like that.

# Answer
> 0 votes
You're moving the object using `Vector3.Lerp()`. When you move with linear interpolation (lerp), the speed is constant. To add speed up at the beginning or slow down at the end, you'd need to use *easing*.

Ironically the source you obtained this code from seems to have left a comment referencing easing but then forgotten to actually include the easing section.

There are many ways to implement easing. One way is to use easing functions. You can search the web to find free libraries of easing functions for Unity. You'd generally use them something like this:

```
var t = passedTime / duration;
var lerpFactor = EasingLibrary.EaseInOutCubic(t);
transform.position = Vector3.Lerp(currentPosition, currentWaypoint.position, lerpFactor);

```

Another solution is to use an Animation Curve. With this approach, you'd declare a curve field at the top of your script:

```
[SerializeField] private AnimationCurve easingCurve;

```

This will show a curve field in the Inspector. We'll use this curve to define the interpolated motion of our GameObject. Start with something like this (note that the curve should start at (0,0) and end at (1,1):

Then we'll use the curve in our movement coroutine:

```
do {
    var t = passedTime / duration;
    var lerpFactor = easingCurve.Evaluate(t); //use the curve to apply easing
    transform.position = Vector3.Lerp(currentPosition, currentWaypoint.position, lerpFactor);
    passedTime += Time.deltaTime;
    yield return null;
} while (passedTime <= duration);

```

Our curve defines a function which takes an input and returns an output. The "time" (x-axis) of the curve represents the input (in our case, a time from 0 - 1) and the "value" (y-axis) represents the corresponding output (in our case, how far the GameObject has moved between the start and end positions).

If the curve was a perfectly straight line from (0,0) to (1,1) the output would be linear (in fact, it would be exactly the same value as the input). However, this s-shaped curve will ease the motion in at the beginning and ease it out at the end. The flatter the curve is in a particular area, the slower our motion will be at that time.

If you find this confusing, try messing around with the shape of the curve and study how this affects the animation.

---

Easing functions usually are easier to use. If there's a specific style of easing that you want, you would just call the appropriate function. Animation curves take a little more work to set up but give you more control over the exact motion.

For a project which makes heavy use of easing, I'll usually rely on an easing library and only use an animation curve if the easing functions don't give me enough fine control. If I only need to use easing in one or two places, I'll usually just use an animation curve rather than adding an easing library to the project.

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


# Question
Title: Working with websockets in Unity: Cannot convert lambda expression to type 'IObserver<ReconnectionInfo>' because it is not a delegate type
I'm a bit stuck on a delegate error in Unity. The code works fine if I'm in a c# console app however Unity is giving me the error:

> Cannot convert lambda expression to type 'IObserver' because it is not a delegate type.

```
client.ReconnectionHappened.Subscribe(type =>
            {
                Log.Information($"Reconnection happened, type: {type}, url: {client.Url}");
            });

```

I tried updating to the latest Unity for the c# 8 support but that didn't appear to fix anything. I'm guessing it has something to do with .net compatibility and Unity. Do I need to create this delegate some other way to be compatible with unity?

I've been looking at the code here. Websockets Server for Unity3d

Using this for the client https://github.com/Marfusios/websocket-client

# Answer
anonymous function is not the same as an object representing an anonymous function. you're trying to pass in anonymous function, but you need to wrap it in the object representing it and pass that one instead https://stackoverflow.com/a/23247231/1705376
> 1 votes

---
Tags: unity, c#, .net, websocket, delegates
---


title: Parallel transformations tree update

text:
# Question
Title: Parallel transformations tree update
I create my own pet-project graphics engine for the learning and research purposes. Now I'm trying to create a more efficient scene transformations update technique. My current approach is the linear encoded transormation tree as follows: My tree node

```
    struct TreeNode
    {
        TransformIndex parent;
        TransformIndex firstChild;
        TransformIndex next;
        TransformIndex prev;
    };

```

It is contained in the vector

```
std::vector<TreeNode> tree_;

```

Also I have world and local matrices for every node

```
    std::vector<mat4x4> worldTransforms_;
    std::vector<mat4x4> localTransforms_;

```

Couple of the dirty flags and the unused indices flags:

```
    using Flags = boost::dynamic_bitset<uint64_t>;
    Flags worldDirty_;
    Flags localDirty_;
    Flags free_;

```

using this flags I insert the new nodes in the any free index, but **always** after their parent:

```
TransformIndex TransformTree::allocateIndex(TransformIndex parent)
{
    assert(parent < tree_.size() && !free_.test(parent));
    auto posIndex = free_.find_next(parent);
    if (posIndex == Flags::npos)
    {
        posIndex = static_cast<TransformIndex>(free_.size());
        resize(free_.size() * 2);
    }
    auto pos = static_cast<TransformIndex>(posIndex);
///........
}

```

so update of the world matrices at the begining of an every frame looks like this:

```
    for (auto index = worldDirty_.find_first(); index != Flags::npos; index = worldDirty_.find_next(index))
    {
        const auto parent = tree_[index].parent;
        assert(parent < index);
        worldTransforms_[index] = worldTransforms_[parent] * localTransforms_[index];
        worldDirty_.set(index, false);
    }

```

It's quite fast, but not as good as it can be. Main issue here that it's unparallelable since every single matrix update depends on another matrix somewhere back in the array and we have to know it's already updated. I want to find a way to change the data structure and/or algorithm to be done in parallel. Also it's would be nice to do it in the compute shader in the future. I've googled for a decent time, but couldn't find any examples of it beyond the basic mentions that such algorithms exist and used in modern engines. Please, give me any advices, how to improve my implementation to make it parallelisable.

# Answer
**The Problem for GPU**

Since each tree in the forest must have its pre-requisite ancestor nodes processed first, as you noted, the tree-in-forest becomes the basic unit of parallelisation.

Without a fixed / similar topological structure for every tree in the forest, conditionals are needed (in shader code) to determine each tree's structure on the fly. This leads to non-parallel processing per tree, and would thus work better on CPU.

**One possible solution for GPU**

Decide on some maximally-defined tree structure, and then for certain trees, use null nodes, thereby clipping off some topology uniquely per tree. You'd write code specifically to operate on *that* maximal tree structure (say 1 root, 3 nodes at depth 1, etc. - specifically), no conditionals. The same amount of geometry would be rendered, but some branches etc. would simply be degenerate (taking up zero volume) due to the null nodes specifying them.

This has an increased chance of cache misses, due to the expanded (non-sparse) data for each tree; but this may be acceptable. Your choice of maximal tree size is going to be critical to the performance of this solution. Too large and you'll have too many cache misses; too small and your trees won't look so great or be particularly varied.

**Either way... GPU or CPU**

> every single matrix update depends on another matrix somewhere back in the array and we have to know it's already updated

So you need a parent node to always appear before any children in that tree's linear list/array, so that it has already been processed within this running kernel instance, and thus guaranteed to have been run, by the time you reach its descendants. Try a depth-first, pre-order traversal of each distinct tree in the forest. To give you some idea of how to order this way (pseudocode):

```
int addToBuffer(TreeNode node) //returns the number of descendants
{
    //anything called here is pre-order...
    dataBuffer.append(node);

    //recurse
    int descendantCount = 0;
    for each (child in node.children) //or however you need to do this
    {
        descendantCount += addToBuffer(child);
    }

    //...anything called here is post-order (nothing in this example)

    return descendantCount;
}

int startIndex = 0;
int descendantCount;

foreach (treeNode in forest) //each treeNode is the root of a tree
{
    descendantCount = addToBuffer(treeNode);
    Rande range = new Range();
    range.startIndex = startIndex;
    range.length = descendantCount;
    rangesBuffer.append(range);

    startIndex += length;
}

```

Each tree's individual linearised data is pushed back-to-back into a buffer, and we have a second buffer containing `Range`s i.e. start/end index tuples for each, pointing into the first buffer. Each kernel instance is then spawned given the offset i.e. `start` and `length`, and the `dataBuffer` itself.

Optional: To find specific ID'ed nodes in this list after having inserted them, you'd need a third buffer or array, which would be a lookup table (LUT) of indices keyed by ID.

If you end up doing this on CPU & single-threaded only, then you can also get away with ordering purely by increasing depth across the entire forest, which is simpler. (see *level order traversal*). **EDIT:** For reasons of data locality, this is probably a worse idea than simply processing each individual tree from root down.
> 1 votes

---
Tags: algorithm, multithreading, scene-graph
---


# Question
Title: Problem with InverseTransformDirection and non-uniform scale
I made the plane to work with mesh vertices

```
var plane = new Plane(
    hit.transform.InverseTransformDirection(normal),
    hit.transform.InverseTransformPoint(position)
);

```

If the object has the uniform scale then all looks good

but otherwise the plane normal has weird angle and I don't understand why.

with InverseTransformVector even worser. The angle goes 2 times bigger

Blue line - my plane
Green spheres - plane intersections
white sphere - plane center

Maybe it can be calculated directly with worldToLocalMatrix?

**UPDATE:**

Okay It is so weird for me. After InverseTransform plane prints in console right normal but has wrong real angle.

There is code to reproduce

Place component to default cube in zero position, rotate it with Y != 0, scale ONE horizontal dimesion. You will see onesided plane.

```
using UnityEngine;

public class PlaceOnCube : MonoBehaviour
{
    public Vector3 PlaneOrigin = new Vector3(0, 0, 0);
    public Vector3 PlaneNormal = new Vector3(1, 0, 0);

    private void OnDrawGizmos()
    {
        Gizmos.DrawSphere(PlaneOrigin, .03f);

        var plane = new Plane(
               transform.InverseTransformDirection(PlaneNormal),
               transform.InverseTransformPoint(PlaneOrigin)
               );

        ReGeneratePlane(plane);
    }

    private void ReGeneratePlane(Plane plane)
    {
        var meshfilter = transform.GetComponent<MeshFilter>();
        var mesh = meshfilter.mesh;
        var tris = mesh.triangles;
        var verts = mesh.vertices;
        var newTris = new int[36 + 6];
        var newVerts = new Vector3[24 + 4];

        for (int j = 0; j < verts.Length; j++)
            newVerts[j] = verts[j];

        newVerts[24] = plane.ClosestPointOnPlane(new Vector3(-2, -1, 0));
        newVerts[25] = plane.ClosestPointOnPlane(new Vector3(2, -1, 0));
        newVerts[26] = plane.ClosestPointOnPlane(new Vector3(-2, 1, 0));
        newVerts[27] = plane.ClosestPointOnPlane(new Vector3(2, 1, 0));

        for (int j = 0; j < tris.Length; j++)
            newTris[j] = tris[j];

        newTris[36] = 24;
        newTris[37] = 26;
        newTris[38] = 25;
        newTris[39] = 26;
        newTris[40] = 27;
        newTris[41] = 25;

        mesh.vertices = newVerts;
        mesh.triangles = newTris;

        meshfilter.mesh = mesh;
    }
}

```

# Answer
> 0 votes
A good person suggested the correct answer on another resource

To fix the scaling, instead of

```
transform.InverseTransformDirection(PlaneNormal)

```

should use

```
 transform.localToWorldMatrix.transpose.MultiplyVector(PlaneNormal)

```

---
Tags: unity, mathematics
---


# Question
Title: SpriteRenderer color not responding to script!
I have written a simple c# class that is supposed to change the color of the Player Renderer. But, there seems to be a problem! whenever I call the function OnCallFun() ... the color stays put and does not change. I have looked into the solution for quite some time now but no hope. does anyone have a solution?

```
using UnityEngine;

public class ChangeColor : MonoBehaviour
{

    // Reference to Sprite Renderer component
    private Renderer rend;

    [SerializeField]
    private Color colorToTurnTo = Color.white;

    // Use this for initialization
    void Start()
    {

        rend = GetComponent<Renderer>();

        // Change sprite color to selected color
        rend.material.SetColor("_SpecColor", colorToTurnTo);
    }
}

```

# Answer
> 0 votes
You are changing a material property called "\_SpecColor" that the default sprite material does not use.

Did you mean to change the colour of the sprite renderer itself? This is more efficient than cloning the material to set unique material properties on the instance.

```
void Start()
{
    rend = GetComponent<SpriteRenderer>();
    rend.color = colorToTurnTo;
}

```

This is shown in the very first code sample in the documentation for SpriteRenderer, so be sure to check the docs when troubleshooting a problem!

# Answer
> 0 votes
If you want to use the Setter, you need to use the correct name of the color that is assigned.

```
 void Start() {
    rend = GetComponent<Renderer>();
    rend.material.SetColor("_Color", colorToTurnTo);
 }

```

You can find the name of it when you follow the `rend.material.color` (which you can set directly as DMGregory posted) and it calls the setter from there.

Addition from DMGregory

Note that `SpriteRenderer.color` does not set `Renderer.material.color`. What it does instead is assign the colour you select as the vertex colours for the vertices of the sprite's polygon. That means you can still draw multiple sprites with different colours in a single draw call with a single material, rather than creating copies of the material with different colours for each one.

---
Tags: unity, c#, materials, color
---


title: Godot tween animation playing order

text:
# Question
Title: Godot tween animation playing order
I'm making a three in line game with godot, but i'm having an issue.

First time when swapping cells, the animation of swapping and the elimination of cells (in the case of making 3 or more cell aligned in a line) played both at the same time.

So i refactored a bit the code, now i have queue for each cell that manages the animation to be played one by one.

Now my problem is this, the cells that the player swaps, they do fine, the play the swap animation then the elimination animation. the problem are the other cells in the line, those get removed as the first cells are playing the swap animation first and then elimination animation.

```
| *              | Step 1           | Step 2          |
| cells in line  |  remove animation|   nothing       |
| swaped cells   |  swap animation  | remove animation|

```

in case i didn't explained well i left a more graphic description of the flow of the animation steps.

this is how i want the animation to be played

```
| *              | Step 1           | Step 2            |
| cells in line  |  nothing         |   remove animation|
| swaped cells   |  swap animation  | remove animation  |

```

I'm not sure how to solve the problem, each cell manages their animations in the queue.

# Answer
If I understand correctly, you have a script that initiates swap and remove animations. I presume it does so by interacting with multiple `AnimationPlayer`. However, you want to play the remove animations after all the swap animations have completed.

To do that, in the script that initiates the swap animations keep track of how many. Each time you start playing a swap animation you increment the count… Use `connect` on the animation players `animation_finished` signal, and in the handler you decrement the count (you can use `CONNECT_ONESHOT` so it disconnects automatically). When the count reaches zero in the handler, it means all the swap animations are done, then you play the remove animations.

*If you are using `Tween` instead of `AnimationPlayer` you want the `tween_completed` signal instead.*

---

For re-usability, I suggest to create a new script that has the logic of playing an animation over a list of nodes, and emit (with `emit_signal`) a signal when they all completed. Then you can use it from your current script. You would tell it to play the swap animation on a set of nodes, `yield` on your signal, and then tell it to play the remove animation on the other set of nodes.
> 1 votes

---
Tags: godot, tweening
---


# Question
Title: How to assign a specific Item index to my inventory when picking up items?
I want to make an inventory system for my game, and I found some issues when collecting an item.

What I want is to match the index in the `Inventory_UI system` exactly to the `currentIndex` on the collected item, then display it on the `Inventory_UI system`.

Let's say I pick up an item with `currentIndex = 1`, so in the `Inventory_UI system` I want to set `index=1` too and so on. This happens with the inventory description too, so the `id` is the same as the `itemIndex` picked up.

Here is my `ItemManager` script, holding the information about the items:

```
[System.Serializable]
public class theItems
{
    public string Name;
    public GameObject[] allCurrentPrefabs;
    public int numberOfIndex;
    public AudioClip[] allSound;
    public string[] terjemahannya;
    public string[] latinnya;
}

public class _ItemManager : MonoBehaviour
{
    public static _ItemManager instance;

    private void Awake()
    {
        instance = this;
    }

    public List<theItems> items;

    [Header("SurahApa")]
    public int Surah;

    [Header("SoundStuff")]
    public AudioSource aSource;

    // Start is called before the first frame update
    void Start()
    {

    }

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

    }

    public void PlaySurah(int surahnya, int ayatnya)
    {
        aSource.clip = items[surahnya].allSurahSound[ayatnya];
        aSource.Play();
    }
}

```

Next my `CollectibleItem`, a component attached to each item.

```
 public static _CollectibleAyat instance;

    private void Awake()
    {
        instance = this;
    }

    public enum InteractionType
    {
        none, pickUp, Examine
    }

    public InteractionType interactType;

    public int currentIndex;

    public string terjemahannya;
    public string latinnya;
    public GameObject allCurrentPrefabs;

    public UnityEvent customevent;

    public void Reset()
    {
        GetComponent<Collider2D>().isTrigger = true;
    }

    public void interact()
    {
        switch (interactType)
        {
            //case InteractionType.none:
            //    Debug.Log("None");
            //    break;
            case InteractionType.Examine:

                _InteractSystem.instance.Examine(this);

                Debug.Log("Examine");

                break;
            case InteractionType.pickUp:
                // Add the object to the pickUpItems List
                // Delete the Object

                _InventorySystem.instance.PickUpItem(gameObject);
                gameObject.SetActive(false);

                Debug.Log("PickingUp");
                break;
            default:

                Debug.Log("Null Item");
                break;
        }

        //Invoke (Call) the custom Event(s)
        customevent.Invoke();
    }

```

And my `InventorySystem`, which handles when items are picked up.

```
public static _InventorySystem instance;

    private void Awake()
    {
        instance = this;
    }

    [Header("GeneralFields")]
    public List<GameObject> items = new List<GameObject>();
    public bool isOpen;
    public int ayah;

    [Header("UI Items Section")]
    public GameObject UI_InventoryWindow;
    public Image[] item_Images;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I))
        {
            ToggleInventory();
        }
    }

    public void ToggleInventory()
    {
        isOpen = !isOpen;
        UI_InventoryWindow.SetActive(isOpen);
    }

    public void PickUpItem(GameObject item)
    {
        items.Add(item);
        Update_UI();
    }

    public void Update_UI()
    {
        HideAll();

        for (int i = 0; i < items.Count; i++)
        {
            item_Images[i].sprite = items[i].GetComponent<SpriteRenderer>().sprite;
            item_Images[i].gameObject.SetActive(true);

        }

    }

    public void HideAll()
    {
        foreach (var i in item_Images)
        {
            i.gameObject.SetActive(false);
        }
    }

    //SampeSini
    public void ShowDescription(int id)
    {

    }

    public void HideDescription()
    {

    }

```

And lastly my `InteractSystem` which handles interacting with and storing items in the `collectibleItem` system.

```
 public static _InteractSystem instance;

    private void Awake()
    {
        instance = this;
    }

    public Transform detectionPoint;

    public const float detectionRadius = .2f;

    public LayerMask detectionLayer;

    public GameObject detectedObject;

    public GameObject examinePanel;

    private void Update()
    {
        if (DetectedObject())
        {
            if (PickUpInput())
            {
                detectedObject.GetComponent<_CollectibleAyat>().interactType = _CollectibleAyat.InteractionType.pickUp;
                detectedObject.GetComponent<_CollectibleAyat>().interact();
                _UIManager.instance.BackToGameFromExamine();
            }

            if (ExamineInput())
            {
                detectedObject.GetComponent<_CollectibleAyat>().interactType = _CollectibleAyat.InteractionType.Examine;
                detectedObject.GetComponent<_CollectibleAyat>().interact();
            }
        }
    }

    bool PickUpInput()
    {
        return CrossPlatformInputManager.GetButtonDown("Fire1");
    }

    bool ExamineInput()
    {
        return CrossPlatformInputManager.GetButtonDown("Fire2");
    }

    bool DetectedObject()
    {
        Collider2D obj = Physics2D.OverlapCircle(detectionPoint.position, detectionRadius, detectionLayer);
        if (obj == null)
        {
            detectedObject = null;
            return false;
        }
        else
        {
            detectedObject = obj.gameObject;
            return true;
        }
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawSphere(detectionPoint.position, detectionRadius);
    }

    public void Examine(_CollectibleAyat items)
    {
        examinePanel.SetActive(true);

        items.terjemahannya = _QuranManager.instance.quran[_QuranManager.instance.Surah].terjemahannya[items.currentAyah].ToString();
        items.latinnya = _QuranManager.instance.quran[_QuranManager.instance.Surah].latinnya[items.currentAyah].ToString();
        items.allCurrentSurahPrefabs = _QuranManager.instance.quran[_QuranManager.instance.Surah].allCurrentSurahPrefabs[items.currentAyah];

        var go = Instantiate(items.allCurrentSurahPrefabs, _UIManager.instance.instantiatePosition.position,Quaternion.identity);
        go.transform.SetParent(_UIManager.instance.instantiatePosition.transform);

        _UIManager.instance.terjemahanText.text = items.terjemahannya;
        _UIManager.instance.latinText.text = items.latinnya;
    }

```

Here is what it looks like when running in the editor:

Note: in `ShowDescription(int id)`, I want to show item information matching the item I picked up.

# Answer
> 0 votes
Presumably you want something like this:

```
[SerializeField] private List<CollectibleItem> items = new List<CollectibleItem>();
private int index;
// ...
public void PickUpItem(CollectibleItem item) {
    items.Add(item);
    this.index = item.currentIndex; //Why do you need this exactly?
    Update_UI();
}

```

Your `InventorySystem` does not have a field named `index` so I'm not sure exactly *why* you want to read the index. However, I am pretty sure that whatever you're trying to do, you're trying to do it the wrong way.

I can't think of any reason why a collectible item would need a public `currentIndex` field that the inventory system would need to read. If you're planning to use that index to retrieve some data (such as a sprite) associated with the item, you should instead read the data directly from the item.

If you are planning to use the "index" to sort the items list, don't call it an "index". Call it `sortOrder` or something like that.

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