如何使用鼠标位置在 Unity 中的 2D 网格上放置图块?
How to place tiles on 2D grid in Unity using mouse position?
我正在尝试制作一个关卡编辑器,用户可以在其中单击他们想要放置图块的位置。这是代码:
using UnityEngine;
using System.Collections;
public class TilePlacement : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown (0)) {
var clickPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f);
clickPos = Camera.main.ScreenToWorldPoint (clickPos);
clickPos.z = 0f;
clickPos.x = Mathf.FloorToInt (clickPos.x);
clickPos.y = Mathf.FloorToInt (clickPos.y);
clickPos.x /= 3.2f;
clickPos.y /= 3.2f;
clickPos.x = Mathf.Round (clickPos.x);
clickPos.y = Mathf.Round (clickPos.y);
clickPos.x *= 3.2f;
clickPos.y *= 3.2f;
var go = new GameObject ();
go.AddComponent<SpriteRenderer> ();
go.GetComponent<SpriteRenderer> ().sprite = Sprite.Create(new Texture2D(32, 32), new Rect(0, 0, 32, 32), new Vector2(0, 0));
go.transform.localScale = new Vector3 (10f, 10f, 0f);
go.transform.position = clickPos;
}
}
}
此代码适用于放置图块,但用户必须单击图块的左下角,更改 clickPos 的公式似乎太复杂,我认为有更好的方法来实现。请帮我解决这两个问题
您是否使用正交相机进行 2D 工作?在 3D 中我会这样做,这也适用于 2D 平面。
Plane _groundPlane;
void Start()
{
_groundPlane = new Plane(Vector3.up, Vector3.zero);
}
void Update()
{
if (Input.GetMouseButtonDown(0) == false)
return;
int x = 0;
int z = 0;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float distance;
if (_groundPlane.Raycast(ray, out distance))
{
Vector3 worldPosition = ray.GetPoint(distance);
x = Mathf.RoundToInt(worldPosition.x);
z = Mathf.RoundToInt(worldPosition.z);
Debug.DrawLine(Camera.main.transform.position, worldPosition);
Debug.LogFormat("Clicked positions: {0} | {1}", x, z);
}
}
我创建了一个 平面,它与默认网格平放。然后我对它进行光线投射以从世界 space 中的鼠标屏幕位置找到命中点。我还将每个单元格的大小设置为一个单位,这样我就可以舍入到 int 以获得索引位置,它也可以作为世界变换位置。
如果您想保存光线投射并且不需要 3D 相机透视图,您可以像您已经在做的那样简单地获取鼠标世界位置。如果您将每个图块设为一个单位,则四舍五入为整数时一切正常。
我正在尝试制作一个关卡编辑器,用户可以在其中单击他们想要放置图块的位置。这是代码:
using UnityEngine;
using System.Collections;
public class TilePlacement : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown (0)) {
var clickPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f);
clickPos = Camera.main.ScreenToWorldPoint (clickPos);
clickPos.z = 0f;
clickPos.x = Mathf.FloorToInt (clickPos.x);
clickPos.y = Mathf.FloorToInt (clickPos.y);
clickPos.x /= 3.2f;
clickPos.y /= 3.2f;
clickPos.x = Mathf.Round (clickPos.x);
clickPos.y = Mathf.Round (clickPos.y);
clickPos.x *= 3.2f;
clickPos.y *= 3.2f;
var go = new GameObject ();
go.AddComponent<SpriteRenderer> ();
go.GetComponent<SpriteRenderer> ().sprite = Sprite.Create(new Texture2D(32, 32), new Rect(0, 0, 32, 32), new Vector2(0, 0));
go.transform.localScale = new Vector3 (10f, 10f, 0f);
go.transform.position = clickPos;
}
}
}
此代码适用于放置图块,但用户必须单击图块的左下角,更改 clickPos 的公式似乎太复杂,我认为有更好的方法来实现。请帮我解决这两个问题
您是否使用正交相机进行 2D 工作?在 3D 中我会这样做,这也适用于 2D 平面。
Plane _groundPlane;
void Start()
{
_groundPlane = new Plane(Vector3.up, Vector3.zero);
}
void Update()
{
if (Input.GetMouseButtonDown(0) == false)
return;
int x = 0;
int z = 0;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float distance;
if (_groundPlane.Raycast(ray, out distance))
{
Vector3 worldPosition = ray.GetPoint(distance);
x = Mathf.RoundToInt(worldPosition.x);
z = Mathf.RoundToInt(worldPosition.z);
Debug.DrawLine(Camera.main.transform.position, worldPosition);
Debug.LogFormat("Clicked positions: {0} | {1}", x, z);
}
}
我创建了一个 平面,它与默认网格平放。然后我对它进行光线投射以从世界 space 中的鼠标屏幕位置找到命中点。我还将每个单元格的大小设置为一个单位,这样我就可以舍入到 int 以获得索引位置,它也可以作为世界变换位置。
如果您想保存光线投射并且不需要 3D 相机透视图,您可以像您已经在做的那样简单地获取鼠标世界位置。如果您将每个图块设为一个单位,则四舍五入为整数时一切正常。