具体思路为鼠标向建筑发射一条射线,建筑沿着方向再发射一条射线检测是否有其他建筑,但是这样是以点来检测的,需要改为范围检测。如果实现了放置需要检测射线点距离格子四点距离来修改标志位,判断格子是否被放置,更为准确。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClickModels : MonoBehaviour {
public string clickObjName = null;//被射线击中的第一个对象的名称
public string clickObjName2 = null;//被射线击中的第一个对象的名称
public bool putDown = true;//对象是否被放下标志位
public GameObject clickedBuilding;//鼠标选中的对象
public GameObject terrain;//获取地图
void Update () {
ClickBuildings();
}
void ClickBuildings() {
//声明屏幕到3D世界的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit)) {
Debug.DrawLine(ray.origin, hit.point, Color.red);//从鼠标到碰撞点画线
if(putDown)//如果对象已经被放下才能更新射线集中的建筑
clickObjName = hit.transform.name;
if (clickObjName == "Terrain")//如果射线击中了地形,返回
return;
Vector3 clickedPos = hit.point;//声明对象被选中后的坐标
clickedPos.y = terrain.transform.position.y+0.1f;//修改物体y坐标比地形y坐标高0.1
clickedBuilding = GameObject.Find(clickObjName);//声明被选中的对象
//clickObjName2 = null;
if (Input.GetMouseButtonDown(0)) {//如果按下鼠标左键,对象被抬起
Ray ray2 = new Ray(hit.point, ray.direction);
RaycastHit hit2 = new RaycastHit();
if(Physics.Raycast(ray2,out hit2)) {
clickObjName2 = hit2.transform.name;
if (clickObjName2 != null) {
if (clickObjName2 != "Terrain") {
Debug.Log("此处无法放置建筑!");
return;
}
}
}
putDown = !putDown;
}
if (putDown == false) {//如果对象没有放下
clickedBuilding.transform.position = clickedPos;//更新对象世界坐标
if (Input.GetKeyDown(KeyCode.Q)) {//如果按下Q、E,旋转对象
clickedBuilding.transform.Rotate(0,-90,0);
}else if (Input.GetKeyDown(KeyCode.E)) {
clickedBuilding.transform.Rotate(0, 90, 0);
}
}
}
}
}
网友评论