C# Unity WorldToViewPoint未给出正确的y位置
我有一个脚本,它将UI元素放置在3d空间中3d对象所在的位置。我是这样做的:C# Unity WorldToViewPoint未给出正确的y位置,c#,user-interface,unity3d,canvas,mapping,C#,User Interface,Unity3d,Canvas,Mapping,我有一个脚本,它将UI元素放置在3d空间中3d对象所在的位置。我是这样做的: public class test : MonoBehaviour { public Camera MainC; public GameObject testc; // Use this for initialization void Start () { var ui = Object.Instantiate((GameObject)Resources.Load("uit"), Vector2.zero,
public class test : MonoBehaviour {
public Camera MainC;
public GameObject testc;
// Use this for initialization
void Start () {
var ui = Object.Instantiate((GameObject)Resources.Load("uit"), Vector2.zero, Quaternion.identity);
ui.transform.SetParent(GameObject.FindObjectOfType<Canvas>().gameObject.transform, false);
var vertexs = testc.GetComponent<MeshFilter>().mesh.vertices;
var trs = testc.GetComponent<Transform>();
var cdc = new Vector2(GameObject.FindObjectOfType<Canvas>().GetComponent<RectTransform>().sizeDelta.x , GameObject.FindObjectOfType<Canvas>().GetComponent<RectTransform>().sizeDelta.y);
Object.Instantiate((GameObject)Resources.Load("pinksphere"), trs.transform.TransformPoint(vertexs[6]), Quaternion.identity); //bottomright
Object.Instantiate((GameObject)Resources.Load("pinksphere"), trs.transform.TransformPoint(vertexs[5]), Quaternion.identity); //topleft
var tl = MainC.WorldToViewportPoint(trs.transform.TransformPoint(vertexs[5]));
var topleft = new Vector2(tl.x * cdc.x, tl.y * -(cdc.y) );
ui.GetComponent<RectTransform>().anchoredPosition = topleft;
}
公共类测试:单一行为{
公共摄像机;
公共游戏对象testc;
//用于初始化
无效开始(){
var ui=Object.Instantiate((GameObject)Resources.Load(“uit”)、Vector2.zero、Quaternion.identity);
ui.transform.SetParent(GameObject.FindObjectOfType().GameObject.transform,false);
var vertexs=testc.GetComponent().mesh.vertex;
var trs=testc.GetComponent();
var cdc=new Vector2(GameObject.FindObjectOfType().GetComponent().sizeDelta.x,GameObject.FindObjectOfType().GetComponent().sizeDelta.y);
Object.Instantiate((GameObject)Resources.Load(“pinksphere”)、trs.transform.TransformPoint(vertexs[6])、Quaternion.identity);//右下角
Object.Instantiate((GameObject)Resources.Load(“pinksphere”)、trs.transform.TransformPoint(vertexs[5])、Quaternion.identity);//左上角
var tl=MainC.WorldToViewportPoint(trs.transform.TransformPoint(顶点[5]);
var topleft=新向量2(tl.x*cdc.x,tl.y*-(cdc.y));
ui.GetComponent().anchoredPosition=topleft;
}
}
但这不会将UI元素放置在所需的位置。有关更多说明,请参见以下图片
在本例中,我希望UI元素的左上角位于whitecube左上角的粉红点的顶部。但正如你所见,Y轴并不完全匹配
关于使用的画布和预设设置等条件的一些额外信息。见下图:
这些是画布设置
这是主要的相机设置
这是UI预置设置
如果你需要更多的信息或者有什么不清楚的,请告诉我,这样我可以澄清代码确实低效且丑陋,但它仅用于测试目的:)对代码进行最小的编辑,以获得所需的效果:
public class Test : MonoBehaviour
{
public Camera MainC;
public GameObject testc;
// Use this for initialization
void Start()
{
var ui = Object.Instantiate((GameObject)Resources.Load("uit"), Vector2.zero, Quaternion.identity);
ui.transform.SetParent(GameObject.FindObjectOfType<Canvas>().gameObject.transform, false);
var uiRT = ui.GetComponent<RectTransform>();
// Ensure uiRT's pivot and anchors are set to the bottom left preset.
uiRT.anchorMin = Vector2.zero;
uiRT.anchorMax = Vector2.zero;
uiRT.pivot = Vector2.zero;
var vertexs = testc.GetComponent<MeshFilter>().mesh.vertices;
var trs = testc.GetComponent<Transform>();
var cdc = new Vector2(GameObject.FindObjectOfType<Canvas>().GetComponent<RectTransform>().sizeDelta.x, GameObject.FindObjectOfType<Canvas>().GetComponent<RectTransform>().sizeDelta.y);
Object.Instantiate((GameObject)Resources.Load("pinksphere"), trs.transform.TransformPoint(vertexs[6]), Quaternion.identity); //bottomright
Object.Instantiate((GameObject)Resources.Load("pinksphere"), trs.transform.TransformPoint(vertexs[5]), Quaternion.identity); //topleft
var tl = MainC.WorldToViewportPoint(trs.transform.TransformPoint(vertexs[5]));
var offset = new Vector2(0, uiRT.sizeDelta.y);
var topleft = tl * cdc - offset;
uiRT.anchoredPosition = topleft;
}
}
公共类测试:单一行为
{
公共摄像机;
公共游戏对象testc;
//用于初始化
void Start()
{
var ui=Object.Instantiate((GameObject)Resources.Load(“uit”)、Vector2.zero、Quaternion.identity);
ui.transform.SetParent(GameObject.FindObjectOfType().GameObject.transform,false);
var uiRT=ui.GetComponent();
//确保uiRT的枢轴和锚定设置为左下预设。
uiRT.anchorMin=Vector2.0;
uiRT.anchorMax=Vector2.0;
uiRT.pivot=Vector2.0;
var vertexs=testc.GetComponent().mesh.vertex;
var trs=testc.GetComponent();
var cdc=new Vector2(GameObject.FindObjectOfType().GetComponent().sizeDelta.x,GameObject.FindObjectOfType().GetComponent().sizeDelta.y);
Object.Instantiate((GameObject)Resources.Load(“pinksphere”)、trs.transform.TransformPoint(vertexs[6])、Quaternion.identity);//右下角
Object.Instantiate((GameObject)Resources.Load(“pinksphere”)、trs.transform.TransformPoint(vertexs[5])、Quaternion.identity);//左上角
var tl=MainC.WorldToViewportPoint(trs.transform.TransformPoint(顶点[5]);
变量偏移=新向量2(0,uiRT.sizeDelta.y);
var topleft=tl*cdc-偏移量;
uiRT.anchoredPosition=左上角;
}
}
必须将UI图像的轴心和锚定设置为左下角,此操作才能正常工作:
我添加了一些代码,可以确保轴和锚都是这样设置的。您可以删除它,只要您确保预制有左下角预设,但这样更安全
这样做的理由如下:
视口坐标的0,0原点位于左下角,因此,如果设置轴并将其固定在那里,则所有轴都将对齐,并且不需要对坐标进行任何转换,这只会省去很多麻烦。剩下的唯一一件事就是减去UI图像的高度,以便使其与3D立方体垂直对齐。我假定此脚本已附加到立方体上。我认为您可以尝试将UI元素的父元素设置为画布。谢谢您的建议,我完全忘记了这一点。但遗憾的是,它没有改变任何事情,仍然存在同样的问题。查看更新的问题我看到您的答案非常有效,即使将UI元素的轴心点保持在左上角。但为什么会发生这种情况,因为我在另一个编程环境中重做了坐标转换计算,结果很好。那么,是什么导致团结失败呢?回答得好!奇怪的当我尝试使用左上角的枢轴时,它对我不起作用;它必须设置为左下角。老实说,我不确定这种怪癖的原因是什么。如果我再坐立不安,想清楚了,我会发表评论。太棒了,太棒了!