如何清除给定世界位置上的SpriteRenderer的像素。

huangapple go评论134阅读模式
英文:

How to clear the pixel of a spriterenderer ata given world position

问题

我有一个精灵渲染器,它被缩放以填满屏幕,我需要清除给定世界位置的像素。

我尝试将世界位置转换为屏幕点,但它被位移了,坐标越远,世界位置与转换之间的差异就越大,我想我必须使用一些数学算法,但我不擅长这方面。

英文:

I have a sprite renderer scaled to fill screen and i need to clear the pixel at a given world position.

I have tried converting world position to screenpoint but it is displaced,the farther the coord the difference is bigger between the world position and the convertion, i suppose i have to use some math algorithm but i am not good at it.

答案1

得分: 0

为了完成这个任务,你需要获取世界位置,进行一些数学计算,以使其在SpriteRenderer的范围内,并进行更多数学计算以找到其在纹理中的位置。

以下代码将在单击纹理上的像素时清除Sprite的纹理,如果你将此脚本附加到具有SpriteRenderer的GameObject上,它应该包含你要查找的内容。

using UnityEngine;

public class ClickPosition : MonoBehaviour
{
    private void OnMouseDown()
    {
        // 示例:从点击获取世界位置
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0.0f));

        SpriteRenderer renderer = GetComponent<SpriteRenderer>();

        // 获取纹理中的像素位置
        Vector2Int pixelPosition = GetPixelPositionInTexture(renderer, worldPos);

        // 对纹理中的像素执行操作
        // 在这种情况下,清除像素
        Texture2D tex = renderer.sprite.texture;
        tex.SetPixel(pixelPosition.x, pixelPosition.y, new Color());
        tex.Apply();
    }

    private Vector2Int GetPixelPositionInTexture(SpriteRenderer renderer, Vector3 worldPosition)
    {
        // 世界中SpriteRenderer的边界
        Bounds bounds = renderer.bounds;
        // 纹理中精灵的矩形
        Rect rect = renderer.sprite.rect;

        // 获取本地位置
        Vector2 localPos = worldPosition - bounds.min;

        // 标准化精灵内的位置
        Vector2 normalPos = new Vector2(localPos.x / bounds.size.x, localPos.y / bounds.size.y);

        // 获取精灵内的像素位置
        Vector2Int spritePixelPos = Vector2Int.FloorToInt(new Vector2(normalPos.x * rect.width, normalPos.y * rect.height));

        // 获取纹理内的像素位置
        Vector2Int texPixelPos = new Vector2Int(Mathf.FloorToInt(rect.x + spritePixelPos.x), Mathf.FloorToInt(rect.y + spritePixelPos.y));

        return texPixelPos;
    }
}

如果相机或SpriteRenderer已旋转或翻转,此代码将无法正常工作。它适用于缩放的GameObject以及设置为多精灵模式的Sprites。

英文:

To accomplish this, you will need take the world position, do some math to get it within the bounds of the SpriteRenderer, and then do some more math to find its position within the texture.

This code below will clear a pixel from the texture of a Sprite when you click on it, if you attach this script to a GameObject with a SpriteRenderer. It should contain what you are looking for.

using UnityEngine;

public class ClickPosition : MonoBehaviour
{
    private void OnMouseDown()
    {
        // example: get world position from click
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0.0f));

        SpriteRenderer renderer = GetComponent&lt;SpriteRenderer&gt;();

        // get pixel position in texture
        Vector2Int pixelPosition = GetPixelPositionInTexture(renderer, worldPos);

        // do what we want with that pixel to the texture
        // in this case, clear the pixel
        Texture2D tex = renderer.sprite.texture;
        tex.SetPixel(pixelPosition.x, pixelPosition.y, new Color());
        tex.Apply();
    }

    private Vector2Int GetPixelPositionInTexture(SpriteRenderer renderer, Vector3 worldPosition)
    {
        // bounds of the sprite renderer in the world
        Bounds bounds = renderer.bounds;
        // rect of the sprite within the texture
        Rect rect = renderer.sprite.rect;

        // get local position
        Vector2 localPos = worldPosition - bounds.min;

        // normalize the positon within the sprite
        Vector2 normalPos = new Vector2(localPos.x / bounds.size.x, localPos.y / bounds.size.y);

        // get the pixel positon within the sprite
        Vector2Int spritePixelPos = Vector2Int.FloorToInt(new Vector2(normalPos.x * rect.width, normalPos.y * rect.height));

        // get the pixel position within the texture
        Vector2Int texPixelPos = new Vector2Int(Mathf.FloorToInt(rect.x + spritePixelPos.x), Mathf.FloorToInt(rect.y + spritePixelPos.y));

        return texPixelPos;
    }
}

This code will not work if the camera or SpriteRenderer has been rotated or flipped. It will work with scaled GameObjects, and Sprites set to the Multiple sprite mode.

huangapple
  • 本文由 发表于 2023年6月8日 01:06:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76425622.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定