# Question
Title: Create 3D line instead of a thin line in Unity in runtime with mouse drag
I know how to use line renderer to drag and drop to create line in runtime, but the line appears to be thin when looking from the end of the line, I want to create a real line that has a thickness(think of it as a tube or pipe shape), no mater where the look direction is, they should has a thinkness. How would you achieve this effect, I've got two ideas,

1.Create a rectangle shape, then extrude this shape to create mesh during runtime, but the manipulation of mesh during runtime is too complicated for me.

or

2.Create prefabs, and spawn new prefabs and connect them along the cursor routing to make them looked as they were a continous line.

Would you suggest me of some new ideas or existing package to achieve this effect, or is the first option is the way to go? What I want to do is to make a shader editor like appearence in 3D space, what I need to create is the edges, and the edges should look 3D instead of 2D line.

# Answer
> 0 votes
What about using an actual 3d model? If you're not looking for something super detailed, you could create a cylinder shaped 3D model, and then replicate that over the course of the line. The overlaps wont look pretty, depending on how sharp the bends are, but it might achieve the look you're going for.

If you wanted to get a little bit better detail, you could have a few different versions of the model with different "end caps". Imagine a sharp 90 turn... you could use 2 cylinders where there ends are "cut off" at a 45 degree angle, meaning they would match up precisely. Even if you have some smoother curves, something like this could smooth over issues where it looks like one "pipe" is sticking through the other.

---
Tags: unity
---


# Question
Title: Should I destroy dynamically created Image.sprite?
Image sprite is created programmatically

```
_image.sprite = Sprite.Create(texture, ...);

```

Should I destroy it before replacing with a new one?

P.S. My question comes from these thoughts: Unity components are destroyed when their scene objects are destroyed. Sprite is not a component, so it seems unclear to me if it will be destroyed somehow (when calling `Resources.UnloadUnusedAssets` or when the scene is unloading) in case it is disconnected from the image (replaced with another one).

# Answer
> 0 votes
I found this post: https://answers.unity.com/questions/919594/how-to-destroy-spritecreate-leak.html

It seems to indicate that the more problematic part if the Texture being used:

"Textures are not garbage collected."

But I suppose if you're reusing Textures that's probably not an issue. If it is in fact an issue, it sounds like calling `Destroy` specifically is preferable to using `Resources.UnloadUnusedAssets`.

---
Tags: unity, sprites, unity-ui, asset-management
---


# Question
Title: Getting a null reference when using 2 delegates in a class
I have a class that is an event manager, which is notifying other scripts of touch events. However, the problem is that while the first public static event - SendInteraction - works, the second event, SendDrag, does not seem to be sending the position to the subscribed class. **Instead, it just prints a null reference error.**

"NullReferenceException: Object reference not set to an instance of an object TouchScreenManager.Update () (at ../TouchScreenManager.cs:47)"

I have tried making the TouchScreenManager class a Singleton and removing references to the events as static, and instead creating new instances in each subscribed class in Awake() but that doesn't work either. How can I fix it?

```

public class TouchScreenManager : MonoBehaviour
  {
    #region events
    public delegate void SendInteraction(GameObject item);
    public static event SendInteraction MoveScene;

    public delegate void SendDrag(Vector2 position);
    public static event SendDrag Drag;
    #endregion

    private Vector3 startPos;
    private Vector2 startPosition;
    private WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();

    void Awake()
    {
        EnhancedTouchSupport.Enable();
        TouchSimulation.Enable();
    }

    void Update()
    {
        if (Touch.activeFingers.Count == 1)
        {
            var touch = Touch.activeTouches[0];

            if (touch.phase == TouchPhase.Began)
            {
                startPosition = touch.startScreenPosition;
                startPos = Camera.main.ScreenToWorldPoint(touch.screenPosition);
                DragAndDrop(touch);
                CheckForInteraction(touch);
            }

            else if (touch.phase == TouchPhase.Moved)
            {
                Debug.Log("from the touch screen manager:" + touch.screenPosition);
                Drag(touch.screenPosition); // PRINTS FINE HERE
            }
        }
    }

```

This script is subscribed to this event.

public class LineGenerator : MonoBehaviour
{
    public GameObject linePrefab;
    Line activeLine;
    Vector2 capturedScreenPos;

    private void OnEnable()
    {
        TouchScreenManager.Drag += DrawLine;
    }

    private void OnDisable()
    {
        TouchScreenManager.Drag -= CompleteLine;

    }

    void DrawLine(Vector2 position)
    {
        GameObject newLine = Instantiate(linePrefab);
        activeLine = newLine.GetComponent<Line>();
        capturedScreenPos = position;
        Debug.Log("from the line generator: " + position); // NULL REF HERE
    }
}
````
</code></pre>

# Answer
I think that you're mistaken about where the problem is occurring... I believe it's in the TouchScreenManager, after the log statement, while it's trying to call the event. I created a contrived example of this and I found that if I called the event before the other class was subscribed to it, I got the error you mentioned, at the call to `Drag()`:

"Object reference not set to an instance of an object."

So I think you need to either wait for the other Component to get initialized, or do a null check on the event if those can be safely ignored.

*Created in LINQPad:*

```
void Main()
{
    var t = new TouchScreenManager();

    // This will throw because the other class isn't subbed yet.
    // Enabling the null check in the TouchScreenManager will essentially ignore the first call to the event, but it wont throw.
    t.Update();

    var l = new LineGenerator();

    // This should always work
    t.Update();
}

public class TouchScreenManager
{
    #region events
    public delegate void SendInteraction(Object item);
    public static event SendInteraction MoveScene;

    public delegate void SendDrag(string position);
    public static event SendDrag Drag;
    #endregion

    public void Update()
    {
        var newPosition = "My new position";
        Debug.WriteLine("from the touch screen manager:" + newPosition);

        // Enable the below line to avoid the exception
        // if (Drag != null)
        Drag(newPosition);
    }
}

public class LineGenerator
{
    public LineGenerator()
    {
        TouchScreenManager.Drag += DrawLine;
    }

    void DrawLine(string position)
    {
        Debug.WriteLine("from the line generator: " + position); // NULL REF HERE
    }
}

```
> 1 votes

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


# Question
Title: Getting the actual height of content size fitter parent
I have a parent gameobject (`Empty`) with a content size fitter with horizontal and vertical fit set to preferred size which is also a `Horizontal Layout Group` with `Control Child size` width and height enabled:

It has got a `TextMeshPro` text as child, and now, as the text expands the parent also expands. The problem is, I want to get the height of this parent. And if I use this:

```
var rect = parent.gameObject.GetComponent<RectTransform>.rect
Debug.Log($"Width: {rect.width}, height: {rect.height}");

```

or even,

```
var mValue = parent.gameObject.GetComponent<RectTransform>.sizeDelta;
Debug.Log($"sizeDeltax: {mValue.x}, sizeDeltaY: {mValue.y}");

```

they both give 0.

I require some way to extract the expanded width and height. How can I do that?

NOTE: The content of the child i.e. text is being assigned dynamically, also the parent/text is a prefab being instantiated dynamically i.e. via `Instantiate`, and this is not done in the start method.

Okay, here's more detail about the hierarchy and stuff:
**The hierarchy**

**Parent**:

**Interface**

**MessageField**

**OutputSection**

**Viewport**

**ChatPanel**

So, eventually chat bubbles are supposed to stack on top of one another, they get parented to ChatPanel, and each child is a prefab instantiated as mentioned above, the prefab detail are:

**hierarchy**

**stackItem**

**ItemParent**

**Tag**

**TextItem** (Note the MessageTextItem is basically not used, it's there for some old code reasons)

**ChatTextBubble**

These are expanded below:

When I send message, I log the width and height of the white part of the chat bubble which is basically the \**chatTextBubble above, using the code: \**

```
   var expRect = chatTextBubble.GetComponent<RectTransform>();
            Debug.Log($"dvz:: expRect width is: {expRect.rect.width} and height is: {expRect.rect.height}");

```

and it logs 0. Please tell me what am I doing wrong. It looks similar to below example but, not working.

This is what it looks like during gameplay:

EDIT: I just noticed, the **chatTextBubble** has this during gameplay:

but, logs 0 when I log with the above mentioned code.

# Answer
> 2 votes
Something is amiss with your setup, because RectTransform.rect *will* contain correct updated values as `ContentSizeFitter` manipulates its dimensions.

Here is a minimum verifiable example. Project hierarchy:

Code, attached to Test Controller GameObject:

```
using UnityEngine;
using UnityEngine.UI;

public class GetParentSize : MonoBehaviour
{

    public RectTransform parent;
    public GameObject childPrefab;
    public Text readout;
    float timer = 0;

    void Update()
    {
        timer += Time.deltaTime;
        if(timer >= .5f)
        {
            var child = Instantiate(childPrefab);
            child.transform.SetParent(parent.transform);

            timer = 0;
        }
        readout.text = string.Format("Parent Width: {0} units",parent.rect.width.ToString());
    }
}

```

Code instantiates a UI prefab every .5s and sets the parent of the instanced gameobject to the gameobject with the `ContentSizeFitter` and `HorizontalLayout` components. Every frame it updates the UI readout text with the width of the gameobject with the `ContentSizeFitter`.

This is how the parent gameobject is configured in the inspector:

This is how the Test Controller is wired up:

And here it is in action:

# Answer
> 2 votes
I just had the same problem and I found the solution was to use ForceRebuildLayoutImmediate (2018 version):

```
LayoutRebuilder.ForceRebuildLayoutImmediate(go.GetComponent<RectTransform>());

```

I can then get the dimensions with: `go.GetComponent<RectTransform>().sizeDelta.x` (Width) or `.y` (Height)

---
Tags: unity, gui
---


# Question
Title: How to understand when and where overdraw occurs
I've realized that I don't have a clear understanding of some of the technical specifics of overdraw in Unity. I often work on mobile, where overdraw is much more of a concern than it would be on a computer or console.

I understand the basics: Overdraw occurs when pixels on the screen are drawn multiple times; this consumes more GPU time and causes the frame to take longer to render. The more pixels on-screen that are suffering from overdraw, and the more times those pixels are redrawn, the greater the performance impact. One of the primary causes of overdraw is transparent sprites, particularly with overlapping particle effects. Post-processing effects also cause overdraw.

The Unity team doesn't provide a lot of information about overdraw in their documentation, and the visualization mode in the Editor does not accurately reflect what happens on the GPU. There are a handful of articles from third parties, but they rely on clumsy real-world analogies and are frustratingly vague on the technical specifics.

## Question 1

Say that we have two partially overlapping sprites that are fully opaque (no alpha channel):

Here, the yellow sprite is partially obscured by the red sprite.

I can think of two possible outcomes:

1.a) Because the yellow sprite is partially visible, the engine draws the whole sprite, then draws the red sprite on top of it. Overdraw occurs where the two sprites overlap.

1.a) The engine is able to determine that some of the yellow square is fully obscured by the red square, and only draws the pixels that aren't obscured. No overdraw occurs.

Which is the case here? Would the behavior be the same if the two squares were rendered by Mesh Renderer with a fully opaque material? I'm assuming it would, since sprites are internally rendered with polygons just like a regular mesh.

## Question 2

Say we have a partially transparent sprite overlapping another sprite:

Here, the blue sprite has an alpha channel. The edges are feathered and partially transparent, while the pixels in the inner portion are fully opaque (alpha of 1).

I can think of three possible outcomes:

2.a) Because the green sprite is partially visible, the engine draws the whole green sprite, then draws the blue sprite on top of it. Overdraw occurs where the two sprites overlap.

2.b) Because the blue sprite is partially transparent, the engine must treat the whole sprite as transparent (even the fully opaque pixels). The engine draws the whole green sprite, then draws the blue sprite on top of it. Overdraw occurs where the two sprites overlap.

2.c) The engine is able to determine that some of the pixels of the blue sprite are fully opaque, and not draw the green sprite underneath those pixels. Overdraw occurs, *but only where the feathered edges of the blue sprite overlap the green sprite*.

Which is the case here?

# Answer
The question to ask when measuring overdraw is "what would *prevent* a pixel from getting drawn to a second time?"

The only part of the pipeline that does this kind of per-pixel clipping is the depth & stencil buffer testing.

Stencil tests are only active when you ask for them, so unless you've deliberately written shaders to set and check stencil values, assume by default the stencil buffer is not doing anything for you.

Depth tests can reject a fragment either before the fragment shader has run (early z rejection - available only if you don't write modified depth values from your fragment shader) or between the fragment shader output and blending. To do this, there needs to already be a depth value in the depth buffer at that fragment's screen position, closer to the camera than the fragment you're trying to render (or father, or no farther, etc., depending on how you've configured the depth test). So:

* the closer polygon must have rendered before the farther polygon (ie. in an earlier queue, earlier in the depth sorting order, or just earlier by chance within a single batch)
* the closer polygon must have used a material that writes to the depth buffer
* the farther polygon must use a material that tests against the depth buffer

Materials that include the *possibility* of transparency/translucency, even if you're only drawing with 100% opaque alpha, typically do not write to the depth buffer, to prevent faded parts of the object from "punching holes" in content that renders behind them later.

That includes the default sprite material. So if you're using sprites, and have not made a custom "fully opaque sprite" shader that writes to the depth buffer, then both of these cases will cause maximum overdraw: every overlapped pixel will get drawn to twice.

If the red diamond in this image is using an opaque or alpha-test material (such as the default lit or unlit color materials on a MeshRenderer), then there's a *chance* it will prevent overdraw in the region where it overlaps the yellow square:

If they're both rendered in the same opaque queue ("Geometry" or "AlphaTest"), then it's up to which batch gets submitted to the GPU first, or which polygon gets processed first if they're both in a single batch. But if the yellow square is in a later queue (like "Trasparent"), then you can be sure the red diamond will block overdraw.

This is part of why the engine draws opaque objects first, to minimize the cost of transparent content by clipping as much of it as possible.
> 4 votes

---
Tags: unity, rendering, performance
---


# Question
Title: Sprite renderer doesn't update color in realtime
Whenever I add colors in Unity using script it updates it in the sprite renderer but I don't see the result on screen and it's not the alpha issue. I can see the result in the sprite renderer color tab, so if I pause the game and click on the color panel it changes it.

```
Color color = collision.gameObject.GetComponent<SpriteRenderer>().color;

sr.color += color;

```

This is what I am doing. It updates the color successfully in inspector but doesn't in playmode.

# Answer
> 1 votes
I'm unable to reproduce this issue. Using the following script:

```
public class CollisionColor : MonoBehaviour
{
    void OnCollisionEnter2D(Collision2D other) {
        if (other.collider.TryGetComponent(out SpriteRenderer otherSR)) {
            GetComponent<SpriteRenderer>().color += otherSR.color;
        }
    }
}

```

And this sprite setup:

I find the sprites change colour in play mode when they collide, as expected:

So, the problem is somewhere in code you have not shown us. Double-check that the object you're inspecting is the one you're seeing on screen, and that your `sr` variable is referring to the `SpriteRenderer` you expect. A common error here is to keep holding onto a reference to the prefab the objects were spawned from, rather than the live copy running in the scene.

If you're unable to identify the cause, then edit your question to include a Minimal Complete Verifiable Example: every line of code and every step of scene/inspector setup that a reader would need to follow, starting from a new, empty project, to reproduce the same problem you're seeing. Once we can reproduce the issue, we can test potential fixes to be sure they'll work for you.

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


# Question
Title: Screen split in different regions, each with a different scene
I am a complete beginner in Unity and, after having search for a while, I am still not sure if it is actually possible to achieve what I would like to do.

My goal is to have a game where the screen is split in 4 regions where:

* in the first there is a 3D scene;
* in the second a 2D representation of the first one (a sort of map);
* in the third a 2D scene that has nothing to do with the previous ones;
* in the fourth a "sort" of UI (i.e. there is no moving object even if it requires an ongoing user interaction).

Interactions of the user in the 1st, 2nd and 4th happen via mouse, in the 3rd with the keyboard.

How can I achieve that?

# Answer
> 6 votes
This is easy to achieve with viewports.

Inside the Inspector settings on the Camera component, you'll find a section labelled "Viewport Rect" that defines the rectangle on screen that this camera should render to.

The default value is {x: 0, y: 0, w: 1, h: 1} which means "start in the bottom-left corner (0, 0) and occupy 100% of the width and height". Changing those 1s to 0.25 would make the camera render to just one quarter of the screen, and changing the 0s would move where that quarter-screen pane sits within the wider screen (or window).

So: give each "scene" you want to render its own camera, with different viewport rectangles each. That will get your split screen rendering taken care of.

You can author each of these four panes in a separate scene file if you like, and when you start the game, load all four scenes together using LoadSceneMode.Additive to stack the scenes up in the current state, rather than unloading the previous scene before loading the next.

This overlaps all scenes in a single world coordinate space, so you'll want to author them so they don't interfere with each other. I'd recommend placing them in distinct areas of the world coordinate system (not *too* far from the origin), so that when you work with them in the scene view while testing you can see and select content from each one without confusion. You can also use Layers to filter content, so cameras in one scene don't see content loaded from another, and so physics objects in one don't interfere with another (using the Layer Collision Matrix).

You can communicate between these scenes with a `static` manager script. Or you can author some of them that need to be tightly linked (like the 3D scene and its 2D map) in a single scene file to make it easy to wire up references between them (though you can still save each version of the environment as its own prefab if you also like working with them as separate files at other times).

You could even make this with a single copy of the 3D environment rendered from two views by two cameras, using layer and shader tricks to make the 2D map camera render it the way you want without needing to author a whole second copy of the space. This can save you from bugs that arise when you change something in one version of the scene and forget to make exactly the same change in its counterpart.

Or, another way you can attack this, since all your other "scenes" are 2D, is to use the UI system. You can render your 3D scene to one corner with a viewport as explained above, then put your other four views into a UI Canvas set to Screenspace Overlay mode, so it draws over the whole screen after all cameras have rendered.

---
Tags: unity, unity-ui, screen, multiple-render-targets
---


# Question
Title: Unity3D - Screen Capture of particular UI elements
How can I screenshot particular UI elements?

In my case I need screen capture UI Panel with child objects like UI Text, UI Input and etc.

Please take a look at picture. Thanks in advance

# Answer
> 5 votes
```
using UnityEngine;
using System.Collections;
using System.IO;

public class ScreenshotNow : MonoBehaviour
{
public RectTransform rectT; // Assign the UI element which you wanna capture
int width; // width of the object to capture
int height; // height of the object to capture

// Use this for initialization
void Start ()
{
    width = System.Convert.ToInt32(rectT.rect.width);
    height = System.Convert.ToInt32(rectT.rect.height);
}

// Update is called once per frame
void Update ()
{
    if (Input.GetMouseButtonDown (0))
    {
        StartCoroutine(takeScreenShot ()); // screenshot of a particular UI Element.
    }
    if (Input.GetKeyDown (KeyCode.A))
    {
        Application.CaptureScreenshot ("FullPageScreenShot.png");
    }

}
public IEnumerator takeScreenShot()
{
    yield return new WaitForEndOfFrame (); // it must be a coroutine

    Vector2 temp = rectT.transform.position;
    var startX = temp.x - width/2;
    var startY = temp.y - height/2;

    var tex = new Texture2D (width, height, TextureFormat.RGB24, false);
    tex.ReadPixels (new Rect(startX, startY, width, height), 0, 0);
    tex.Apply ();

    // Encode texture into PNG
    var bytes = tex.EncodeToPNG();
    Destroy(tex);

    File.WriteAllBytes(Application.dataPath + "ScreenShot.png", bytes);

}
}

```

# Answer
> 1 votes
```
public class ScreenShotRect : MonoBehaviour {

    public RectTransform rectT; // Assign the UI element which you wanna capture

    private int width; // width of the object to capture
    private int height; // height of the object to capture
    private Transform rectTransformParent;  //RectTransform parent to reasign after usage
    private GameObject screenShotGO;    //Tempory GameObject to copy recttransform
                                        //RectTransform values to reasign after usage
    private Vector2 offsetMinValues;
    private Vector2 offsetMaxValues;
    private Vector3 localScaleValues;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (rectT != null)
            {
                if (rectT.root.GetComponent<CanvasScaler>().uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize)
                {
                    if (rectT.root.GetComponent<CanvasScaler>().screenMatchMode != CanvasScaler.ScreenMatchMode.MatchWidthOrHeight ||
                        rectT.root.GetComponent<CanvasScaler>().matchWidthOrHeight != 0.5f)
                    {
                            Debug.LogWarning("UI may not look the same due to Canvas Scaler either screenMatchMode was not set MatchWidthOrHeight or MatchWidthOrHeight is not set to 0.5f");
                    }
                    createCanvasWithRectTransform();
                }
                else if (rectT.root.GetComponent<CanvasScaler>().uiScaleMode == CanvasScaler.ScaleMode.ConstantPixelSize)
                {
                    StartCoroutine(takeScreenShot());
                }
                else
                {
                    Debug.LogWarning("Canvas Scaler mode not supported.");
                }
            }
            else
            {
                Debug.Log("Rect transform is null to capture the screenshot, hence fullscreen has been taken.");
                Application.CaptureScreenshot("FullPageScreenShot.png");
            }
        }

    }

    private void createCanvasWithRectTransform()
    {
        rectTransformParent = rectT.parent; //Assigning Parent transform to reasign after usage

        //Copying RectTransform values to reasign after switching parent
        offsetMinValues = rectT.offsetMin;
        offsetMaxValues = rectT.offsetMax;
        localScaleValues = rectT.localScale;

        //Creating secondary CANVAS with required fields
        screenShotGO = new GameObject("ScreenShotGO");
        screenShotGO.transform.parent = null;
        Canvas canvas = screenShotGO.AddComponent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceOverlay;
        CanvasScaler canvasScalar = screenShotGO.AddComponent<CanvasScaler>();
        canvasScalar.uiScaleMode = CanvasScaler.ScaleMode.ConstantPixelSize;
        screenShotGO.AddComponent<GraphicRaycaster>();

        rectT.SetParent(screenShotGO.transform);    //Assigning capture recttransform to temporary parent gameobject

        //Reasigning recttransform values
        rectT.offsetMin = offsetMinValues;
        rectT.offsetMax = offsetMaxValues;
        rectT.localScale = localScaleValues;

        Canvas.ForceUpdateCanvases();   // Forcing all canvas to update the UI

        StartCoroutine(takeScreenShot());   //Once everything was set ready, Capture the screenshot
    }

    private IEnumerator takeScreenShot()
    {
        yield return new WaitForEndOfFrame(); // it must be a coroutine

        //Calcualtion for the width and height of the screenshot from recttransform
        width = System.Convert.ToInt32(rectT.rect.width);
        height = System.Convert.ToInt32(rectT.rect.height);

        //Calcualtion for the starting position of the recttransform to be captured
        Vector2 temp = rectT.transform.position;
        var startX = temp.x - width / 2;
        var startY = temp.y - height / 2;

        // Read the pixels from the texture
        var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
        tex.ReadPixels(new Rect(startX, startY, width, height), 0, 0);
        tex.Apply();

        // split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        var bytes = tex.EncodeToPNG();
        Destroy(tex);

        //Writing bytes to a file
        File.WriteAllBytes(Application.dataPath + "/ScreenShotRect/ScreenShot.png", bytes);

        //In case of ScaleMode was not ScaleWithScreenSize, parent will not be assigned then no need to revert the changes
        if (rectTransformParent != null)
        {
            //Reasigning gameobject to its original parent group
            rectT.SetParent(rectTransformParent);

            //Reasigning recttransform values
            rectT.offsetMin = offsetMinValues;
            rectT.offsetMax = offsetMaxValues;
            rectT.localScale = localScaleValues;

            //Destorying temporary created gameobject after usage
            Destroy(screenShotGO);
        }

        Debug.Log("Picture taken");
    }
}

```

Note: UI may not look the same when Canvas Scaler either screenMatchMode was not set MatchWidthOrHeight or MatchWidthOrHeight is not set to 0.5f

This code is modified based on Shuvro Sarkar's answer

# Answer
> 0 votes
In my runs, I discovered the solution to the size of the window and only part of the panel problem was solved by going to the Canvas Scaler and changing UI Scale mode to costant pixel.

# Answer
> 0 votes
This is the modified answer for `scaleWithScreenSize` option on **CanvasScaler**,

```
    if(sourceRect.root.GetComponent<UnityEngine.UI.CanvasScaler>().uiScaleMode == UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize)
    {
        UnityEngine.UI.CanvasScaler scaler = sourceRect.root.GetComponent<UnityEngine.UI.CanvasScaler>();
        if (scaler.matchWidthOrHeight == 0)
        {
            height = System.Convert.ToInt32((float)Screen.width  / (float)width * height);
            width = Screen.width;
        }
        else // scaler.matchWidthOrHeight == 1
        {
            width = System.Convert.ToInt32((float)Screen.height / (float)height * width);
            height = Screen.height;
        }
    }

```

Just a quick fix for the `matchWidthOrHeight` on 0 and 1, If anyone have some idea about the value between, please let me know :)

(Add code below `Vector2 temp = rectT.transform.position;` from Shuvro Sarkar's answer)

# Answer
> 0 votes
I was able to accomplish this even with CanvasScaler set to scaleWithScreenSize and matchWidthOrHeight set to arbitrary value, using the RectTransformUtility api:

```
    Rect rect = RectTransformUtility.PixelAdjustRect(rectT, canvas);

    int textWidth = System.Convert.ToInt32(rect.width); // width of the object to capture
    int textHeight = System.Convert.ToInt32(rect.height); // height of the object to capture

    var startX = System.Convert.ToInt32(rect.x) + Screen.width / 2; // offset X
    var startY = System.Convert.ToInt32(rect.y) + Screen.height / 2; // offset Y

    var tex = new Texture2D(textWidth, textHeight, TextureFormat.RGB24, false);
    tex.ReadPixels(new Rect(startX, startY, textWidth, textHeight), 0, 0);
    tex.Apply();

```

# Answer
> 0 votes
Some people may want go for something simple using the built-in capture, and into texture, for our case texture does not need to be written to file, you can whatever with the texture.

```
private IEnumerator takeScreenShot()
{
    // GameObject to hide while capturing
    ControlsGO.SetActive(false);

    yield return new WaitForEndOfFrame();

    Texture2D texture;
    if (!ControlsGO.activeSelf)
    {
        texture = ScreenCapture.CaptureScreenshotAsTexture();
        finishedMainRoutine = true;
        ControlsGO.SetActive(true);

        var bytes = texture.EncodeToPNG();

        File.WriteAllBytes(Application.dataPath + "ScreenShot.png", bytes);
        Debug.Log("Done");
    }
}

```

# Answer
> 0 votes
This code will do exactly this.

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

public class TakeScreenshotAndSave : MonoBehaviour
{
    //Object To Screenshot
    [SerializeField] private RectTransform _objToScreenshot;

    //Assign the button to take screenshot on clicking
    [SerializeField] private Button _takeScreenshotButton;

    void Start()
    {
        _takeScreenshotButton.onClick.AddListener(OnClickTakeScreenshotAndSaveButton);
    }

    private void OnClickTakeScreenshotAndSaveButton()
    {
        StartCoroutine(TakeSnapShotAndSave());
    }

    //Using a Coroutine instead of normal method
    public IEnumerator TakeSnapShotAndSave()
    {
        //Code will throw error at runtime if this is removed
        yield return new WaitForEndOfFrame();

        //Get the corners of RectTransform rect and store it in a array vector
        Vector3[] corners = new Vector3[4];
        _objToScreenshot.GetWorldCorners(corners);

        //Remove 100 and you will get error
        int width = ((int)corners[3].x - (int)corners[0].x) - 100;
        int height = (int)corners[1].y - (int)corners[0].y;
        var startX = corners[0].x;
        var startY = corners[0].y;

        //Make a temporary texture and read pixels from it
        Texture2D ss = new Texture2D(width, height, TextureFormat.RGB24, false);
        ss.ReadPixels(new Rect(startX, startY, width, height), 0, 0);
        ss.Apply();

        Debug.Log("Start X : " + startX + " Start Y : " + startY);
        Debug.Log("Screen Width : " + Screen.width + " Screen Height : " + Screen.height);
        Debug.Log("Texture Width : " + width + " Texture Height : " + height);

        //Save the screenshot to disk
        byte[] byteArray = ss.EncodeToPNG();
        string savePath = Application.persistentDataPath + "/ScreenshotSave.png";
        System.IO.File.WriteAllBytes(savePath, byteArray);
        Debug.Log("Screenshot Path : " + savePath);

        // Destroy texture to avoid memory leaks
        Destroy(ss);
    }
}

```

---
Tags: unity, screenshot
---


# Question
Title: What does "Continuity of response" mean in the book "Game Feel"
In Steve Swink's book "Game Feel", he talks about 3 thresholds the computer must meet in order to maintain the illusion of real-time control.

> 1. The impression of motion (display above 10 fps). The frames displayed on the screen must be above 10 per second to maintain the impression of motion. The impression will be better and smoother at 20 or 30 frames per second.
> 2. Instantaneous response (input to display happens in 240 ms or less). The computer’s half of the process must take less than correction cycle for the player. At 50 ms, response feels instantaneous.
> Above 100 ms, the lag is noticeable but ignorable. At 200 ms, the response feels sluggish.
> 3. Continuity of response Cycle time for the computer’s half of the process stays at a consistent 100 ms or fewer.

Later in the book he restates the three items above, using slightly different language.

> 1. 10 frames per second. The images are displayed at a rate faster than one cycle of the human perceptual processor, which will be 50 to 200 ms. Therefore, images displayed at a rate at or above a rate of 10 frames per second will appear fused into motion, and 20 frames per second or higher is necessary for a smooth motion. In the case of a game, this is not a series of linear frames played back in sequence but a series of states generated in response to input.
> 2. Response time of 100 ms or less. The game’s response to input happens within one perceptual cycle (50 to 200 ms) of the player’s action, fusing into a sense of causality and instantaneous response.
> 3. A continuous feedback loop. The game provides a continuous, unbroken flow of input and instant response, enabling ongoing correction cycles to occur.

I understand the first two thresholds, but I am struggling to understand "Continuity of response". His discussion on the topic does not make it clear for me.

What is "Continuity of response" and what does it feel like if there is no or poor continuity of response?

The "continuous feedback" phrase makes more sense to me, but still confused by what is meant by the 100ms in the Continuity of response description.

# Answer
> 2 votes
This is a bit of conjecture; I haven't read the book, but did some digging on the author's companion website for the book.

There I found links to some posts stating

> These articles were one of the reasons I started thinking about this stuff and wanted to write a book.

In particular, the post Measuring Responsiveness in Video Games by Mick West caught my attention regarding processing consistency. In that post, Mick writes:

> Then what about the games where the lag varies? Harry Potter is 10-14 which is bad enough, but Heavenly Sword is an astonishing 7-18. It takes 7/60ths to start an attack, but 18/60ths to start to turn around (See movie: mvi\_4263w). Clearly something is wrong there. I would consider that a bug. It’s sad that the programmer made the effort that allowed for a 7/60th response time, but then someone else messed up down the line, making the turn take nearly a third of a second. Halo 3 is another example, with the shooting and moving being 8, but the jumping being 10.

Combined with the definitions provided in the question, my read seems to match the suggestion in the comments that "continuity of response" refers to consistency & that a lack of consistency (which is to say a *variable* amount of lag introduced processing lag) further exaggerates a player's perception of a game's responsiveness.

Anecdotally, that feels reasonable. If a game has a consistent amount of processing lag, it's easier to learn how to lead & compensate. Whether intentional or not, it might even be internalized as part of the game. If the processing lag is inconsistent, the player can't effectively compensate & the gameplay feels worse.

---
Tags: control, interface, realtime
---


# Question
Title: How can I rotate an object based on another's offset to it?
I have a 3D model of a turret that con rotate around the Y-axis. This turret has a cannon that is significantly off the center of the object. I want the cannon, not the turret, to aim at a specified target. I can only rotate the turret, however, and thus I don't know what equation I need to apply in order to accomplish by objective.

The following image illustrates my problem:

If I have the turret "LookAt()" the target, a laser originating from the cannon will completely miss said target.

If this were a completely top-down scenario, and the cannon were exactly parallel to the turret, then my logic tells me that the fake target should be located at a position that's equal to the actual target plus an offset that's equal to that between the turret and the cannon. However, in my actual scenario, my camera is angled 60º, and the cannon has a slight rotation.

The following image illustrates the scenario:

I'm not sure exactly why, but if I apply that same offset, it only seems to work while aiming at certain distances from the turret.

Is my logic flawed? Am I missing something fundamental here?

Final Edit: the solution provided by @JohnHamilton latest update solves this problem with perfect precision. I have now removed the code and images that I used to illustrate my incorrect implementations.

# Answer
The answer is actually pretty easy if you do the math. You have a fixed distance of Y and a variable distance of X (See Picture 1). You need to find out the angle between Z and X and turn your turret that much more.

Step 1 - Get distance between the turret line (V) and the gun line (W) which is Y (this is constant but doesn't hurt to calculate). Get distance from the turret to the target (which is X).

Step 2 - Divide Y by X and then get the inverse sine of the value to recover the angle

```
double turnRadians = Mathf.Asin(Y/X);
double angle = Mathf.Rad2Deg * turnRadians;

//where B is the red dot, A is a point on the X line and C is a point on the Z line.

```

Step 3 - Turn the turret that much more (around the axis that goes from it's top to it's bottom, most likely up axis but only you can know that part).

```
gameObject.transform.Rotate(Vector3.up, turnAngle);

```

Of course in this case, you need it to turn counterclockwise so you might need to add a minus in front of the turnAngle there, as in `-turnAngle`.

Edited some parts. Thanks to @ens for pointing out the difference in distance.

The OP said his gun has an angle so here we go, image first, explanation later:

We already know from the previous calculation where to aim the red line according to the blue line. So aiming for the blue line first:

```
float turnAngle = angleBetweenTurretAndTarget - angleBetweenTurretAndGun;
turret.transform.Rotate(Vector3.up, turnAngle);

```

The only calculation that differs here, is the calculation of "X Prime" (X') because the angle between the gun and the turret (angle "a") changed the distance between the lines.

```
//(this part had a mistake of using previous code inside new variable names, YPrime and Y are shown as X' and X in the 2nd picture.
float YPrime = Cos(a)*Y; //this part is what @ens is doing in his answer
double turnRadians = Mathf.Asin(YPrime/X);
double angle = Mathf.Rad2Deg * turnRadians;
turret.transform.Rotate(Vector3.up, angle);

```

This next part is ONLY necessary if you're doing the turret guns modular (i.e. user can change the guns on a turret and different guns have different angles). If you're doing this in editor, you can already see what the gun angle is according to the turret.

There are two methods for finding the angle "a" , one is the transform.up method:

```
float angleBetween = Vector3.Angle(turret.transform.up, gun.transform.up);

```

Above technique will calculate in 3D, so if you want a 2D result, you need to get rid of the Z axis (that's what I assume where gravity is, but if you changed nothing, in Unity it's Y axis that is up or down, i.e. gravity is on the Y axis, so you might have to change things up):

```
Vector2 turretVector = new Vector2(turret.transform.up.x, turret.transform.up.y);
Vector2 gunVector = new Vector2(gun.transform.up.x, gun.transform.up.y);
float angleBetween = Vector2.Angle(turretVector, gunVector);

```

Second way is the rotation method (I'm thinking in 2D in this case):

```
double angleRadians = Mathf.Asin(turret.transform.rotation.z - gun.transform.rotation.z);
double angle = 2 * Mathf.Rad2Deg * angleRadians;

```

Again, all these codes will give you values that are positive, so you might have to add or subtract the amount depending on the angle (there are calculations for that too, but I'm not going to go that in-depth). A good place to start on this would be the `Vector2.Dot`method in Unity.

Final block of code for additional explanation of what we're doing:

```
//turn turret towards target
turretTransform.up = targetTransform.position - turretTransform.position;
//adjust for gun angle
if (weaponTransform.localEulerAngles.z <180) //if the value is over 180 it's actually a negative for us
    turretTransform.Rotate(Vector3.forward, 90 - b - a);
else
    turretTransform.Rotate(Vector3.forward, 90 - b + a);

```

If you did everything right, you should get a scene like this (link for the unitypackage):  What I mean by always positive values:

The Z method can give negative values:

For an example scene, get the unitypackage from this link.

Here's the code I've used in the scene (on the turret):

```
public class TurretAimCorrection : MonoBehaviour
{
    public Transform targetTransform;
    public Transform turretTransform;
    public Transform weaponTransform;

    private float f, d, x, y, h, b, a, weaponAngle, turnAngle;
    private void Start()
    {
        TurnCorrection();
    }

    private void Update()
    {
        TurnCorrection();
    }
    void TurnCorrection()
    {
        //find distances and angles
        d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.y), new Vector2(turretTransform.position.x, turretTransform.position.y));
        x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.y), new Vector2(weaponTransform.position.x, weaponTransform.position.y));
        weaponAngle = weaponTransform.localEulerAngles.z;
        weaponAngle = weaponAngle * Mathf.Deg2Rad;
        y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
        b = Mathf.Rad2Deg * Mathf.Acos(y / d);
        a = Mathf.Rad2Deg * Mathf.Acos(y / x);
        //turn turret towards target
        turretTransform.up = targetTransform.position - turretTransform.position;
        //adjust for gun angle
        if (weaponTransform.localEulerAngles.z < 180)
            turretTransform.Rotate(Vector3.forward, 90 - b - a);
        else
            turretTransform.Rotate(Vector3.forward, 90 - b + a);
        //Please leave this comment in the code. This code was made by
        //http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR.
        //This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
    }
}

```

3D adapted code with X and Z as the 2D plane:

```
public class TurretAimCorrection : MonoBehaviour
{
    public Transform targetTransform; //drag target here
    public Transform turretTransform; //drag turret base or turret top part here
    public Transform weaponTransform; //drag the attached weapon here

    private float d, x, y, b, a, weaponAngle, turnAngle;
    private void Start()
    {
        TurnAdjustment();
    }

    private void Update()
    {
        TurnAdjustment();
    }
    void TurnAdjustment()
    {

        d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.z), new Vector2(turretTransform.position.x, turretTransform.position.z));
        x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.z), new Vector2(weaponTransform.position.x, weaponTransform.position.z));
        weaponAngle = weaponTransform.localEulerAngles.y;
        weaponAngle = weaponAngle * Mathf.Deg2Rad;
        y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
        b = Mathf.Rad2Deg * Mathf.Acos(y / d);
        a = Mathf.Rad2Deg * Mathf.Acos(y / x);
        //turn turret towards target
        turretTransform.forward = new Vector3(targetTransform.position.x, 0, targetTransform.position.z) - new Vector3(turretTransform.position.x, 0, turretTransform.position.z);
        //adjust for gun angle
        if (weaponTransform.localEulerAngles.y < 180)
            turretTransform.Rotate(Vector3.up, - a +b-90);
        else
            turretTransform.Rotate(Vector3.up, + a+ b - 90);
        //Please leave this comment in the code. This code was made by
        //http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR.
        //This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
    }
}

```
> 35 votes

# Answer
You could also use a more general approach:

The math for your problem already exists in the form of the scalarproduct (or dot product). You only need to get the directions of your weapons forward axis and the direction from your weapon to the target.

Let W be your weapon's forward vector.

Let D be the direction from your weapon to your target. (Target.pos - Weapon.pos)

If you solve the dot product's formula

```
dot(A,B) = |A|*|B|*cos(alpha) with alpha = the angle between A and B

```

for alpha, you get:

```
              ( dot(W,D) )
alpha = arccos(--------- )
              ( |W|*|D|  )

```

You only have to convert radians to degrees and you got your angle to rotate your robot. (As you mentioned the weapon is at an angle to your robot, so you need to add the angle to alpha)
> 3 votes

# Answer
All the answers posted so far are (more or less) wrong, so here's a quick correct solution:

To aim the gun towards the target, rotate the turret forward vector to the target and add the angle θ.

So let's find θ:

```
   d / sin(δ) = a / sin(α) # By the Law of Sines
=> α = asin(a * sin(δ) / d)

   β = 180° - α - δ
   θ = 90° - β
=> θ = α + δ - 90°
     = asin(a * sin(δ) / d) + δ - 90°
     = asin(a * cos(δ') / d) - δ' # Where (δ' = 90° - δ) is the angle between
                                  # the gun and the turret forward vector.

```

When `δ' = 0` this simplifies to `θ = asin(a / d)`, which matches the first part of John Hamilton's answer.

**Edit:**

I've added a working example.

Open in JSFiddle or use the embedded snippet below:

```
var Degree = Math.PI / 180;
var showDebugOverlays = false;

var Turret = {
    gunAngle: -10 * Degree,
    maxGunAngle: 85 * Degree,
    adaptedGunXOffset: null,

    rotateToTarget: function (target) {
        var delta = Vec.subtract(this.position, target.position);
        var dist = Vec.length(delta);
        var angle = Vec.angle(delta);

        theta = Math.asin(this.adaptedGunXOffset / dist) + this.gunAngle;
        this.rotation = -(angle + theta);

        this.updateGunRay(target);
    },

    setGunAngle: function (angle) {
        var angle = this.clampGunAngle(angle);
        this.gunAngle = angle;
        this.gun.rotation = angle;
        // Account for the fact that the origin of the gun also has an y offset
        // relative to the turret origin
        var extraXOffset = this.gun.position.y * Math.tan(angle);
        var gunXOffset = this.gun.position.x + extraXOffset;
        // This equals "a * cos(δ')" in the angle formula
        this.adaptedGunXOffset = gunXOffset * Math.cos(-angle);

        if (showDebugOverlays) {
            // Show x offsets
            this.removeChild(this.xOffsetOverlay);
            this.removeChild(this.extraXOffsetOverlay);
            this.xOffsetOverlay = addRect(this, 0, 0, this.gun.position.x, 1, 0xf6ff00);
            this.extraXOffsetOverlay = addRect(this, this.gun.position.x, 0, extraXOffset, 1, 0xff00ae);
        }
    },

    rotateGun: function (angleDelta) {
        this.setGunAngle(this.gunAngle + angleDelta);
    },

    updateGunRay: function (target) {
        var delta = this.gun.toLocal(target.position);
        var dist = Vec.length(delta);
        this.gun.removeChild(this.gun.ray);
        this.gun.ray = makeLine(0, 0, 0, -dist);
        this.gun.addChildAt(this.gun.ray, 0);
    },

    clampGunAngle: function (angle) {
        if (angle > this.maxGunAngle) {
            return this.maxGunAngle;
        }
        if (angle < -this.maxGunAngle) {
            return -this.maxGunAngle;
        }
        return angle;
    }
}

function makeTurret() {
    var turret = new PIXI.Sprite.fromImage('http://i.imgur.com/gPtlPJh.png');
    var gunPos = new PIXI.Point(25, -25)

    turret.anchor.set(0.5, 0.5);

    var gun = new PIXI.Container();
    var gunImg = new PIXI.Sprite.fromImage('http://i.imgur.com/RE45GEY.png');
    gun.ray = makeLine(0, 0, 0, -250);
    gun.addChild(gun.ray);

    gunImg.anchor.set(0.5, 0.6);
    gun.addChild(gunImg);
    gun.position = gunPos;

    // Turret forward vector
    turret.addChild(makeLine(0, -38, 0, -90, 0x38ce2c));
    turret.addChild(gun);
    turret.gun = gun;

    Object.setPrototypeOf(Turret, Object.getPrototypeOf(turret));
    Object.setPrototypeOf(turret, Turret);

    turret.setGunAngle(turret.gunAngle);

    if (showDebugOverlays) {
        addRect(turret, 0, 0, 1, 1); // Show turret origin
        addRect(gun, -1, 1, 2, 2, 0xff0096); // Show gun origin
    }

    return turret;
}

function makeTarget() {
    var target = new PIXI.Graphics();
    target.beginFill(0xd92f8f);
    target.drawCircle(0, 0, 9);
    target.endFill();
    return target;
}

var CursorKeys = {
    map: { ArrowLeft: -1, ArrowRight: 1 },
    pressedKeyDirection: null,

    onKeyDown: function (keyEvent) {
        var key = this.map[keyEvent.key];
        if (key) {
            this.pressedKeyDirection = key;
        }
    },
    onKeyUp: function (keyEvent) {
        var key = this.map[keyEvent.key];
        if (key) {
            if (this.pressedKeyDirection == key) {
                this.pressedKeyDirection = null;
            }
        }
    }
}

document.body.addEventListener("keydown", CursorKeys.onKeyDown.bind(CursorKeys));
document.body.addEventListener("keyup", CursorKeys.onKeyUp.bind(CursorKeys));

function makeLine(x1, y1, x2, y2, color) {
    if (color == undefined) {
        color = 0x66CCFF;
    }
    var line = new PIXI.Graphics();
    line.lineStyle(1.5, color, 1);
    line.moveTo(x1, y1);
    line.lineTo(x2, y2);
    return line;
}

function addRect(parent, x, y, w, h, color) {
    if (color == undefined) {
        color = 0x66CCFF;
    }
    var rectangle = new PIXI.Graphics();
    rectangle.beginFill(color);
    rectangle.drawRect(x, y, w, h);
    rectangle.endFill();
    parent.addChild(rectangle);
    return rectangle;
}

var Vec = {
    subtract: function (a, b) {
        return { x: a.x - b.x,
                 y: a.y - b.y };
    },
    length: function (v) {
        return Math.sqrt(v.x * v.x + v.y * v.y);
    },
    angle: function (v) {
        return Math.atan2(v.x, v.y)
    }
}

Math.clamp = function(n, min, max) {
    return Math.max(min, Math.min(n, max));
}

var renderer;
var stage;
var turret;
var target;

function run() {
    renderer = PIXI.autoDetectRenderer(600, 300, { antialias: true });
    renderer.backgroundColor = 0x2a2f34;
    document.body.appendChild(renderer.view);
    stage = new PIXI.Container();
    stage.interactive = true;

    target = makeTarget();
    target.position = { x: renderer.width * 0.2, y: renderer.height * 0.3 };

    turret = makeTurret();
    turret.position = { x: renderer.width * 0.65, y: renderer.height * 0.3 };
    turret.rotateToTarget(target);

    stage.addChild(turret);
    stage.addChild(target);

    var message = new PIXI.Text(
        "Controls: Mouse, left/right cursor keys",
        {font: "18px Arial", fill: "#7c7c7c"}
    );
    message.position.set(10, 10);
    stage.addChild(message);

    stage.on('mousemove', function(e) {
        var pos = e.data.global;
        target.position.x = Math.clamp(pos.x, 0, renderer.width);
        target.position.y = Math.clamp(pos.y, 0, renderer.height);
        turret.rotateToTarget(target);
    })

    animate();
}

function animate() {
    requestAnimationFrame(animate);

    if (CursorKeys.pressedKeyDirection) {
        turret.rotateGun(3 * Degree * CursorKeys.pressedKeyDirection);
        turret.rotateToTarget(target);
    }

    renderer.render(stage);
}

run();
```

```
body {
    padding: 0;
    margin: 0;
}

#capture_focus {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0);
}
```

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.2.2/pixi.min.js"></script>
<div id="capture_focus" />
```
> 2 votes

# Answer
Rotate the turret base in a simple manner, except subtract the "fire from" offset position to your target position. Roughly:

```
    Vector3 adjustedTargetPos = TargetPos - (gunTipPos - TurretBaseTransform.position);
    Quaternion adjustedRotToTarget = Quaternion.LookRotation(adjustedTargetPos - TurretBaseTransform.position);
    TurretBaseTransform.rotation = adjustedRotToTarget;

```

This is a lot simpler than other methods I have used and seems to work great. Tested with 3d turret and 3D IK aiming. 2D or gun tip rotation not taken into account but should be easy. I dunno, am I missing something or does this work like a charm for others?
> 0 votes

---
Tags: unity, rotation, vector, linear-algebra
---


# Question
Title: Manage game states of a card game with MVC
I am creating a Yugioh java game with MVC. I was wondering wich is the better way to manage game states with MVC? I tought maybe I can use State Pattern in Model section with DrawPhase, InvocationPhase and BattlePhase as states, but in this way I won't know wich player has invoked a card or do something. Is there another way that allow me to know the whole game state and have control over the turns?
Also I'm not sure about using Threads with a Computer bot to play with so the idea of a game loop is almost discarded.

This Yugioh game is a little more simple:

On each turn you:

-Pick a card from your Deck and add it to your Hand

-Invoke monsters and spells to the board

-Battle Phase: atack to the opponent with your monsters that are in the board or use your spells that are in the board to: damage the opponent, gain life points, increase damage of monsters, etc. Monsters that fight can die and go to the gaveyard. (each player has a gaveyard)

-Next turn and repeat.

# Answer
From what I've understood, you want to use the States pattern to convey/control the overall game flow of the card game. You have defined 3 **logical game states**, Pick a card(s1), Invoke Monster(s2), and Battle Phase(s3).

Assuming your manager/controller class has an entity that is managing the transitions b/w these logical game states (s1,s2,s3), you can also have another entity that is storing/managing the **current player state** P1 or P2.

now the overall state of the game is defined as the combination of both **logical game states** and the **current player state** for eg.

```
{p1, s1}, {p1, s2}, {p1, s3} or {p2, s1}, {p2, s2}, {p2, s3}.

```

Now your View logic will be observing the overall state of the game, It will know which player turn is this, and what actions are allowed and will update accordingly.

Your View will also expose Action buttons to transition the **logical game state** using the controller. In the case of a bot, your bot script will directly use the controller to transition the state using the API provided by the controller.

The overall idea is to have different state machines instead of a single large one to represent the overall state of the game. Otherwise, permutation and combination will be high for the total number of states.
> 1 votes

---
Tags: java, state, card-game, mvc
---


# Question
Title: Can a game have characters named after video game franchises?
The video game Battlerite, a free to play team brawler, includes a hero called "Destiny", essentially named after the Destiny video game franchise. Is this legal, and why it is not a trademark infringement?

# Answer
> 1 votes
I'll start by saying that I'm by no means a legal expert and that your question will be much better answered in the Law Stack Exchange.

That being said, from my understanding of the U.S. copyright and trademarks laws, it depends on the specifics of the use of the name. As you seem to know, names aren't under copyright, but under trademarks. In order to keep your trademark, you need to defend it, otherwise you'll loose it. This is why the Elder Scrolls sued Mojang for the use of Scrolls in the name of one of their games. They needed to do so to keep their trademark, but they lost because Scrolls is too common of a word to be kept by one person. Also, remember that the trademark law is meant to benefit the consumers, not the companies, to make the products differentiable. So if the two products, or the use of the name in both cases, is easily differentiable, it should not be a trademark infringement. In your case, unless Destiny clearly refers to the game or one of its characters, I don't think it would be a trademark infringement. Imagine if all books using the word destiny could to be sued for that, it wouldn't make any sense.

But remember that I might be completely off, especially if you're not talking about the U.S., in which case I refer you to Law Stack Exchange (linked earlier) or to your relevant jurisdiction's website to read the actual laws, such as:

---
Tags: legal
---


# Question
Title: How to roll two dice so they land on pre-determined numbers?
I am developing a game in Unity in which you throw two dice which should roll normally, but you have to get a predetermined output based on the user input. Say the user enters 2,5 and presses enter, the dice should fall on the ground and roll in such a way that the first die results in 2 and second die results in 5

To achieve this I have split the rolling logic into two parts. The first part runs until the dice touch the ground, using physics, and the second part when it starts rolling slowly I use `leanTween`.

So when I press enter the code is as shown below:

```
if (Input.GetKeyDown(KeyCode.Return))
{
    transform.position = initialPosition;
    transform.rotation = Quaternion.Euler(75f, 180f, 270f);
    initialPush = true;
    collidedWithGround = false;
    rollCompleted = false;
    // above conditions repeated so that in play mode when u enter the numbers again and get the things done, the values are reset
     rigidBodyCube.useGravity = true;
     MagnitudeX = Random.Range(0f, 1000f);
     MagnitudeY = Random.Range(0f, 1000f);
     MagnitudeZ = Random.Range(0f, 1000f);
}

```

```
private void FixedUpdate()
{
   if(initialPush)
    {
        rigidBodyCube.AddForce(new Vector3(pushForce, -pushForce,0f));
        rigidBodyCube.AddTorque(MagnitudeX, MagnitudeY, MagnitudeZ);
    }
    if (collidedWithGround && !rollCompleted)
    {
        RollDiceToDesiredNumber();
    }
}

```

```
private void OnCollisionEnter(Collision other)
{
    if (other.gameObject.name == "Ground")
    {
        //Debug.Log("Dice collided with Ground..........");
        initialPush = false;
        collidedWithGround = true;
    }
}

private void RollDiceToDesiredNumber()
{
    int diceNumber = int.Parse(finalResult.GetComponent<TMP_InputField>().text);
    LeanTween.rotateLocal(gameObject, wantedRotation[diceNumber - 1], timeRoll).setOnComplete(() => rollCompleted = true);
}

```

So to explain the above code, when I press enter I make `initialPush` true. In the fixed update I add a sideward force on the pair of dice so that they fall from some space above onto the ground. The `rigidBodyCube.AddTorque` is so that the dice can rotate as they keep falling.

When it hits the ground, to make sure the forward push is ceased, I make `initialPush = false`. Now I make the `collidedWithGround = true`. From there on lean tween takes control of stuff until it gets the result to a determined value.

The value of the wanted rotations which I have given in the start looks like this:

```
wantedRotation[0] = new Vector3(270f, 0, 0);
wantedRotation[1] = new Vector3(0, 0, 0);
wantedRotation[2] = new Vector3(0, 0, 270f);
wantedRotation[3] = new Vector3(0, 0, 90f);
wantedRotation[4] = new Vector3(180f, 0f, 0f);
wantedRotation[5] = new Vector3(90f, 0f, 0f);

```

It works fine, but not in a realistic way. That is sometimes when it hits the ground, the pair of dice revolve backwards, where it actually had to revolve forward, which gives an awkward look. I tried using the `rotation.lerp` function but the dice are continuously rotating. I tried to search how to rotate the dice slowly using physics until the desired rotation but I am not getting any proper results. I tried to use Lean tween from the moment it was thrown till it hits the ground, but there is this time variable which makes it hard for me to correct predict when it hits the ground correctly.

How can I get a realistic solution for this problem?

# Answer
One way I could see this work would be to pre-bake some rolling dice animations and based on the inputs, change the initial states of the dices. So either change the textures or put the anmiation on empties, parent your dices to them and change their rotation. For randomness, you could make a buch of them and choose one at random at the beginning.

Another way would be to make a real world ''cheating dice'', where you add a gentle force that pulls the right face up or the opposite face down all the time, so that it has more chances of falling the right way. Although you might endup not getting the result you want and having to tweak the settings for hours.
> 1 votes

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


# Question
Title: Numbering sprites in a sprite sheet left-to-right, top-to-bottom
I'm using this program called Quadtastic which is a sprite sheet management tool that lets you define quads on a sprite sheet, name them, etc, and export to metadata with those names (+ position, size, etc). It has a feature that automatically numbers selected quads from top left to top right by sorting first by y axis and then by x.

Ideally I want my sprites numbered in this order:

However, due to the arbitrary size of the sprites in my sprite sheet, the sprite identified as the top left wasn't the actual top left sprite. Another sprite on the same row had a larger bounding box than it and thus had a lower y position which caused it to get sorted before the actual top left one (which was sorted as 5th)

I tried to modify the source code to try a different algorithm where I sorted by the distance of each quad's top left corner to the top left corner of the minimum bounding box of all the selected quads (a rectangle that encompasses all of them). This somewhat worked and was able to correctly sort the top left sprite as the first but a bunch of others were incorrect.

So, where can I go from here? I can't really think of any other algorithms for sorting. If anyone has any ideas for other algorithms I could try, that'd be great!

And, if anyone is wondering, the code for the sorting can be found here.

If you want to run and test algorithms yourself you need the 32 bit version of Love 10.1. If you get errors about an lfs.dll, take it from the shared folder in the repo and put it in the base directory of 32-bit Love 10.1, where love.exe, is and you should be able to run it.

# Answer
> 0 votes
Try something like:

```
local function sort(quad_a, quad_b)
  return (quad_a.y + quad_a.height) < quad_b.y or (quad_a.y < (quad_b.y + quad_b.height) and quad_a.x < quad_b.x)
end

```

This sorts A before B if:

1. A's bottom is above B's top (ie. B is definitely in a lower row), or...
2. A is not below the bottom of B (if 1 fails and 2 passes, then A and B overlap on the y axis, which we'll take to mean "same row")...

* ...and A starts to the left of B

# Answer
> 0 votes
I was able to solve this by using Row-major ordering, which you can read more about here. The general gist of how I approached it (at the time I didn't know about row-major ordering) can be seen in this image:

This works for pretty much all cases in the sprite sheet I'm using but may not work for all cases (depending on layout of a sprite sheet, size of frames, how close they are, etc). Some edge cases can also be solved by allowing the user to define a threshold when they sort to avoid erroneous detection of rows.

The code is pretty horrendous (performance and quality) and is pretty tightly integrated into this software's codebase. I'll update this post with a link to the code on my fork of quadtastic when I'm happy with the code.

---
Tags: algorithm, lua, spritesheet, love2d, sorting
---


title: Detecting Player by Raycasting

text:
# Question
Title: Detecting Player by Raycasting
I am having a problem where my ray is unable to detect the player, even if I did layermask and went to draw ray and all other stuff.

Here is my code

```
RaycastHit2D raycastHit2D = Physics2D.Raycast(enemyEyes.transform.position, new Vector2(directionOfRay, 0), LayerMask.GetMask("Player"));

if(raycastHit2D.collider != null )
{
    if (raycastHit2D.collider.gameObject.tag=="Player")
    {
        Debug.Log("Hit Hit");
    }
}

Debug.DrawRay(enemyEyes.transform.position,new Vector3(directionOfRay , 0,0)  , Color.red);

```

Problem is HIT HIT is not displaying in console .

Raycasting Problem where my ray is unable to detect my player.

# Answer
You've made the same mistake as in this previous question: Why is Raycast hitting a masked layer?

Paraphrasing/quoting my answer there:

> The problem is that raycast functions have so darned many optional parameters, and `LayerMask` isn't picky about what type it's treated as.
>
> From the docs:
>
> ```
> public static RaycastHit2D Raycast(
>       Vector2 origin,
>       Vector2 direction,
>       float distance = Mathf.Infinity,
>       int layerMask = DefaultRaycastLayers,
>       float minDepth = -Mathf.Infinity,
>       float maxDepth = Mathf.Infinity
> );
>
> ```
>
> `layerMask` is the fourth parameter. So if you provide only three parameters, Unity wants to interpret them as origin, direction, and **distance**.
>
> It might seem like providing an input of type `LayerMask` should make your intent unambiguous, or at least generate a compile-time error, but `LayerMask` can implicitly convert to `int`, and `int` can implicitly convert to `float`.
>
> So when you put a LayerMask in the third argument, the compiler tries to convert it to a float, succeeds, and so silently re-interprets your mask as a distance.

If your mask evaluates to a small number, like say 1, then you get a very short ray that misses your player. If it evaluates to a large number, you might get a ray long enough to hit the player, but along the way it hits something on a non-player layer (since the function thinks you provided no layer mask), and returns that instead.

> You can fix this by providing a dummy distance value (say, infinity, if you don't have any more conservative upper bound) so your layer mask selections end up in the fourth argument where Unity expects it:

```
RaycastHit2D raycastHit2D = Physics2D.Raycast(enemyEyes.transform.position, new Vector2(directionOfRay, 0), float.positiveInfinity, LayerMask.GetMask("Player"));

```
> 0 votes

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


title: PhysX overlap always returns false

text:
# Question
Title: PhysX overlap always returns false
I am creating a game using PhysX as the physics engine and I have a function which checks the overlapped bodies based on a sphere geometry. When there are overlapping bodies I just set a force on them. The problem is that the overlap function always return false. No matter what I feed it with. Here is my code:

```
void PhysxManager::ExplosionSphere(const glm::vec3& pos, float radius, float _force)
{
    PxOverlapBuffer hit;            // [out] Overlap results
    PxSphereGeometry overlapShape = PxSphereGeometry(radius);  // [in] shape to test for overlaps
    PxTransform shapePose = PxTransform(PxVec3(pos.x, pos.y, pos.z));    // [in] initial shape pose (at distance=0)

    if (mScene->overlap(overlapShape, shapePose, hit, PxSceneQueryFilterData(PxQueryFlag::eNO_BLOCK))) {
        for (int i = 0; i < hit.nbTouches; ++i) {
            auto actor = dynamic_cast<physx::PxRigidDynamic*>(hit.touches[i].actor);
            if (actor) {
                PxVec3 force = (actor->getGlobalPose().p - PxVec3(pos.x, pos.y, pos.z));

                actor->addForce(force * _force);
            }
        }
    }
}

```

Any ideas what might be the problem or maybe an alternative to overlap?

# Answer
> 1 votes
I couldn't get it to work as mentioned above. Instead I made it to work as I wanted using

> PxSceneQueryExt::overlapMultiple

This was suggested by NVidia on their forums as an alternative. Note that I wanted to work with multiple objects in the query.

I used it like this :

```
PxSphereGeometry overlapShape = PxSphereGeometry(radius);  // [in] shape to test for overlaps
PxTransform shapePose = PxTransform(PxVec3(pos.x, pos.y, pos.z), PxQuat(physx::PxHalfPi, physx::PxVec3(0.0f, 0.0f, 1.0f)));    // [in] initial shape pose (at distance=0)

std::unique_ptr<PxOverlapHit[]> hitOv = std::make_unique<PxOverlapHit[]>(4096);
int howMany = PxSceneQueryExt::overlapMultiple(*mScene, overlapShape, shapePose, hitOv.get(), 4096, PxQueryFilterData(PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC | PxQueryFlag::eNO_BLOCK));

```

---
Tags: physx
---


# Question
Title: How do I increment a quaternion rotation in update()?
When working with rotations expressed as angles, it makes sense to be able do to something like

```
void GameLoop::update(){
     pawn.rotation.x += 0.01;
}

```

And slowly watch the model rotate. However when I tried to do the same thing with a Quaternion based rotation, I observed that the rotation did not behave as expected. For context I'm using GLM's Quaternion implementation. What is the best known method for updating and interacting with Quaternions? should I convert the Quat back to Euler angles, do the update and then store the updated value, or is there a Quat analog to `+= 0.01` that is considered standard? Am I wrong for storing a model's rotation as a Quaternion in the first place?

# Answer
> 3 votes
Applying the rotation that a quaternion represents is done via multiplication. This is really neat, because it works on vectors, like so:

```
v2 = q * v1

```

but also on other quaternions:

```
q2 = q * q1

```

...which means that combining rotations is quite easy. The downside is that, compared to euler angles, it's a bit more difficult to immediately translate between your intuition of what a rotation is like and its quaternion representation (although I find that quaternion rotations seem far less arcane if you think about angle-axis rotations, since there is a very straightforward conversion between the two).

For your case, since you know the Euler representation of the rotation you want, you might want to just convert that directly to a quaternion and multiply it by the current rotation every frame (note that the order matters, quaternion multiplication is not commutative).

I'm not sure if glm has a built-in conversion between the two models, but the answer I linked before has several examples of how to implement one if you need it. So, once you have the `eulerToQuaternion` function, you can do something like this:

```
Quaternion q = eulerToQuaternion(0.01, 0, 0);
void GameLoop::update(){
     pawn.rotation = q * pawn.rotation;
}

```

Also, as to whether it's a good idea to use quaternions or not, it kind of depends on what exactly you are doing, but I think the general consensus is that yes, they are the most convenient way to work with rotations. The wikipedia page on the subject says:

> Compared to rotation matrices, quaternions are more compact, efficient, and numerically stable. Compared to Euler angles, they are simpler to compose. However, they are not as intuitive and easy to understand and, due to the periodic nature of sine and cosine, rotation angles differing precisely by the natural period will be encoded into identical quaternions and recovered angles in radians will be limited to \[ 0 , 2 π \].

Which sums it up pretty well, I think.

---
Tags: 3d, rotation, quaternion, glm
---


# Question
Title: Limit/Clamp camera movement using quaternions
I'm making a camera object for rendering with OpenGL. However, instead of using the typical "LookAt" method I'm trying to use just a Quaternion for orientation and a Vector3 for position. Instead of messing with euler angles to rotate the Camera I use quaternions directly, like this:

```
glm::vec3 up = glm::normalize(glm::inverse(cam.Orientation) * glm::vec3(0, 1, 0));
glm::vec3 right = glm::vec3(-1, 0, 0);
cam.Orientation = glm::rotate(cam.Orientation, glm::radians(-xoffset), up);
cam.Orientation = glm::rotate(cam.Orientation, glm::radians(-yoffset), right);

```

`xoffset` and `yoffset` are just the amount the mouse has moved since the last frame.

I create my view matrix from the inverse of the two variables. I've already got FPS style camera movement and rotation working. The problem I have now is that I want to prevent the camera from being able to flip over. I.E. moving the mouse up or down enough that the view becomes upside down. Is there a way to clamp the rotation using purely quaternions to prevent this?

# Answer
> 1 votes
I know its old, but maybe somebody else is facing this painful challange:

So a camera represented only by:

```
glm::quat mRotation;
glm::vec3 mPosition;

```

needs also keep track the Pitch and Yaw separately, and apply it one by one to the main mRotation quaternion. I haven't found any other way to limit a quaternion otherwise.

So all in all the Camera class must have these members initialized to 0.0f:

```
glm::quat mRotation;
glm::vec3 mPosition;
float mPitch, mYaw;

```

During the frame by frame call, where you pass in the delta mouse movement values, the Pitch keeps track the cumulated mouse movement, and thats what you can clamp, then pass it into the quaternion as angel axis, here is how:

```
void Camera::rotate(const float horizontalMouseMove, const float verticalMouseMove)
{
    mPitch -= verticalMouseMove;
    mYaw -= horizontalMouseMove;

    //TODO: clamp Yaw?
    mRotation = glm::angleAxis(mYaw, axis::positiveY);

    //clamp Pitch
    constexpr float PITCH_LIMIT = 1.4f;//magic number, 1.0f is too flat to my taste
    if (mPitch < -PITCH_LIMIT)
    {
        mPitch = -PITCH_LIMIT;
    }
    else
    if (mPitch > PITCH_LIMIT)
    {
        mPitch = PITCH_LIMIT;
    }

    //quaternion multiplication is not commutative, and we have YAW rotation already applied mRotation
    mRotation = mRotation * glm::angleAxis(mPitch, getRight());
}

```

---
Tags: opengl, c++, quaternion, glm
---


title: Convert mobile gesture to mouse input?

text:
# Question
Title: Convert mobile gesture to mouse input?
I use `Input.GetTouch(0).deltaPosition.x` on a mobile device and do something like this:

```
transform.Rotate(-Input.GetTouch(0).deltaPosition.x / 10 , 0,0);

```

But now I'm switching to a Windows platform.

How can I convert `Input.GetTouch(0).deltaPosition.x` to `Input.GetMouseButtonDown(0)` & then drag left and right?

ok i test this , it's work well, but it reset the difference rotation angle when click

private Vector3 _prevPos;

Vector2 ret = Input.mousePosition - _prevPos;
_prevPos = Input.mousePosition;

then

transform.Rotate(ret.x / 10 , 0,0);
```
</code></pre>

# Answer
> 0 votes
Finally used this method:

```
private Vector3 _prevPos;

private void Update()
{
    if(Input.GetMouseButtonDown(0))
    {
        _prevPos = Input.mousePosition
    }
    else if (Input.GetMouseButton(0))
    {
        ret = Input.mousePosition - _prevPos;
        _prevPos = Input.mousePosition;

        transform.Rotate(ret.y / 10, 0, ret.x );
    }
}

```

---
Tags: unity
---


# Question
Title: Creating a procedural filter stack GUI similar to Blender's Mofifier panel
I have a data structure that represents a simple terrain system and a number of filter algorithms that can be run on it. I want to be able to apply them in in any arbitrary order and have multiple instances with their own settings, basically how the Modfiers panel works in blender.

Currently, the filters are SO's that implement an interface. Then via Odin, I can expose a list of type `<IFilter>` to the inspector, and populate with SO instances in any order.

The script then iterates through the list, feeding the output from one to the input of the next.

```
List<Vertex2> generatedVerts = generateVerts(Settings settings)
foreach (var filter in filterList)
{
    generatedVerts = filter.Process(generatedVerts);
}

return generatedVerts;

```

It works, but the problem is each entry in the list is associated with an instance of the SO. So if I want to tweak the settings, I have to keep track of which SO instance corresponds to which entry in the list and it gets confusing.

What I really want is an interface where I can visually reorder modules in the inspector, but they also have their own controls exposed rather than being driven by a separate SO, as I say like how it works with blender modifiers.

Can anyone suggest an approach for this? I do have access to Odin if that will help.

# Answer
I can think of two solutions.

The first one is to keep things as they currently are, and use a custom inspector to show the Scriptable Object fields as part of the inspector view of the object that contains the reference. You don't even need to know how to implement this, there are a bunch of plugins out there that have that feature. I personally like Naughty Attributes, but I've seen several others that do it as well.

The downside is that you still need to create an Scriptable Object instance in your project for each set of parameters that you want, which is kind of awful.

So, my preferred solution would be to make the filters not be Scriptable Objects at all, just plain C# objects. That way, when you serialize an instance it is serialized by value, and it is tied to the script that contains it, rather than sitting in your project forever.

So you would just do:

```
[System.Serializable]
public class Filter : IFilter{
   //...
}

```

And then:

```
[SerializeReference] List<IFilter> filters;

```

Except there's a problem. By default, Unity would not actually let you change the filters correctly through the inspector when using polymorphism. This is not because the serializer doesn't allow it, but simply because the objects won't be correctly drawn to the inspector. You can solve that with custom Property Drawers, but they are quite tedious to implement. In the past, I have used Animancer's Polymorphic Drawer for this, but that's only convenient because I happen to already be using Animancer as a whole in my project. I'm sure there are other projects that have similar attributes for this, I just don't know of them (maybe Odin has something like it? I wouldn't know).
> 0 votes

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


# Question
Title: Opponents keep reference to old ball instead of newly-spawned ball
I have the position of a ball that the opponents get and reach for it.

When the ball is destroyed, according to my idea, a new one should be created and opponents should reach for it instead.

The ball is created, but the opponents refer to the old ball. How can I make the opponents reach for the new balls too?

```
public class EnemyPoint : MonoBehaviour {
     public float speed = 5;
     Transform ball;
     public float stoppingDistance;
     public float force = 5000f;
     public GameObject keepHolding;
     public GameObject myEnemy;

     private float spawnRangeX = 10;
     private float spawnZMin = 15;
     private float spawnZMax = 25;
     // Start is called before the first frame update
     void Start()
     {
         ball = GameObject.FindGameObjectWithTag("Ball").transform;

         Instantiate(ball.transform, GenerateSpawnPosition(), ball.transform.rotation);

     }

     // Update is called once per frame
     void FixedUpdate()
     {
         EnemyWalk();
     }

     private void OnTriggerEnter(Collider other)
     {
         Vector3 dir = ball.position - transform.position;

         if (ball)
         {

             other.GetComponent<Rigidbody>().velocity = dir.normalized * force * Time.deltaTime ;

         }

     }

     void EnemyWalk()
     {
         float rangeX = Mathf.Clamp(transform.position.x, -50, 65);
         float rangeY = Mathf.Clamp(transform.position.y, 5, 5);
         float rangeZ = Mathf.Clamp(transform.position.z, -55, -55);

         myEnemy.transform.position = new Vector3(rangeX, rangeY, rangeZ);

         if (Vector3.Distance(keepHolding.transform.position, ball.position) < stoppingDistance)
         {
             myEnemy.transform.position = Vector3.MoveTowards(myEnemy.transform.position, ball.position, speed * Time.deltaTime);
         }

     }
     Vector3 GenerateSpawnPosition()
     {
         float xPos = Random.Range(-spawnRangeX, spawnRangeX);
         float zPos = Random.Range(spawnZMin, spawnZMax);
         return new Vector3(xPos, 3, zPos);
     }
 }

```

# Answer
> 0 votes
If I read your comments right, all you need to do is assign the instantiated ball and just use it everywhere instead of the current ball.

```
private Transform spawnedBall;

void Start() {
   ball = GameObject.FindGameObjectWithTag("Ball").transform;
   spawnedBall = Instantiate(ball.transform, GenerateSpawnPosition(), ball.transform.rotation);
}

```

So instead of

```
private void OnTriggerEnter(Collider other) {
   Vector3 dir = ball.position - transform.position;
   ...
}

```

you change it to (and all other times you wrote `ball`)

```
Vector3 dir = spawnedBall.position - transform.position;

```

I'm not sure how it interacts with your other scripts or what happens to your original ball, how you destroy them or actually spawn new ones. But if you want to chase after the spawned ball, this should do the trick.

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


# Question
Title: Why do reward items in Battle Passes have rarity levels?
Many free-to-play video games feature a Trophy Path mechanic, also known as Battle Pass/Premium Pass. It offers an alternate progression path to players beyond the core game in the form of rewards, as well as acting both as a player retention mechanism and a monetisation strategy.

TP rewards can be quite diverse: in-game items, skins, soft currency, emblems... and they are rewarded to players in a sequential fashion: the more they play, the more trophies they get, the more rewards they earn. There's no such concept as **"probability"** of earning something at a given progression level: **TP items are either owned or not**.

Moreover, a given Trophy Path is the *same* for everyone playing during a certain season, meaning that some players will unlock and get the *same items*. Potentially, *all players* would earn those very same rewards, given enough time.

If so, **why do granted items have a "rarity"?** Is it about a *future projection* of players' ownership for a given item? Or, more simply, is it just a reinterpretation of the original idea of rarity, here used only as *reinforcement of the aspirational value of the item*?

# Answer
My experience is that, even though we use this term "rarity" to refer to the colour-coded category of a reward item, this often has nothing to do with the probability of acquiring it.

It may have once been used more literally, in a progenitor game where "better" loot was doled out with diminishing probabilities (there are several that could fit the bill, I won't speculate on which one began or cemented the trend). But once it was engrained in player expectations that "rarity" ≈ "goodness" of the item, calling things "common"/"uncommon"/"rare" became a useful shorthand for "meh" "better" "better-er".

Players internalized that purple "epic" drops were things to get excited about, so game designers wanting to get players excited about an item made it purple and called it "epic", and doubly so for gold/"legendary", though there's some variance in the exact sequence/labels between games.

So I'd advise not taking the term "rarity" literally to mean "low probability to acquire". It's really just an alias for "quality" or "grade". We could replace it with a star rating from 1 to 5 stars like a hotel rating or film review and the meaning would be basically unchanged.

In games without probabilistic rewards, this rarity label is just an arbitrary signifier designers attach to influence the perceived value of the item. Other games have trained players to sit up and pay attention when "rare" drops are on the line, so this just leverages that expectation as a way to give players a sense of stakes.

Often the assignment of these labels also correlates to information about the item. For gear that has stats, there might be certain stat ranges or certain (numbers of) special perks set aside for each rarity tier. Or for skins, it might reflect the complexity of the skin.

On an open world shooter game I worked on, our "common" skins were just single-colour paint jobs / palette swaps, our "rare" skins were tiling patterns (still straightforward to churn out for tons of weapons), while our "legendary" skins were one-off art pieces with bits of lore attached. So you can see this was a classification of quality / production cost / visual interest, not "rarity" (since there was exactly one copy of every skin in the game, and you could eventually unlock them all).
> 1 votes

---
Tags: game-design, free-to-play
---


# Question
Title: How do I implement a countdown timer for a multiplayer chess game?
There's a lot of multiplayer games out there that uses countdown timers to set a time limit in their game sessions, but how is it actually implemented?

For example, in a chess multiplayer game based on web, where the server is the source of truth and I've to keep a countdown timer for each player, should I store the time left for each player in a database like redis and afterwards send events to update the client timer or there's a better solution for that?

# Answer
As I mentioned in a comment, this can be implemented as a timestamp.

When an opponent reports their move to the server, the server records the time on the server clock as the last move time for that game. Then it relays that information to the player - immediately or when they next log on and query the current game state.

The player's game client can now render the time remaining on screen, and update it each frame in its game loop, without any work for the server.

When the player makes their move, they report it to the server. The server checks the last move time stored in the database, subtracts to find how much time has elapsed, and confirms whether the move from the player was received in time to count. If so, the cycle continues. If not, you fall back to your "player timed out" behaviour. You can also trigger this the next time the player or their opponent log on / refresh the current game state, if the state turns out to be "a player has timed out".

In between answering these queries, there's nothing your server has to do to maintain the state of the game, so you can support a large number of concurrent games with very modest server requirements.
> 1 votes

---
Tags: timer, websocket, chess
---


# Question
Title: Updating UI Graphic vertex positions through code
I'm trying to update the positions of vertices in my project.

I'd been using Unity's built in Line Renderer previously which worked fine, but had some problems when points got too close to each other.

Now I'm writing my own Line Renderer which is also looking good so far; it draws lines. I'm having no trouble with updating the values in inspector at runtime. Though doing it through code doesn't seem to do anything...

I'm using the `Graphic` class from the `UnityEngine.UI` library because I want to draw the lines as UI elements. And the solution I've found has been using either `Rebuild()`, SetAllDirty() or `SetVerticesDirty()` to force the mesh to update. This works, but also seems to leave old invisible vertices and tris in the scene every time it's called. After a couple seconds of running, the scene has 300k vertices and is running at 10 Fps, when the mesh itself is only about 2k verts.

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

public class UICircleBuilder : Graphic
{
    public Point[] points;
    public bool makeTri2;
    public Color secondColor;

    public CanvasUpdate update;

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        UIVertex vertex = UIVertex.simpleVert;
        vertex.color = color;

        for (int i = 0; i < points.Length-1; i++)
        {

            float vertexWidth = Mathf.Clamp(points[i].width / 2, 0, 1000);
            float nextVertexWidth = Mathf.Clamp(points[i+1].width / 2, 0, 1000);

            Vector2 angleBetweenPoints = (points[i + 1].position - points[i].position).normalized;
            Vector2 pointCross = Vector3.Cross(angleBetweenPoints, Vector3.forward).normalized;
            Debug.DrawLine(points[i + 1].position, points[i].position, Color.green, 10);
            Debug.DrawLine(points[i].position,points[i].position + pointCross*100, Color.blue, 10);

            vertex.color = points[i].color;
            //Vertex i
            vertex.position = (Vector3)points[i].position - (Vector3)pointCross * vertexWidth;
            vh.AddVert(vertex);

            //Vertex i+1
            vertex.position = (Vector3)points[i].position + (Vector3)pointCross * vertexWidth;
            vh.AddVert(vertex);

            if(i != points.Length)
            {
                //Vertex i+2
                vertex.position = (Vector3)points[i + 1].position - (Vector3)pointCross * nextVertexWidth;
                vh.AddVert(vertex);

                //Vertex i+3
                vertex.position = (Vector3)points[i + 1].position + (Vector3)pointCross * nextVertexWidth;
                vh.AddVert(vertex);
            }

        }

        for (int i = 0; i < points.Length-1; i++)
        {
            vh.AddTriangle(i*4, i*4+1, (i*4+3));
            Debug.Log(i*4 + ", " + (i*4 + 1) + ", " + (i*4 + 3));

            if (makeTri2)
            {
                vh.AddTriangle((i * 4 + 3), (i * 4 + 2), i * 4);
                Debug.Log((i * 4 + 3) + ", " + (i * 4 + 2) + ", " + i * 4);
            }

        }

    }

    public void UpdateMesh()
    {
        SetVerticesDirty();
    }

}

[System.Serializable]
public class Point
{
    public Vector2 position;
    [Range(0,1000)]
    public float width = 1;
    public Color color = Color.white;
    public Point(Vector2 position, float width = 1)
    {
        this.position = position;
        this.width = width;
    }
}

```

The mesh is generated using this code, which reads an array of vector2 positions and creates the vertices, afterwards it draws the tris

Scene stats after running for 5 seconds:

I'd be grateful for any ideas.

# Answer
> 0 votes
dont use Deafult Materil. it draw a lot times , but I don't know why.

---
Tags: unity, c#, mesh, unity-ui
---