Jes*_*ano 0 c# interactive shape unity-game-engine
我对Unity相当陌生,但是我已经找到了解决方法。但是,我遇到了一个问题,无论我用多少谷歌搜索,我似乎都找不到有效的解决方案。我可能只是在做一些愚蠢的事情。任何帮助,将不胜感激。我发布到了Unity论坛,但是没有人回应,所以我想我也会给Stack Overflow一个机会。
所以我想做的是在Unity中创建2D地图。该地图将用于在3D世界中导航。该地图必须是可点击的,因为我将从世界地图开始,然后根据用户的点击,将地图更改为该国家/地区的地图。我曾与不同的人交谈过,我想使用的方式是使用shapefile,因为它们已经包含了有关国家和州边界的信息。另外,我知道将来我将不得不使用shapefile,所以我认为现在可以对它们进行一些练习。我想从小处着手,所以我下载了一个zip文件,其中包含美国的shapefile。我按照论坛的说明下载了QGIS,并在该软件中打开了shapefile。在QGIS中,我能够突出显示各个状态,如下图所示
现在,我希望在Unity中具有相同的功能,除了我不仅要突出显示它,还希望它可以单击并能够将其标识为蒙大拿州。
因此,从这里我可以将该文件转换为DXF,然后将其转换为FBX。但是在那之后我迷路了。我不确定我是否必须进行这些转换。
如果有人可以帮助我,我将不胜感激!同样,我是Unity新手,所以如果您能牢记这一点,我将不胜感激。
下面的答案描述了如何做到这一点。出于示范目的,只有八个国家完成了这项工作。
有4个步骤可以执行此操作,但是每个步骤都可能包含另一个步骤。创建模型,将其导出并将其导入到Unity中,添加Mesh Collider到每个模型中,使用来检测单击,OnPointerDown然后更改所单击的GameObject的颜色。
为此,您需要Maya 2016和Unity 5.5。
首先要注意的是Maya具有简单的菜单和选项菜单。
如果我说“(选项菜单)”,则是说右侧菜单旁边的框。看下图,了解菜单和选项菜单之间的区别:
确保检查以下指令中是否包含“(选项菜单)”。
1.创建用于对状态建模的图像参考。
。获取参考地图图像。
查找美国各州的黑白图像参考。我将使用这个,所以下载它。
B。用参考文件制作图像平面。
打开Maya并创建新项目,然后导入下载的状态图像。
为此,请转到“ 创建 -> 自由图像平面”。
在“ 图像平面属性”下,选择“ 图像名称”中的图标,然后在此处放置您下载的图像地图参考的路径。
C切换到前视图。
选择“ 图像平面”,将鼠标置于视图的中间,然后按键盘上的SPACE键。您将看到四个相机视图。将鼠标移到左下视图(Front View),然后再次按SPACE键。Maya将切换到“前视图”。您将在前视图中工作。
现在,按F放大图像平面。
D。将图像平面放置在一个层中,然后将其锁定。
相机在“ 图像平面”中放大后,如果未选择,请再次选择“ 图像平面”,然后单击“ 通道盒/图层编辑器”。
现在,单击Layers- > 从Selected创建Layer。在创建的图层上有三个复选框。
继续单击第三个(最后一个)复选框,直到显示“ R”。“ R”将锁定图像平面,以便在建模时不能再次选择它或干涉它。
2.创建每个状态模型。
一个 .Create曲线进入创建 - > 曲线工具 - > 铅笔曲线工具
按住鼠标左键并在所选状态周围进行跟踪,以绘制一个状态。在行的开头和结尾之间留一点空间。
我将以内布拉斯加州为例。
选择曲线,然后转到曲线 -> 打开/关闭
C。创建一个Nurbs平面以覆盖您绘制的曲线的整个形状。
选择曲线,然后转到“ 修改 -> 中心枢轴”
您将使用此曲线从Nurbs Plane中剪切出其形状。
转到“ 创建 -> NURBS基本体”,然后确保已选中/启用了“ 交互创建”和“完成时退出”。
转到创建 -> NURBS基本体 -> 平面。
按住鼠标左键,然后拖动并移动鼠标以创建一个平面。确保“平面”的大小覆盖步骤2A中绘制的状态的形状。
D。将曲线投影到曲面
选择这两个的平面步骤创建2C和曲线步骤创建2A。
为此,请按住鼠标左键,然后将鼠标指针拖到两个鼠标上,然后松开。
现在应该选择两个对象。
转到曲面 -> 曲面上的投影曲线
E。修剪所选对象。
从步骤D中选择平面。
转到表面 -> 修剪工具
单击曲线的内部(中间),然后按Enter。
现在应该从平面上切出曲线的形状,
F。删除历史记录,然后将枢轴居中。
选择在此过程中创建的所有内容(按住并在所有内容上移动鼠标,然后释放)。
转到编辑 -> 按类型删除 -> 历史记录。
转到修改 -> 中心枢轴
G。将NubSurface平面转换为多边形,因为Unity和其他游戏引擎使用多边形。
从步骤E中选择平面。
转到“ 修改” ->“ 转换” ->“将NURBS 转换为多边形”(选项菜单)
使用以下设置:
类型:四边形
镶嵌方法:标准拟合
弦高比:0.54
分数公差:0.01
最小边长:0.001
3D增量:0.0461
单击应用。
现在,您有了一个多边形,将其重命名为适当的状态名称(内布拉斯加州)。
H。删除后面的对象
仍选择多边形。
转到修改 -> 冻结转换
转到修改 -> 中心枢轴
将多边形移开。之后,删除其后面的所有其他对象(NubSurface和曲线)。
再次选择多边形,然后转到“ 修改 -> 重置变换”。这将使多边形回到其原始位置。
转到修改 -> 中心枢轴
我。添加材料创建的状态。
转到“ 渲染”选项卡。
单击圆形图标,它是Blinn材质。它将创建一个Blinn材料。将其命名为“ State_Material”。如果您已经创建了“ State_Material”,则不必创建新的。
转到渲染模式。
选择多边形。
转到“ 照明/阴影” ->“ 分配现有材料” ->“ State_Material”。
目标是将一种材料(状态_材料)分配给所有状态/多边形。这样可以避免将50种材料导出到Unity。
J。自动绘制UV。
转到UV- > 自动
然后,K。删除历史记录将转换后的对象的枢轴居中。
转到编辑 -> 按类型删除 -> 历史记录。
转到修改 -> 中心枢轴
做完了!跳回到2.创建每个状态模型。并为其余州做相同的事情。
3.导出为FBX。
一。出口作为FBX。
选择所有状态。我的场景中有8个。
转到文件 -> 导出选择...(选项菜单)。
将文件类型更改为FBX导出。
单击导出选择按钮
选择目录和文件名,然后再次单击导出选择。
4.在Unity中使用地图。
一个 .IMPORT的FBX到Unity。
打开Unity,转到资产 -> 导入新资产...
选择通过Maya保存的目录和FBX文件。
B。将网格碰撞器附加到每个状态/平面。
将地图拖动到层次结构。
选择所有状态/模型,然后转到组件 -> 物理 -> 网格碰撞器。
C。将模型定位到摄像机视图。
必须将对象在y轴上旋转到180度,然后将x和y轴缩放到100。如果按照相同的图像参考完全按照本教程进行操作,则必须将其旋转并缩放道路。
D.设置事件系统
转到GameObject- > 创建空,然后将其命名为“ EventSystem”。
转到组件 -> 事件 -> 事件系统。
转到组件 -> 事件 -> 独立输入模块。
选择“主摄像机”,然后转到“ 组件 -> 事件 -> 物理Raycaster”。我说Physics Raycaster不是Physics 2D Raycaster
E。附加测试脚本
进入游戏对象 - > 创建空,然后将其命名为“MapManager”。
选择MapManager GameObject并将MapManager脚本附加到该对象。
选择除父对象之外的所有状态/模型,然后将MapClickDetector脚本附加到所有状态/模型。一次执行比较容易。
脚本说明:
该MapClickDetector脚本将检测鼠标单击,鼠标悬停和其他鼠标操作,然后将其发送到MapManager脚本。然后,您可以在MapManager脚本中执行所需的任何操作。它还发送被单击的Map GameObject,以便您可以获得州的名称。
为了检测点击, IPointerDownHandler实现,然后OnPointerDown用于检测地图中哪个状态被点击。您也可以使用Raycast,但IPointerDownHandler效果更好,因为它可以防止UI出现问题。
MapManager脚本:
using UnityEngine;
public class MapManager : MonoBehaviour
{
Color normalColor = Color.red;
Color mouseDownColor = Color.green;
Color mouseEnterColor = Color.yellow;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void mapclick(GameObject objClicked)
{
Debug.Log("Clicked: " + objClicked.name);
}
public void mapMouseDown(GameObject objClicked)
{
Debug.Log("Pointer Down: " + objClicked.name);
MeshRenderer mr = objClicked.GetComponent<MeshRenderer>();
mr.material.color = mouseDownColor;
}
public void mapMouseUp(GameObject objClicked)
{
Debug.Log("Pointer Up: " + objClicked.name);
MeshRenderer mr = objClicked.GetComponent<MeshRenderer>();
mr.material.color = normalColor; ;
}
public void mapMouseEnter(GameObject objClicked)
{
Debug.Log("Pointer Enter: " + objClicked.name);
MeshRenderer mr = objClicked.GetComponent<MeshRenderer>();
mr.material.color = mouseEnterColor;
}
public void mapMouseExit(GameObject objClicked)
{
Debug.Log("Pointer Exit: " + objClicked.name);
MeshRenderer mr = objClicked.GetComponent<MeshRenderer>();
mr.material.color = normalColor;
}
}
Run Code Online (Sandbox Code Playgroud)
MapClickDetector脚本:
using UnityEngine;
using UnityEngine.EventSystems;
public class MapClickDetector : MonoBehaviour, IPointerClickHandler, IPointerDownHandler,
IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler
{
MapManager mapManager;
void Start()
{
addPhysicsRaycaster();
mapManager = GameObject.Find("MapManager").GetComponent<MapManager>();
}
void addPhysicsRaycaster()
{
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}
public void OnPointerClick(PointerEventData eventData)
{
mapManager.mapclick(gameObject);
}
public void OnPointerDown(PointerEventData eventData)
{
mapManager.mapMouseDown(gameObject);
}
public void OnPointerUp(PointerEventData eventData)
{
mapManager.mapMouseUp(gameObject);
}
public void OnPointerEnter(PointerEventData eventData)
{
mapManager.mapMouseEnter(gameObject);
}
public void OnPointerExit(PointerEventData eventData)
{
mapManager.mapMouseExit(gameObject);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3200 次 |
| 最近记录: |