Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 屏幕外目标指示器-Unity 2D_C#_Unity3d - Fatal编程技术网

C# 屏幕外目标指示器-Unity 2D

C# 屏幕外目标指示器-Unity 2D,c#,unity3d,C#,Unity3d,我试图在屏幕外指向一个对象。这些对象是静态的 public class SpawnIndicator : MonoBehaviour { public Camera UIcamera; public GameObject point; public Canvas canvas; // Start is called before the first frame update void Start() { } // Update is called once per frame vo

我试图在屏幕外指向一个对象。这些对象是静态的

public class SpawnIndicator : MonoBehaviour
{
public Camera UIcamera;
public GameObject point;
public Canvas canvas;

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

// Update is called once per frame
void Update()
{
    if (point.GetComponent<Renderer>().isVisible)
    {
        gameObject.GetComponent<SpriteRenderer>().color = Color.clear;
    }

    else
    {
        gameObject.GetComponent<SpriteRenderer>().color = Color.white;

        //POSITION
        Vector3 pointPos = UIcamera.WorldToScreenPoint(point.transform.position);

        pointPos.z = 0;
        pointPos.x = Mathf.Clamp(pointPos.x, (Screen.width * 0.01f), (Screen.width * 0.99f));
        pointPos.y = Mathf.Clamp(pointPos.y, (Screen.height * 0.01f), (Screen.height * 0.99f));
        pointPos -= new Vector3((Screen.width/2), (Screen.height/2), 0);

        gameObject.transform.localPosition = pointPos;

        
        //ROTATION
        gameObject.GetComponent<SpriteRenderer>().color = Color.white;
        Vector3 vectorToTarget = point.transform.position - gameObject.transform.position;
        float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
        angle -= 90;
        Quaternion newRotation = Quaternion.AngleAxis(angle, Vector3.forward);
        gameObject.transform.rotation = newRotation; 
    }
    
}
}
公共类产卵指示器:单行为
{
公共摄像机;
公共游戏对象点;
公共画布;
//在第一帧更新之前调用Start
void Start()
{
}
//每帧调用一次更新
无效更新()
{
if(point.GetComponent().isVisible)
{
gameObject.GetComponent().color=color.clear;
}
其他的
{
gameObject.GetComponent().color=color.white;
//位置
Vector3 pointPos=UIcamera.WorldToScreenPoint(point.transform.position);
点位置z=0;
pointPos.x=数学夹具(pointPos.x,(屏幕宽度*0.01f),(屏幕宽度*0.99f));
点位置y=数学夹具(点位置y,(屏幕高度*0.01f),(屏幕高度*0.99f));
pointPos-=新矢量3((屏幕宽度/2),(屏幕高度/2),0);
gameObject.transform.localPosition=pointPos;
//轮换
gameObject.GetComponent().color=color.white;
Vector3 VectorTarget=point.transform.position-gameObject.transform.position;
浮动角度=Mathf.Atan2(vectortarget.y,vectortarget.x)*Mathf.Rad2Deg;
角度-=90;
四元数newRotation=四元数角度轴(角度,矢量3向前);
gameObject.transform.rotation=newRotation;
}
}
}
当屏幕尺寸为1920x1080(我的画布的参考尺寸)时,这种方法可以很好地工作。但是,在较小的尺寸下,对象位于远离边缘的位置,而在较大的尺寸下,对象位于边缘之外

把它弄明白了

WorldToScreenPoint基于参考分辨率(1920x1080)返回一个值,因此不同的分辨率不匹配。我想这就是问题所在,不管怎样,我已经找到了解决办法

我发现这个方法可以将世界位置转换为画布位置

 public static Vector3 WorldToScreenSpace(Vector3 worldPos, Camera cam, RectTransform area)
{
    Vector3 screenPoint = cam.WorldToScreenPoint(worldPos);
    screenPoint.z = 0;

    Vector2 screenPos;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screenPoint, cam, out screenPos))
    {
        return screenPos;
    }

    return screenPoint;
}
在找到解决方案之前,我还对代码的其余部分做了一些修改(巧合的是,我使用了画布大小),所以下面是完整的脚本:

public class SpawnIndicator : MonoBehaviour
{
public Camera UIcamera;
public GameObject point;
public Canvas canvas;

Vector3 pointPos;

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

// Update is called once per frame
void Update()
{
    if (point.GetComponent<Renderer>().isVisible)
    {
        gameObject.GetComponent<SpriteRenderer>().color = Color.clear;
    }
    else
    {


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

        Vector3[] canvasPoints = new Vector3[4];
        canvas.GetComponent<RectTransform>().GetLocalCorners(canvasPoints);

        Vector3 pointPos = WorldToScreenSpace(point.transform.position, UIcamera, canvas.GetComponent<RectTransform>());

        float xMin = canvasPoints[0].x * 0.98f;
        float xMax = canvasPoints[2].x * 0.98f;
        float yMin = canvasPoints[0].y * 0.8f;
        float yMax = canvasPoints[2].y * 0.98f;

        //POSITION
        if (pointPos.x <= xMin) pointPos.x = xMin;
        if (pointPos.x >= xMax) pointPos.x = xMax;
        if (pointPos.y <= yMin) pointPos.y = yMin;
        if (pointPos.y >= yMax) pointPos.y = yMax;

        pointPos.z = 0f;
        gameObject.transform.localPosition = pointPos;

        //ROTATION
        gameObject.GetComponent<SpriteRenderer>().color = Color.white;
        Vector3 vectorToTarget = point.transform.position - gameObject.transform.position;
        float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
        angle -= 90;
        Quaternion newRotation = Quaternion.AngleAxis(angle, Vector3.forward);
        gameObject.transform.rotation = newRotation;

    }
}

public static Vector3 WorldToScreenSpace(Vector3 worldPos, Camera cam, RectTransform area)
{
    Vector3 screenPoint = cam.WorldToScreenPoint(worldPos);
    screenPoint.z = 0;

    Vector2 screenPos;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screenPoint, cam, out screenPos))
    {
        return screenPos;
    }

    return screenPoint;
}
公共类产卵指示器:单行为
{
公共摄像机;
公共游戏对象点;
公共画布;
向量3点位置;
//在第一帧更新之前调用Start
void Start()
{
}
//每帧调用一次更新
无效更新()
{
if(point.GetComponent().isVisible)
{
gameObject.GetComponent().color=color.clear;
}
其他的
{
gameObject.GetComponent().color=color.white;
Vector3[]canvasPoints=新Vector3[4];
canvas.GetComponent().GetLocalCorners(canvasPoints);
Vector3 pointPos=WorldToScreenSpace(point.transform.position,UIcamera,canvas.GetComponent());
浮点xMin=canvasPoints[0].x*0.98f;
float xMax=canvasPoints[2].x*0.98f;
浮动yMin=canvasPoints[0].y*0.8f;
浮动yMax=画布点[2]。y*0.98f;
//位置
如果(pointPos.x=xMax)pointPos.x=xMax;
如果(pointPos.y=yMax)pointPos.y=yMax;
点位置z=0f;
gameObject.transform.localPosition=pointPos;
//轮换
gameObject.GetComponent().color=color.white;
Vector3 VectorTarget=point.transform.position-gameObject.transform.position;
浮动角度=Mathf.Atan2(vectortarget.y,vectortarget.x)*Mathf.Rad2Deg;
角度-=90;
四元数newRotation=四元数角度轴(角度,矢量3向前);
gameObject.transform.rotation=newRotation;
}
}
公共静态Vector3 WorldToScreenSpace(Vector3 worldPos、摄像头、矩形变换区域)
{
Vector3屏幕点=cam.WorldToScreenPoint(worldPos);
屏幕点z=0;
矢量2屏幕位置;
if(RectTransformUtility.ScreenPointToLocalPointInRectangle(区域、screenPoint、cam、out screenPos))
{
返回屏幕POS;
}
返回点;
}

}

几乎没有使用Unity的经验,但您使用的是屏幕像素宽度的百分比并乘以该百分比,但也使用画布缩放器。。。是否两者都同时被应用-画布缩放器已经在处理缩放,因此正在根据与引用的比率乘以移位?如果使用固定数量的像素偏移量,而不是依赖于0.01/0.99的乘法,会发生什么?这并没有改变它。虽然我确实觉得画布缩放可能会出现某种程度的加倍,但我不确定在何处或如何消除它:/如果关闭缩放器会发生什么?解决了它,似乎是WorldToScreenPoint忽略了当前屏幕大小,并基于参考大小(1920x1080)返回。差不多吧。我发布了一个答案:)