# Question
Title: How Do I Separate Dragging My Finger On Joystick And Swiping?
I am currently making a 2D top-down view shooter game for Android, where the game is played horizontally.

On the left side of the screen, you can touch anywhere to spawn in a joystick and aim by dragging your finger, and that works completely fine.

You can also swipe and it shoots. Swiping up shoots one type of bullet, whilst swiping down shoots another.

The problem is when doing both at the same time. If I start aiming, and then swipe, the swipe won't work, and the angle for aiming starts being read also from the touch position of the finger swiping, and this glitches the aiming.

Swipe Script:

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

public class Swipe : MonoBehaviour
{
    private bool tap,swipeUp,swipeDown, swipeLeft, swipeRight;
    private bool isDraging = false;
    private Vector2 startTouch, swipeDelta;

    private void Update()
    {
        tap = swipeUp = swipeDown = swipeLeft = swipeRight = false;

        #region Touch Inputs
        if (Input.touches.Length > 0)
        {
            if (Input.touches[0].phase == TouchPhase.Began){
                isDraging = true;
                tap = true;
                startTouch = Input.touches[0].position;
            }
            else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
            {

                isDraging = false;
                Reset();
            }
        }
        #endregion

        #region Standalone Inputs
        if (Input.GetMouseButtonDown(0)){
            tap = true;
            isDraging = true;
            startTouch = Input.mousePosition;
        }else if(Input.GetMouseButtonUp(0))
        {
            isDraging = false;
            Reset();
        }
        #endregion

        // Calculate the distance
        swipeDelta = Vector2.zero;
        if(isDraging)
        {
            if(Input.touches.Length > 0)
                swipeDelta = Input.touches[0].position - startTouch;
            else if (Input.GetMouseButton(0))
                swipeDelta = (Vector2)Input.mousePosition - startTouch;
        }

        // Did we cross the deadzone?
        if (swipeDelta.magnitude > 125)
        {
            // Which direction?
            float x = swipeDelta.x;
            float y = swipeDelta.y;
            if(Mathf.Abs(x) > Mathf.Abs(y))
            {
                // left or right
                if (x < 0)
                    swipeLeft = true;

                else
                    swipeRight = true;
            }
            else{
                // up or down
                if (y < 0)
                    swipeDown = true;

                else
                    swipeUp = true;
            }

            Reset();
        }
    }

    private void Reset()
    {

        startTouch = swipeDelta = Vector2.zero;
        isDraging = false;

    }

    public Vector2 SwipeDelta { get { return swipeDelta;}}
    public bool SwipeUp { get { return swipeUp;}}
    public bool SwipeDown { get { return swipeDown;}}
    public bool SwipeLeft { get { return swipeLeft;}}
    public bool SwipeRight{ get { return swipeRight;}}
}

```

GestureDetection Script:

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

public class GestureDetector : MonoBehaviour
{
    public Shooting other;

    public Swipe swipeControls;

    private void Update()
    {
        if (GameObject.Find("robot") != null) {

            if (swipeControls.SwipeLeft)
                 Debug.Log("LeftSwipe");

            if (swipeControls.SwipeRight)
                 Debug.Log("RightSwipe");

            if (swipeControls.SwipeUp)
                 other.ShootGreen();

            if (swipeControls.SwipeDown)
                 other.Shoot();
        }
    }
}

```

Joystick Script:

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

public class joystickShoot : MonoBehaviour {
    public Shooting other;
    public Rigidbody2D rb;

    private bool touchStart = false;

    private Vector2 pointA;
    private Vector2 pointB;
    public Transform player;
    public float speed = 15.0f;
    public GameObject bulletPrefab;

    public Transform circle;
    public Transform outerCircle;

    private Vector2 startingPoint;
    private int leftTouch = 99;

    void Update () {
        int i = 0;
        while(i < Input.touchCount){
            Touch t = Input.GetTouch(i);
            Vector2 touchPos = getTouchPosition(t.position); // * -1 for perspective cameras
            if(t.phase == TouchPhase.Began){
                if(t.position.x > Screen.width / 2) {
                } else {
                    touchStart = true;
                    leftTouch = t.fingerId;
                      pointA = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z));
                    circle.transform.position = pointA * 1;
                    outerCircle.transform.position = pointA * 1;
                    circle.GetComponent<SpriteRenderer>().enabled = true;
                    outerCircle.GetComponent<SpriteRenderer>().enabled = true;
                    startingPoint = touchPos;

                }
            }else if(t.phase == TouchPhase.Moved && leftTouch == t.fingerId){
               touchStart = true;
                Vector2 offset = touchPos - startingPoint;
                Vector2 direction = Vector2.ClampMagnitude(offset, 1.0f);

                 pointB = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z));

                aimCharacter(direction);
                circle.transform.position = new Vector2(pointA.x + direction.x, pointA.y + direction.y) * 1;
                circle.transform.position = new Vector2(outerCircle.transform.position.x + direction.x, outerCircle.transform.position.y + direction.y);

            }else if(t.phase == TouchPhase.Ended && leftTouch == t.fingerId){

                circle.GetComponent<SpriteRenderer>().enabled = false;
            outerCircle.GetComponent<SpriteRenderer>().enabled = false;
                leftTouch = 99;
                circle.transform.position = new Vector2(outerCircle.transform.position.x, outerCircle.transform.position.y);
            }else{

                touchStart = false;

            }
            ++i;
        }
    }

    Vector2 getTouchPosition(Vector2 touchPosition){
        return GetComponent<Camera>().ScreenToWorldPoint(new Vector3(touchPosition.x, touchPosition.y, transform.position.z));
    }

    private void FixedUpdate() {
          if (touchStart) {
            Vector2 offset = pointB - pointA;
            Vector2 direction = Vector2.ClampMagnitude(offset, 1.0f);
            aimCharacter(direction * 1);
          }
    }

    void aimCharacter(Vector2 direction){
        Vector2 lookDir = pointB - pointA;
        float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg;
        rb.rotation = angle;
    }
}

```

# Answer
> 0 votes
Two problems:

* Your Swipe script only looks at touch 0. Subsequent touches get ignored, not what you want.
* Your Swipe script doesn't check to see if the touch is already handled by the joystick (ie. on the left side of the screen), so it can ignore it.

I'd rewrite the swipe script to look something more like this instead. Advantages of this approach:

* We can now track multiple swipe attempts in progress from multiple touches. So if you're using the joystick or accidentally touched the screen with another finger while gripping your phone, this won't interrupt swipe tracking.
* We can specify a rectangular region of the screen where swipes are allowed to originate. This lets you ignore the left half of the screen that's owned by the joystick. But since this is just data, you can change it for different instances of the script: say if you had a minigame that was all about swiping and had no joystick to avoid, you could let that one use the whole screen with the same code, just different Inspector configuration.
* Instead of setting bools, I've used `UnityEvent` variables to let you wire up what should happen from each swipe. Now you don't need your GestureDetector script at all - the `OnSwipeUp` event can call `ShootGreen()` directly, without coupling in your code.
* I added a small deadzone close to the 45-degree lines, where it's ambiguous whether the player meant to swipe left/right or up/down. That way, we wait and see if the touch continues to veer further horizontally or vertically, rather than firing off our event prematurely with maybe the wrong swipe detected.

I've commented the code sample, but please feel free to comment below if anything is unclear.

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

public class SwipeDetector : MonoBehaviour
{
    // To keep our code paths unified, we'll pretend the mouse is a finger
    // and just choose an ID for it that's obviously not one Unity uses for fingers.
    const int MOUSE_ID = -42;

    [Tooltip("Fraction of the screen where a swipe can start, where 0 is the bottom/left and 1 is top/right.")]
    public Rect swipeRange = new Rect(0.5f, 0f, 0.5f, 1f);
    [Tooltip("Fraction of the screen diameter a touch has to travel to be considered a swipe.")]
    public float deadZone = 0.1f;

    // We'll use events to fire off responses to swipes/taps instead of bools,
    // because we could hypothetically have two taps/swipes in the same frame from different fingers.
    // This also reduces coupling: your gameplay code doesn't need to know about swiping.
    public UnityEvent OnTouch;
    public UnityEvent OnSwipeUp;
    public UnityEvent OnSwipeDown;
    public UnityEvent OnSwipeLeft;
    public UnityEvent OnSwipeRight;

    // We'll use a dictionary to be able to track multiple swipes happening at the same time.
    Dictionary<int, Vector2> _swipeStartPos = new Dictionary<int, Vector2>();

    // Check if a touch at the given position is allowed to start a swipe.
    bool IsTouchStartValid(Vector2 position) {
        Vector2 normalized = new Vector2(position.x / Screen.width, position.y / Screen.height);
        return swipeRange.Contains(normalized);
    }

    // Handle initial touches in our range, and start tracking them for future swipes.
    void TryStartSwipe(int id, Vector2 startPosition) {

        if (IsTouchStartValid(startPosition)) {
            // Debug.Log("Swipe started at " + startPosition);
            _swipeStartPos[id] = startPosition;
            OnTouch?.Invoke();
        }
    }

    // Check if a moved touch should count as a swipe, and consume it if so.
    void CheckSwipe (int id, Vector2 currentPosition, float thresholdSquared) {
        // If this isn't a finger we're tracking, abort.
        if (!_swipeStartPos.TryGetValue(id, out Vector2 startPosition))
            return;

        // If the touch hasn't moved far enough to count yet, abort.
        Vector2 delta = currentPosition - startPosition;
        if (delta.sqrMagnitude < thresholdSquared)
            return;

        Vector2 absoluteDelta = new Vector2(Mathf.Abs(delta.x), Mathf.Abs(delta.y));

        // This adds a little extra dead zone around the 45-degree line, where it's
        // ambiguous whether the player was trying to swipe vertically or horizontally.
        // 1 = no deadzone, 0.2 = swiped axis must be 20% more than the perpendicular.
        float angularDeadzone = 1f + 0.2f;

        // If we've swiped in a particular direction, fire off the event callback,
        // and stop tracking this finger. (Need to tap again for a new swipe)
        if (absoluteDelta.x >= angularDeadzone * absoluteDelta.y) {
            if (delta.x > 0) {
                OnSwipeRight?.Invoke();
            } else {
                OnSwipeLeft?.Invoke();
            }
            EndSwipe(id);
        } else if (absoluteDelta.y >= angularDeadzone * absoluteDelta.x) {
            if (delta.y > 0) {
                OnSwipeUp?.Invoke();
            } else {
                OnSwipeDown?.Invoke();
            }
            EndSwipe(id);
        }
    }

    // Don't call this "Reset" - that's a special function name the Unity Editor
    // uses to wipe a component's data clean. If that's not what the function
    // is for, use a different name so it's not called at the wrong time.
    void EndSwipe(int id) {
        // Technically, removing touches from tracking is not necessary,
        // since we'll overwrite the start position on the next Began.
        // I just like to do it for neatness, so the state in the dictionary
        // closely matches the state of active swipes in flight.
        _swipeStartPos.Remove(id);
    }

    void Update() {
        // Convert our normalized deadzone threshold into an absolute pixel size,
        // accounting for the possibility that our window size changed recently.
        float deadZoneThreshold = deadZone * Mathf.Min(Screen.width, Screen.height);
        deadZoneThreshold *= deadZoneThreshold;

        // Check all touches, not just the first one.
        for (int i = 0; i < Input.touchCount; i++) {
            var touch = Input.GetTouch(i);

            switch (touch.phase) {
                case TouchPhase.Began:
                    TryStartSwipe(touch.fingerId, touch.position);
                    break;

                case TouchPhase.Moved:
                    CheckSwipe(touch.fingerId, touch.position, deadZoneThreshold);
                    break;

                case TouchPhase.Ended:
                case TouchPhase.Canceled:
                    EndSwipe(touch.fingerId);
                    break;
            }
        }

        // Repeat the swipe lifecycle tracking for our mouse in standalone mode.
        if(Input.GetMouseButton(0)) {
            if(Input.GetMouseButtonDown(0)) {
                TryStartSwipe(MOUSE_ID, Input.mousePosition);
            } else {
                CheckSwipe(MOUSE_ID, Input.mousePosition, deadZoneThreshold);
            }
        } else if (Input.GetMouseButtonUp(0)) {
            // Technically a mouse can be clicked and released in the same frame.
            // We'll handle the release for the click-release case.
            // For the release-then-click case, the swipe start just gets
            // overwritten above, so it's safe to ignore.
            EndSwipe(MOUSE_ID);
        }
    }
}

```

---
Tags: unity, c#, android, touch, multitouch
---


# Question
Title: How to develop both a client and headless server together in Unity
I'm making a multiplayer 2d shooter platformer in unity. And after studying the different options to program an authoritarian server and with the great help that many of you have already provided me on this site. I have decided to create my server also with a unity in headless mode in order to reproduce or simulate the physics of the games on the server with the same engine (box2d) and that the server is the one that decides the movements of the clients.

As you have told me (Thanks @DMGregory), a good option for server development in unity is to use a single project to program both client and server and thus be able to reuse the scenes and prefabs without having to clone them in 2 different projects, but with This idea I find some main problems that I do not know how to solve.

1. **Debugging**. How can I run the 2 editors of the same project in unity simultaneously to run server and client?
2. **Separate client and server**. Is there a way to separate those elements necessary for the client from those necessary for the server in unity? If not, when compiling my project to use it as a server, it will have a lot of unnecessary material (scripts, sprites, prefabs, etc.) that will make the program more heavy without necessity.

Thank you very much and sorry for my level of English

# Answer
> 7 votes
Myself, I'd recommend keeping the server and client authored in a single Unity project. This minimizes the chance for mistakes where you change something in either the server or client and miss updating the other, resulting in divergent behaviour or major errors.

You could approach it in other ways, like bundling everything needed by both client and server into a shared library and asset pack referenced in each separate project, but that's extra hoops to jump through every time you change something.

Instead, we can keep everything in one project, and use preprocessor directives to control what gets built into the client versus server. Code wrapped in an `#if SERVER_BUILD ... #endif` pair will be compiled only if you've defined the `SERVER_BUILD` symbol in this compilation pass.

We can add our `SERVER_BUILD` symbol under Build \> Player Settings... \> Other Settings \> Configuration\> Scripting Define Symbols when we're exporting a server build, or leave it out when compiling for the client.

You can automate this with a custom build script or command line shortcut, so you can export either a client or server build on demand without manually twiddling the settings every time.

To avoid littering your code with `#if` directives all over the place, you can take advantage of a feature in C# called partial classes. This lets you split the definition of a single class between multiple files, and we'll use it to group together the common, client, and server-specific functionality we need.

First we'll define a partial class that has just the stuff that's always needed - no matter whether we're a server build or a client. Here's a very barebones example:

```
public partial class PlayerController : MonoBehaviour
{
    // Common variables needed on both server and client go here.
    public float movementSpeed;

    void Start() {
        // Common start-up code needed on both server and client
        // can be written here.

        // Call serve/client-specific start-up behaviour,
        // depending on which one we are.
        OnStartup();
    }

    void Move(Vector2 input) {
        // TODO: implement move logic.
        // Note that here, we don't know whether the input
        // came from a locally-connected gamepad/keyboard,
        // or a network packet. We can handle it agnostically.
    }
}

```

Note that this class has no notion of the source of input, or that the player has a model/sprite/animator at all, since only the client needs to worry about that stuff.

Then we can have a separate file, call it `PlayerController_client.cs` that expands on this with client-specific needs and implementations. We wrap the whole thing inside an `#if !SERVER_BUILD || UNITY_EDITOR` directive, so when we're compiling a server build, the compiler sees this as an empty file and it has no effect on the code that's generated or the data that's packed. But we still keep our public/serializable fields to be able to edit them in the Inspector, and persist our work as we toggle our build flags back and forth.

Any methods that might have conflicting definitions for the server vs the client should be in their own chunk that you restrict to just that version - rather than making an exception for the editor as we do for our serialized fields.

```
#if !SERVER_BUILD || UNITY_EDITOR
using UnityEngine;

public partial class PlayerController : MonoBehaviour
{
    // Client-only serialized fields, also accessible in editor.

    public Animator visualPrefab;
    public string horizontalAxis;
    public string verticalAxis;

    // Client-only methods and unserialized data.
    // We don't use the || UNITY_EDITOR
    // exception here, to ensure we don't conflict with the
    // server file's method definitions.
    #if !SERVER_BUILD

    Animator _visual;
    Camera _camera;

    void OnStartup() {
        _visual = Instantiate(visualPrefab, transform);
        _camera = Camera.main;
    }

    private void Update() {
        // Capture input from client's controller.
        Vector2 input = new Vector2(Input.GetAxis(horizontalAxis),
                                    Input.GetAxis(verticalAxis));

        // TODO: SendInputToServer(input);

        // Locally predict the movement based on this input.
        Move(input);

        // Update our animation states accordingly.
        _visual.SetFloat("horizontal", input.x);
        _visual.SetFloat("vertical", input.y);

        // TODO: Handle applying corrections from server in case of bad predictions.
    }
    #endif
}
#endif

```

Here the visual representation of the player character isn't part of the character prefab. We spawn it from its own prefab in Start. (You could also do this in an editor callback if you need to position player avatars visually in the scene when setting up maps)

Because this reference to the visual prefab is only present in the client version, when we compile a server version the visual model is completely unreferenced, and Unity can optimize your build by excluding that model, animation data, materials, textures, etc. from the server version of the game.

Note that we still call into the same `Move()` function that's shared between the server and client functions. So any changes we make to that movement logic will take effect identically between server and client.

We can make another partial class for the server-specific functionality. In that version, our `Update` method will take its input from the network messages received from the client, instead of trying to read a local gamepad. But again we'll call into the same `Move()` function to get consistent simulation rules. And we'll skip the overhead of updating the character's animation state, since the server doesn't care about that detail (as long as you're not using animation events to affect gameplay beheviour - if you do that, then you'd want to move the animation logic into the shared file).

This basic strategy will let you very efficiently strip-out functionality or assets you don't need for one platform or another at compile time, and switch between implementations appropriate for each. Doing it in separate files through partial classes helps you keep the code organized, and clearly separate responsibilities - one member of your team could be updating the server logic while another one edits the client-side feedback, without versioning conflicts.

---
Tags: unity, box2d, multiplayer, client-server, server
---


# Question
Title: How can I sample objects color based on position and apply to an object in a shader?
I think what I want to achieve is similar to how grass can get the terrain color so it looks more blended, though this is not what I will be doing.

My texture is a palette of colors:

I have created a basic example in Unity. The cube represents an object that could be placed (and moved again later). The plane with the colors uv mapped would act as the ground (this will become a more complex mesh).

How can I sample the color and apply it to the object placed?

Edit:

If the object is over more than one color, then ideally I would like to blend those colors instead of having a hard transition.

# Answer
> 2 votes
I wrote this answer based on your initial reply "All one colour would be fine" - so it doesn't handle weighted blending. If you want that, it's doable, but would take more work.

The basic strategy goes like this:

* Each frame in Update, we fire a ray to see what part of the ground we're over.
* We read the texture coordinate of the point the ray hit to figure out which part of the palette texture is displayed there.
* We apply that texture offset to our own renderer's material that's using that same colour palette texture, so we sample the same colour as the point we hit.

This sample is written for the built-in render pipeline. If you're using the URP/HDRP or a custom scriptable render pipeline, you'd likely want to do away with material property blocks and instead create a copy of the material and set the UV offset there directly - the SRP batcher handles that more efficiently than the built-in pipeline's property blocks.

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

[RequireComponent(typeof(Renderer))]
public class ColourMatcher : MonoBehaviour {
    [Tooltip("What physics layers should our raycast check for colour sources?")]
    public LayerMask colourSource;

    Renderer _renderer;
    static MaterialPropertyBlock _materialProperties;
    static int _textureScaleOffsetID = Shader.PropertyToID("_MainTex_ST");

    void Start() {
        _renderer = GetComponent<Renderer>();
        if(_materialProperties == null)
            _materialProperties = new MaterialPropertyBlock();
    }

    void Update() {
        // Create a ray fired downward from our center.
        var ray = new Ray(transform.position, Vector3.down);

        // Check to see what the ray hits.
        if (Physics.Raycast(ray, out RaycastHit hit, colourSource)) {
            // If we hit something, take the UV coordinate of the hit,
            // and apply it as our texture offset.

            // The x and y components of the ST vector are the scale.
            // I set these to zero so all parts of the cube sample the same point.
            Vector4 scaleTranslate = Vector4.zero;

            // The z and w components of the ST vector are the translation.
            // I set these to match the UV of the part of the texture that we hit.
            scaleTranslate.z = hit.textureCoord.x;
            scaleTranslate.w = hit.textureCoord.y;

            // Set our renderer to use this texture scale and offset,
            // rather than whatever the default for the material was.
            _materialProperties.SetVector(_textureScaleOffsetID, scaleTranslate);
            _renderer.SetPropertyBlock(_materialProperties);
        } else {
            // If our raycast hits nothing, by default we'll just keep our previous colour.
            // But you could modify this to switch to a default colour instead here.
        }
    }
}

```

To extend this to do a weighted blend of colours, we would...

* Fire multiple rays around the cube to sample multiple points (the more points, the smoother the blend and the more sensitively we can catch small corners of a different colour)
* For each UV coordinate we find, look up the corresponding pixel from the texture (which now needs to be marked CPU readable) to find the colour
* Average the colours from all our hits
* Blend our material's current \_Color property toward this target, to have it fade smoothly instead of snapping.

Or, an alternative:

* Set up a second camera that looks straight down, orthographically capturing our ground geometry. It should use a layer mask to ignore any other visual objects
* Output what that camera sees into a RenderTexture
* Use that RenderTexture in our cube's material
* In the cube's shader, find the position of the center of the cube in the second camera's field of view (you can use a script to save its inverse view matrix as a shader variable)
* Sample the RenderTexture at that point with bilinear filtering, or average samples from several nearby samples, to get the average colour the camera sees there.

You may need to use shader replacement with this strategy to exclude the effects of lighting, which could tint what gets captured into the RenderTexture if you're not using unlit materials.

---
Tags: unity, shaders, uv-mapping
---


# Question
Title: Why won't my integer go down when my function is called?
I'm trying to implement a limited-use slow-mo power into my game using C#, but I can use it infinitely. Why won't my integer go down when my function is called?

```
using UnityEngine;

public class TimeManager : MonoBehaviour
{
    public float slowdownFactor = 0.05f;
    public float slowdownLength = 2f;
    public int slowmos = 5;

    private void Update()
    {
        Time.timeScale += (1f / slowdownLength) * Time.unscaledDeltaTime;
        Time.timeScale = Mathf.Clamp(Time.timeScale, 0f, 1f);
    }

    public void SlowMo()
    {
        if (slowmos != 0)
        {
            Time.timeScale = slowdownFactor;
            Time.fixedDeltaTime = Time.timeScale * .02f;
            slowmos--;
        }
    }
}

------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
------------------------------------------------------------------------

public class charcterMovement : MonoBehaviour
{
    public TimeManager timemanager;
    public Rigidbody rb;
    public float forwardForce = 1000f;
    public float rightForce = 100f;
    public float leftForce = -100f;

    // Start is called before the first frame update
    void Start()
    {
        rb.useGravity = true;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime, ForceMode.VelocityChange);
        //Set Speed To Cube

        if (Input.GetKey("d"))
        {
            rb.AddForce(rightForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("a"))
        {
            rb.AddForce(leftForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("space"))
        {
            timemanager.SlowMo();
        }
    }
}

```

# Answer
> 1 votes
There are a few problems, lets go over them one by one.

For the start, don't use `if (slowmos != 0)`. If for some reason your slowmos drops to negative, you have infinite slowmos since it is never 0 and you happily subtract just another slowmo. Better is to just check if you have more than 0 `if (slowmos > 0)`.

The next problem is `if (Input.GetKey("space"))`. GetKey returns true as long as it is pressed, as long as it is pressed. With 60fps your slowmos are gone like instant. Together with the first problem, it could be reduced into negative values. Use `if (Input.GetKeyDown("space"))` instead. This returns once true so your slowmo is only called on the first space pressed.

Now that we use the correct method, it needs to move to the correct update method. While fixedUpdate is correct for physic manipulation, if you leave the new GetKeyDown there, it won't always capture your pressed key events. You did not had the problem with skipped key input, since your GetKey was spamming slowmo with USE IT, USE IT.

Last thing is, you should take a look at the input manager from unity. It allows you easier bindings of keys (maybe user want to remap later the slowmo to not space but ctrl - whatever). The code would change to `Input.GetButtonDown("SlowMo")`. You need to define SlowMo in the input manager, switch Key to Button but else it is working the same. And it makes your code way nicer to read.

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


# Question
Title: Despite the connect() method returning 0 (enum), the function specified in the connection is not called
The subject script:

```
    extends ColorRect

onready var subject = get_parent().get_node('Page1')

func _ready():
    var error = subject.connect('set_timer', self, 'ad')

func ad():
    print('signal connected')

```

# Answer
> 1 votes
You are setting the function `ad` to run when the signal `set_timer` is emitted (not when it is connected). I cannot find an standard `set_timer` signal (for reference `Timer` nodes have a `timeout` signal, perhaps that is what you want?). I'd suppose it is a custom signal you created. If you are not emitting that signal, Godot will not call `ad` for you.

To emit a custom signal, in the script attached to the subject (`Page1`), call `emit_signal("set_timer")`. See Godot documentation on `emit_signal`.

The following code is taken from Godot documentation on Sigals:

```
extends Node2D

signal my_signal

func _ready():
    emit_signal("my_signal")

```

If you try to emit a signal that does not exist, you will get an error in the console like this one:

```
emit_signal: Can't emit non-existing signal "set_time".

```

However, in your case, I believe the signal exist, otherwise, when connecting you would have got the following error:

```
connect: In Object of type 'ColorRect': Attempt to connect nonexistent signal 'set_time' to method 'ColorRect.ad'

```

---
Tags: godot, scene
---


# Question
Title: Why does my godot game not take input in the browser?
My game works perfectly fine in godot and as a widows executable but when exported to html5, I can't move my character.

The game is publicly available at https://ashir-rashid.itch.io/export-experiment

There is something fishy going on in the web console(chrome).

I exported a gui app made in goodt on itch.io which worked absolutely fine. I think the problem is in taking the keyboard input.

I've been stuck here for too long. Any help will be highly appreciated. Thanks in advance.

The console log:

```
[Intervention] Slow network is detected. See https://www.chromestatus.com/feature/5636954674692096 for more details. Fallback font will be used while loading: https://static.itch.io/fonts/lato-v14-latin-700.woff2
export-experiment:1 [Intervention] Slow network is detected. See https://www.chromestatus.com/feature/5636954674692096 for more details. Fallback font will be used while loading: https://static.itch.io/fonts/lato-v14-latin-regular.woff2
export-experiment:1 [Intervention] Slow network is detected. See https://www.chromestatus.com/feature/5636954674692096 for more details. Fallback font will be used while loading: https://static.itch.io/icons/fonts/icomoon.ttf?4ibnvg
export-experiment:1 [Intervention] Slow network is detected. See https://www.chromestatus.com/feature/5636954674692096 for more details. Fallback font will be used while loading: https://static.itch.io/fonts/lato-v14-latin-900.woff2
lib.js?1600863858:3 Allow attribute will take precedence over 'allowfullscreen'.
ca @ lib.js?1600863858:3
index.js:7 Godot Engine v3.2.2.stable.official - https://godotengine.org
index.js:7 OpenGL ES 2.0 Renderer: WebKit WebGL
index.js:7 OpenGL ES 2.0 Batching: ON
index.js:7
index.js:7 **WARNING**: Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7
index.js:7    At: scene/main/scene_tree.cpp:1153:_update_root_rect() - Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p1.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p1.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p1.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p1.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p1.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p1.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **WARNING**: Couldn't load external resource: res://Scripts/p1.gd
put_char @ index.js:7
index.js:7    At: scene/resources/resource_format_text.cpp:175:_parse_ext_resource() - Couldn't load external resource: res://Scripts/p1.gd
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p2.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p2.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p2.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p2.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p2.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p2.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **WARNING**: Couldn't load external resource: res://Scripts/p2.gd
put_char @ index.js:7
index.js:7    At: scene/resources/resource_format_text.cpp:175:_parse_ext_resource() - Couldn't load external resource: res://Scripts/p2.gd
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Indented block expected after declaration of "_process" function.
put_char @ index.js:7
index.js:7    At: res://Scripts/Boss.gdc:8:GDScript::load_byte_code() - Parse Error: Indented block expected after declaration of "_process" function.
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/Boss.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/Boss.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Indented block expected after declaration of "_process" function.
put_char @ index.js:7
index.js:7    At: res://Scripts/Boss.gdc:8:GDScript::load_byte_code() - Parse Error: Indented block expected after declaration of "_process" function.
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/Boss.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/Boss.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **WARNING**: Couldn't load external resource: res://Scripts/Boss.gd
put_char @ index.js:7
index.js:7    At: scene/resources/resource_format_text.cpp:175:_parse_ext_resource() - Couldn't load external resource: res://Scripts/Boss.gd
put_char @ index.js:7
export-experiment:1 Uncaught (in promise) DOMException: screen.orientation.lock() is not available on this device.
index.js:7 **WARNING**: Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7
index.js:7    At: scene/main/scene_tree.cpp:1153:_update_root_rect() - Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p1.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p1.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p1.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p1.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p1.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p1.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **WARNING**: Couldn't load external resource: res://Scripts/p1.gd
put_char @ index.js:7
index.js:7    At: scene/resources/resource_format_text.cpp:175:_parse_ext_resource() - Couldn't load external resource: res://Scripts/p1.gd
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p2.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p2.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p2.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:829:load_source_code() - Condition "err" is true. Returned: err
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load source code from file 'res://Scripts//player.gd'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2285:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts//player.gd.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **SCRIPT ERROR**: Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7    At: res://Scripts/p2.gdc:1:GDScript::load_byte_code() - Parse Error: Couldn't load the base class: res://Scripts//player.gd
put_char @ index.js:7
index.js:7 **ERROR**: Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:801:load_byte_code() - Method failed. Returning: ERR_PARSE_ERROR
put_char @ index.js:7
index.js:7 **ERROR**: Cannot load byte code from file 'res://Scripts/p2.gdc'.
put_char @ index.js:7
index.js:7    At: modules/gdscript/gdscript.cpp:2281:load() - Condition "err != OK" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **ERROR**: Failed loading resource: res://Scripts/p2.gdc.
put_char @ index.js:7
index.js:7    At: core/io/resource_loader.cpp:278:_load() - Condition "found" is true. Returned: RES()
put_char @ index.js:7
index.js:7 **WARNING**: Couldn't load external resource: res://Scripts/p2.gd
put_char @ index.js:7
index.js:7    At: scene/resources/resource_format_text.cpp:175:_parse_ext_resource() - Couldn't load external resource: res://Scripts/p2.gd
put_char @ index.js:7
index.js:7 **WARNING**: Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7
index.js:7    At: scene/main/scene_tree.cpp:1153:_update_root_rect() - Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.
put_char @ index.js:7

```

# Answer
Cause of the problem: I have two scripts named p2.gd and p1.gd inheriting from a base player class. I had not named the base class. So, my p1 and p2 scripts contained references to player.gd in terms of paths.

Solution: I used the class\_name variable in gdscript to name the class and then refered to it in p1 and p2 scripts in terms of its name.

Although I solved the problem, I am not able to explain ,at a lower level, what caused it. Any information regarding this will be highly appreciated.
> 2 votes

---
Tags: html5, godot, export
---


title: Godot - Offscreen Target Indicator

text:
# Question
Title: Godot - Offscreen Target Indicator
I have a crosshair image that will lock onto enemies that are visible in the camera and will stay on the edge of the screen when the enemy is offscreen. This works until you face more than 90º away from the enemy in either direction. If facing exactly 180º from the enemy, the indicator will appear as thought the enemy were directly in front of the camera but I would like it to stick to the closest edge of the screen instead. The red crosshair is drawn onto a 2d space and positioned within the camera view.

On screen:

Slightly offscreen:

Very offscreen:

```
        var enemy_pos:Vector3 = enemy.global_transform.origin
        var screen_pos:Vector2 = camera.unproject_position(enemy_pos)
        var lock:TextureRect = $TargetLock
        var lock_size:Vector2 = lock.texture.get_size()
        var crosshair_center:Vector2 = crosshair.rect_position + crosshair.rect_size * 0.5

        var direction_to_enemy := (enemy_pos - camera.global_transform.origin).normalized()
        var direction_facing := -camera.global_transform.basis.z

        # currently unused, > 0 = target within 90º rotation
        # var facing_target = direction_facing.dot(direction_to_enemy)

        var screen_width = ProjectSettings.get_setting("display/window/size/width")
        var screen_height = ProjectSettings.get_setting("display/window/size/height")

        screen_pos -= lock_size / 2
        screen_pos.x = clamp(screen_pos.x, 0, screen_width - lock_size.x)
        screen_pos.y = clamp(screen_pos.y, 0, screen_height - lock_size.y)

        lock.set_position(screen_pos)

```

I can understand the issue, but my vector math in 3d space is not good enough to solve this issue.

# Answer
The dot product should tell you if the camera is looking roughly at the enemy or away from it. You have it in comments:

```
var facing_target = direction_facing.dot(direction_to_enemy)

```

Now, if that is less than 0, it means the camera is looking away from the enemy. In that case, take `screen_pos` and scale it, such that when you `clamp` it it will be on the edge of the screen.

Compute the center of the screen:

```
var screen_center = Vector2(screen_width * 0.5, screen_height * 0.5);

```

Then take the position form the center, scaled up (I'm using `screen_width` as scale factor), and offset by the center (to have it back from the top-left corner):

```
screen_pos = (screen_pos - screen_center) * screen_width + screen_center;

```

Clamp that as usual, and it should give you a position on the edge of the screen. Except when `screen_pos` and `screen_center` are equal. Hopefully that is acceptable.
> 1 votes

---
Tags: mathematics, vector, godot
---


# Question
Title: What should I enter in Debug user and Release User in android export section in Godot?
I just want to export to android.

I have tried by adding my name, I got install error.

# Answer
When you create your keystore, you set an alias. Taking the example of the debugkeystore from the documentation:

```
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999

```

The alias is `androiddebugkey` (set with `-alias`. That is what you should put as Debug User. Whatever you wrote for `-alias` when you generated your release keystore is what you should put for Release User.

---

If you forgot you alias but still have your password, you can run

```
keytool -list -keystore <name of keystore file>

```

The keytool will ask for the password. Once entered it will list the entries on the keystore. There should be one entry. The alias is name of the entry. *And that is what you put as user in Godot.*
> 1 votes

---
Tags: godot
---


# Question
Title: How to make attention grabbing notifications?
A lot of my play-testers miss the tutorial notifications in my game. The notifications fade into the screen and fade out after the player progresses away from where the tutorial was relevant. I've tried adding a moving gif (the little orange thing in picture below) but it still doesn't draw enough attention. Could someone please recommend me some options for how I can catch the user's attention better?

In the example below, the player is given their first "key item" in the game and I want to direct them to click on the "Special" items tab. About 60% of my play-testers open it up, while the other 40% skip past it by clicking the "Search" button to progress to the next part of the tutorial. Then some time later, when the player needs to check their "Special" items, they don't know where they are.

I'm a little unsure if I should prevent the player from progressing until they perform certain actions the tutorial asks. I feel it makes the game feel rigid, but as my game is more turn-based with decision buttons, its like I can teach them they can push blocks to make a staircase to get over a tall hill as one would in a simple platformer.

# Answer
> 2 votes
When you want the player to complete a tutorial before they progress, then it usually helps a lot to give the player a good reason to complete that tutorial.

The direct way to do that is to simply prevent the player from progressing before they learned the mechanic you want to teach them. For example, if you want to teach the player how to jump, put the tutorial tooltip in front of an obstacle which blocks the only way to progress and which the player can only pass by jumping. If you want to be even more direct, **trap** the player in a situation which they can only escape by jumping. That way they can not even come to the false conclusion that progression is impossible here and backtrack without learning the mechanic.

If you want to be more indirect and more considerate of player agency, then it can be helpful to promise a reward for learning the mechanic. Place some reward in a place where it is very visible and attention-grabbing, but can only be reached by using that mechanic. For example, if you want to teach the player how to climb ladders, then create a very plain and boring passage. Then add a ladder in the middle of that passage with a very visible treasure on top. With nothing else to distract them, the players attention will immediately be caught by the treasure. They will look for a way to reach it. That's where they will appreciate the tooltip telling them how to climb the ladder.

Regarding your problem with the user not remembering the tooltip about the "Special" tab: Don't give them that tutorial popup when they first encounter an item which goes there. Give it to them when they first need to use the item which can be found there. Ideally you would pace it in a way that this happens immediately after receiving that item, so they still remember getting it.

# Answer
> 3 votes
> The notifications fade into the screen (…)

Don't do that. Making them appear suddenly would catch more attention.

With that said, motion is probably a good idea. You can make the notification slide in the viewport.

Another thing to try is to have a sound effect associated with it. As long as it does not bothers the players too much.

*We could argue for other stuff to draw more attention to it, however, we would be into annoying territory.*

---

How exactly do you design your tutorial? Usual wisdom is to stop the player until they perform whatever they are supposed to learn (be it from following instructions or figuring it out by themselves). *Then again, over do it with the notifications, and you are in hand holding territory (notifications says do x, then do y, and so on).*

For example, if you need to teach how to break objects. Put breakable objects blocking the way. A good pattern is to:

* Provide a safe space for the players to try out the mechanic.
* Place some obstacle that can only be surpassed with the mechanic.
* Give the player more advanced challenges involving the mechanic.
* Give the player challenges that involve using the mechanic in conjunction with others.

Plan ahead how you would do that for every mechanic you introduce. In fact, your tutorial does not need to look like a tutorial. Nor be front loaded. You can spread it out, and teach mechanics as the player unlocks them.

If players are having difficulties with learning the mechanics, consider working on the mechanics to make them more intuitive (see the concept of Affordance). In fact, some hints can be useful. For example have some way to highlight objects with which the player can interact with (perhaps that can be disabled via menu). *Which reminds me of assist mode, but that is another tale.*

---
Tags: game-design, gui, tutorials
---


# Question
Title: Why does Unity launch Visual Studio but opens files in Notepad?
In Unity 5.2.0f3, when I double-click a C# script, it effectively launches Visual Studio Community 2015 but then opens the source code file in Notepad instead of inside the Visual Studio IDE.

How can I make sure that source code is opened inside Visual Studio (the one Unity started)

*Investigation Notes:*

1. It happens both from double-clicking an attached script the inspector or the script icon in the project/assets panel.
2. Although the specific file is not open, the "Class View" in the VS IDE loads that I'm in MyGame.CSharp and MyGame.CSharp.Editor, so some kind of interaction must happen.
3. It happened to me that initially Visual Studio claimed it was in "expired trial mode", then I created a MS account and bound it to the the VS. Don't know if this had any effect on that.
4. I can't tell if it was working previously, as I come from a Unity version that used to use MonoDevelop.

# Answer
Well, it is not a matter of Unity. In fact, Unity sends the file to the Visual Studio and it is Visual Studio that re-sends it into a NotePad.

**Reason**

The reason behind is that VS does not open all the files. The file I was trying to open is legacy source code that, for some reason, did contain the ASCII `ETX` character (`0x03`) in it.

Visual Studio seems to reject non-perfectly-formatted files.

**How to repeat**

In fact, the error can be repeted without unity at all and playing only with the filesystem and the Visual Studio.

I just started by making a drag-and-drop from the Explorer into the VS, like this:

Visual Studio finds the file as "invalid" and does not want to open it. So it launches Notepad:

You can see it directly starts with the text `using`. This is what the file looked like (dumped with OctalDump dumping "hexa" in one line and "ascii" in the other, in a Linux machine):

You can see it really starts with the text `using` at byte 0. You can see the rare character there (`0x03`, `ETX`).

I then opened the file into Sublime Text. You can see the `ETX` there in the middle:

**Solution**

What then I did is to tell Sublime to add the UTF-8 BOM header into the file, so it should be, at least, "more compatible" than finding weird characters without telling anything.

This is what the file looks like now in a hex dump:

So you can there see first the BOM header at bytes 0, 1 and 2, then the `using` word starting at byte number 3. Still you can see the `ETX` invalid char there inside.

Now, you drag-n-drop the file into Visual Studio, and it opens it:

Finally, and for the sake of testing, I just duble-click within Unity and yes, it opens within Visual Studio:

*Note 1:*

If I remove ALL invalid characters from a file, then, even if the file does not have a BOM header, VS properly opens the file. But as this is legacy code and I don't know why another coder put the `ETX` there, I can't just remove it and let it go... I need to keep the source as untouched. So adding the BOM was the solving solution.

*Note 2:*

It happened to me with the `ETX` invalid char, but I guess this is extensible to any non-printable basic-ascii127 character.
> 3 votes

# Answer
I found another reason. On the PC where I had Windows 7 I had the Visual Studio `devenv.exe` program set to open as administrator (every time). Unity was NOT opening as administrator, and as such, when Visual Studio was being launched by Unity, Notepad opened first, followed by a blank Visual Studio window. As soon as I right-clicked the Unity icon and selected `Run as administrator` it was all good, so I just updated the shortcut properties to always run Unity as administrator (right-click, then `Properties->Advanced->Run as administrator`).

In summary, if the security context is different, it will most likely cause this issue as well.
> 0 votes

# Answer
i had this problem with Unity 2020.x and Visual Studio 2019 (happened after testing Rider editor and then switched back to VS)

Solution:

* Edit Preferences, External Script editor: Set to VS2019 (if not already)
* Assets/Open C# project (this opens VS2019, and now double clicking scripts also open in VS2019)

\*Nevermind: it still opens with notepad after restarting Unity
> 0 votes

---
Tags: unity
---


# Question
Title: What is the equivalent for "(Input.GetAxisRaw(Horizontal))" in the new Input System?
I'm making a 2D platformer game with Unity and I have some problems with the new Input System. Also, I'm using PlayerInput component with invoke unity events behavior. In fact, I downloaded a player controller code from GitHub to use it as a guide so I used it in my actual player controller. But there is a problem and that is the code is using the old Input and I don't know how to change "Input.GetAxis" and what is the equivalent in the new system. I've read many documents about it and I know that there is no official equivalent but there should be a way to get the same output. And other than this you may find some mistakes in the code and I would appreciate If you guide me. Thanks in advance.

This is my Player Controller.

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

public class PlayerController : MonoBehaviour
{
    private PlayerInputActions controls;

    private Rigidbody2D rb;
    private Animator anim;
    private bool facingRight = true;
    private float moveInput;
    public Transform feetPos;
    public float jumpInput;
    public float speed;

    [SerializeField] float JumpVelocity = 5;
    float JumpPressedRemember = 0;
    [SerializeField] float JumpPressedRememberTime = 0.2f;

    float GroundedRemember = 0;

    [SerializeField] float GroundedRememberTime = 0.25f;
    [SerializeField] float HorizontalAcceleration = 1;
    [SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
    [SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
    [SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
    [SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;

    private void Awake()
    {
        controls = new PlayerInputActions();
    }

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        moveInput = context.ReadValue<float>();
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        JumpVelocity = context.ReadValue<float>();
    }

    void FixedUpdate()
    {
        rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);

        if (facingRight == false && moveInput > 0)
        {
            Flip();
        }
        else if (facingRight == true && moveInput < 0)
        {

            Flip();
        }
    }

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

    void Update()
    {
        Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
        Vector2 GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
        bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0);

        GroundedRemember -= Time.deltaTime;

        if (Grounded)
        {
            GroundedRemember = GroundedRememberTime;
        }

        JumpPressedRemember -= Time.deltaTime;

        if (controls.Player.Jump.triggered)
        {
            JumpPressedRemember = JumpPressedRememberTime;
        }

        if (controls.Player.Jump.triggered)
        {
            if (rb.velocity.y > 0)
            {
                rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * JumpHeight);
            }
        }

        if ((JumpPressedRemember > 0) && (GroundedRemember > 0))
        {
            JumpPressedRemember = 0;
            GroundedRemember = 0;
            rb.velocity = new Vector2(rb.velocity.x, JumpVelocity);
        }

        float HorizontalVelocity = rb.velocity.x;
        HorizontalVelocity += Input.GetAxisRaw("Horizontal");

        if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) < 0.01f)
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
        else if (Mathf.Sign(Input.GetAxisRaw("Horizontal")) != Mathf.Sign(HorizontalVelocity))
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
        else
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);

        rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
    }
}

```

And this is the code that I downloaded from GitHub.

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

public class PlayerMovement : MonoBehaviour
{
[SerializeField]
LayerMask lmWalls;

[SerializeField]
float fJumpVelocity = 5;

Rigidbody2D rigid;

float fJumpPressedRemember = 0;
[SerializeField]
float fJumpPressedRememberTime = 0.2f;

float fGroundedRemember = 0;
[SerializeField]
float fGroundedRememberTime = 0.25f;

[SerializeField]
float fHorizontalAcceleration = 1;
[SerializeField]
[Range(0, 1)]
float fHorizontalDampingBasic = 0.5f;
[SerializeField]
[Range(0, 1)]
float fHorizontalDampingWhenStopping = 0.5f;
[SerializeField]
[Range(0, 1)]
float fHorizontalDampingWhenTurning = 0.5f;

[SerializeField]
[Range(0, 1)]
float fCutJumpHeight = 0.5f;

void Start ()
{
    rigid = GetComponent<Rigidbody2D>();
}

void Update ()
{
    Vector2 v2GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
    Vector2 v2GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
    bool bGrounded = Physics2D.OverlapBox(v2GroundedBoxCheckPosition, v2GroundedBoxCheckScale, 0, lmWalls);

    fGroundedRemember -= Time.deltaTime;
    if (bGrounded)
    {
        fGroundedRemember = fGroundedRememberTime;
    }

    fJumpPressedRemember -= Time.deltaTime;
    if (Input.GetButtonDown("Jump"))
    {
        fJumpPressedRemember = fJumpPressedRememberTime;
    }

    if (Input.GetButtonUp("Jump"))
    {
        if (rigid.velocity.y > 0)
        {
            rigid.velocity = new Vector2(rigid.velocity.x, rigid.velocity.y * fCutJumpHeight);
        }
    }

    if ((fJumpPressedRemember > 0) && (fGroundedRemember > 0))
    {
        fJumpPressedRemember = 0;
        fGroundedRemember = 0;
        rigid.velocity = new Vector2(rigid.velocity.x, fJumpVelocity);
    }

    float fHorizontalVelocity = rigid.velocity.x;
    fHorizontalVelocity += Input.GetAxisRaw("Horizontal");

    if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) < 0.01f)
        fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * 10f);
    else if (Mathf.Sign(Input.GetAxisRaw("Horizontal")) != Mathf.Sign(fHorizontalVelocity))
        fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * 10f);
    else
        fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * 10f);

    rigid.velocity = new Vector2(fHorizontalVelocity, rigid.velocity.y);
}

```

# Answer
> 0 votes
Finally, I can now move my character. Jumping still has some problems which I will cover it on my next questions. I asked this question on Stack Overflow and I was able to fix my problem with the help of a friend. Since the answer is long and it continues with more than 10 comments, I decided to put the link to my question here.

https://stackoverflow.com/questions/64019057/i-have-some-serious-problems-with-new-input-system/64066014?noredirect=1#comment113359107\_64066014

---
Tags: unity, c#, platformer, jumping
---


# Question
Title: Optimizing a quadtree for circles and circular queries
I'm developing a 2D ant simulation in JavaScript. I'd like to implement a quadtree to store the positions of ants and other markers. I approximate all of these entities as circles, and I'm only querying for circles that fall within the radius of a query circle.

Most of the things I've read about quadtrees implement rectangular entities/queries very efficiently. Is there a more efficient way of implementing a quadtree given *all* entities/queries are circular? Otherwise I would plan to store each circle as a square and perform a circular collision check on top of each query result.

# Answer
As explained in the answer by Romen, there aren't many applicable data structures which are not based on rectangles. But there are a couple other optimizations you can do for circle-circle collisions which could reduce your demand for a more optimized data-structure.

## Compare the square of the distance with the square of the radius.

If you want to check if a point is in a circle or if two circles intersect, you have to use the Pythagorean theorem, which in its naive implementation looks like this:

```
distX = a.x - b.x
distY = a.y - b.y
radiusSum = a.radius + b.radius;

dist = sqrt(distX * distX + distY * distY);
if (dist < radiusSum) {
    // collision
}

```

Unfortunately, calculating the square-root of a number is a very expensive operation. Fortunately, you can replace that square-root with a much cheaper multiplication in this case. Just compare the squares of the sum of the radiii with the square of the distance:

```
distSquared = distX * distX + distY * distY;
if (distSquared < radiusSum * radiusSum) {
    // collision
}

```

Also note that if you want to check if **points** are within a circle, then you only need to calculate the square of the radius once. If it's always the same circle, you can even cache it. You can also cache the square of the radius sum if you compare objects which all have the same radius.

## Check bounding boxes and inner boxes first

While multiplications are cheaper than square-roots, they are still not as cheap as addition and subtraction. But what you *can* do using only subtraction and addition is comparison between two axis-aligned boxes. So by checking the inner and outer rectangles of the circles first, you can rule out or detect a lot of circle-circle collisions without having to actually check if the radii overlap.

1. If the bounding squares of two circles do not intersect, then there can not be a collision
2. If the inner squares intersect, then there must be a collision
3. If the outer squares intersect but the inner ones do not, then there *might* be a collision, which means you have to calculate the square of the distance and compare it to the square of the sum of the radii

(note that when you have a game where objects move relatively slow and overlapping objects usually don't remain overlapped, then implementing the 2nd step might not be worth it. When two objects approach each other slowly, then you will in most cases detect a circle-circle collision before you detect an inner rectangle collision)

## And if you want to check bounding boxes first...

...then a quad tree can be a useful optimization.

I personally prefer spatial hashes, though. They are easier to implement (IMO) and often work better if objects are relatively evenly distributed. But trees usually adapt better to scenarios where you have to deal with vastly different object densities.
> 3 votes

# Answer
I can't recommend a structure that actually implements what you're asking for, but it definitely won't work like a quad tree. It may not be a tree at all and it might not even exist...

A quad tree has a tree structure because each node represents the node above it divided into four quadrants. At any level these four quadrants cover *all* of the space covered by their parent. Every single point in the 2D space can be inserted at exactly one leaf node somewhere on the tree.

If you try to divide space into circles, you're not going to be able to find a set of circles that cover their parent circle *completely* and *evenly*. This geometric problem rules out the possibility that you can store these circles in a tree that will be useful to traverse for collision detection. There will always be points that are either not covered by a circle or covered by more than one circle. (That's bad because it means a point in 2D space either has nowhere to go in the tree or it has more than one place to go!)

Testing whether two circles intersect is simple, but I am not aware of anything simpler than just checking if the distance between them is less than the sum of their radii. You can save some CPU power on so many circle-circle tests by comparing the squared radii and distances and skipping the `sqrt` calculation.
> 2 votes

---
Tags: collision-detection, javascript, quadtree, spatial-partitioning
---


# Question
Title: How can I stop the ball from bouncing forever without changing the gravity?
I am using Monogame in Visual Studio 2019 and I need to find a method to make the ball that I fired with the cannon stop after bouncing from the ground, and while doing this, I have to not change the gravity.

* `gravity = 10;`
* `yFriction = 0.2;`

```
    public override void Update(GameTime gameTime)
    {
        position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

        velocity.Y += gravity;

    }
    public void CheckBounce(SpriteGameObject other)
    {
        if (!this.CollidesWith(other)) return;

        CollisionResult side = this.CollisionSide(other);
        Bounce(side);

        // Relocating the ball if it's in the wall
        switch (side)
        {
            case CollisionResult.LEFT:
                position.X = other.Position.X + other.Width + this.Center.X;
                break;
            case CollisionResult.RIGHT:
                position.X = other.Position.X - this.Center.X;
                break;
            case CollisionResult.TOP:
                position.Y = other.Position.Y + other.Height + this.Center.Y;
                break;
            case CollisionResult.BOTTOM:
                position.Y = other.Position.Y - this.Center.Y;
                break;
        }
    }

    public void Bounce(CollisionResult side)
    {
        switch (side)
        {
            case CollisionResult.BOTTOM:
                velocity.Y *= yFriction;
                Stop();
                velocity.Y *= -1;
                break;
            case CollisionResult.TOP:
                velocity.Y = Math.Abs(velocity.Y) * yFriction;
                break;
            case CollisionResult.LEFT:
                velocity.X = Math.Abs(velocity.X) * xFriction;
                break;
            case CollisionResult.RIGHT:
                velocity.X = Math.Abs(velocity.X) * -xFriction;
                break;
        }
    }
    public void Stop()
    {
        if (velocity.Y <= gravity)
        {
            velocity.Y -= velocity.Y;
        }
    }

```

At this moment it puts it's velocity.Y to 0. But the problem is the gravity. After bouncing because it doesn't collides, it keeps adding velocity to the ball. As a result I printed out this variables:

```
After gravity adding
39.01105
After gravity adding
49.01105
After Friction
9.80221
After Stop
0
After bounce
0
After gravity adding
10
After gravity adding
20
After gravity adding
30
After gravity adding
40
After Friction
8
After Stop
0
After bounce
0
After gravity adding
10
After gravity adding
20
After gravity adding
30
After gravity adding
40
After Friction
8
After Stop
0

```

And keeps so on.

***Thank you all in advance.***

# Answer
I found that I must add gravity to the velocity before add velocity to the position. And I have also changed collision code.

```
    public override void Update(GameTime gameTime)
    {
        velocity.Y += gravity;
        position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

    }
    public void CheckBounce(SpriteGameObject other)
    {
        if (!this.CollidesWith(other)) return;

        CollisionResult side = this.CollisionSide(other);
        Bounce(side);

        // Relocating the ball if it's in the wall
        switch (side)
        {
            case CollisionResult.LEFT:
                position.X = other.Position.X + other.Width + this.Center.X;
                velocity.X = Math.Abs(velocity.X) * xFriction;
                break;
            case CollisionResult.RIGHT:
                position.X = other.Position.X - this.Center.X;
                velocity.X = Math.Abs(velocity.X) * -xFriction;
                break;
            case CollisionResult.TOP:
                position.Y = other.Position.Y + other.Height + this.Center.Y;
                velocity.Y = Math.Abs(velocity.Y) * yFriction;
                break;
            case CollisionResult.BOTTOM:
                position.Y = other.Position.Y - this.Center.Y + 1;
                velocity.Y *= -yFriction;
                break;
        }
    }

```

Keeping the ball in the wall only 1 pixel solves the problem.
> 0 votes

# Answer
the simplest way is to add a lower bound at which you invert the velocity on bounce and make it larger than gravity can add in a single timestep.

```
case CollisionResult.BOTTOM:
    if(abs(velocity.Y) < MIN_BOUNCE_VELOCITY) {
        velocity.Y = 0;
    } else {
        velocity.Y *= yFriction;
        Stop();
        velocity.Y *= -1;
    }
    break;

```

Another thing you can do in addition is to track grounded state and don't add gravity when it's resting on the ground.

```
if (!grounded)
    velocity.Y += gravity;

```
> 0 votes

---
Tags: c#, physics, monogame
---


title: Bind render result to texture id

text:
# Question
Title: Bind render result to texture id
I want to save the result screen of the rendering and then apply another shader on that result, the typical way is to read the screen using **glReadPixels** and then buffer that image to gpu and then apply my effect, so is there a way to bind the screen result to a texture id directory in gpu, instead of retrieving it back to CPU and then buffer it to GPU ?

# Answer
> 0 votes
Check out this great tutorial.

Basically you need to create a new texture of the size you want, and then use glDrawBuffers.

---
Tags: opengl, c++, textures, opengl-es, image-processing
---


# Question
Title: Moving object parallel to another on path on 2d space
How to Move object parallel to another on curved path on 2d space

# Answer
> 0 votes
You are missing a lot of critical information...

If you want the black ball to follow the red ball in real time along its parallel path, you have a few options:

1. If the red ball is always facing the direction of travel, you can set the black ball as a child of the red ball, but this will have noticeable incorrect black paths if the red path has sharp turns
2. If the red ball is not always facing forward, you can use trigonometry to calculate calculate a position relative to the red ball position, i.e. left/right/above/below. This has the same problem as one that the black ball will move slightly backwards on tight turns.

If you are not "tracking" the red ball in real time and rather just have a set of points and you want to generate the black path from the red path data, you again have a few options:

1. Copy the red path and translate it along the X/Y axes to get your black path. This won't work for complex paths (imagine using this method on a U-turn shape).
2. The most general (and most complicated) method is to have your path points saved as relative to either the previous point or a common origin. Consider these paths:

Notice how different the "parallel"\* black baths are from the red paths, depending on if the black paths are right or left of the red paths. What you need to to is for each point, calculate the angle of the turn. Of course, the angle will be different depending on if you are calculating a path that is on the right or left of the original. Find the bisection of the angle of each turn, calculate some distance along that line using trig (how ever "far" your new path is from your old path), and that's your new point. Something like this:

```
public List<Vector2> calculateParallelPathRight(List<Vector2> originalPath, float distance){
    //trig magic here
}

public List<Vector2> calculateParallelPathLeft(List<Vector2> originalPath, float distance){
    //trig magic here
}

```

I'll leave working through the trigonometry to you, as it is definitely not my strong suite and would take me a lot of trial and error. But this is how I would tackle the problem.

\*P.S. Note that these lines aren't technically mathematically parallel since the definition of parallel lines is two lines that are always the same distance apart, and that does not hold true at the corners. But I suspect this is what you want.

---
Tags: unity, 2d, angles, curves, path
---