已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在做一个策略类的游戏时,需要实现一个基地的功能,功能并不是太复杂,默认只能显示场景的一部分,然后通过场景(地形)查看场景中的其他部分(但是摄像机不能超出地形),当点击建筑时,建筑选中并且有选中效果,当点击非建筑时,选中效果消失!并且可以拖动场景中的建筑到一定地方,因为准确需求还不明确,所以事先做了个基地的 DEMO!最终效果如下:20141011163816_4843.jpg (85.64 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传 第一步:先布局好大体场景界面,如下图,只有两个建筑,一个平面(用于绘制格子,因为没有足够的资源,格子未显示),另外还有一个叫 BuildingCamera 的摄像机,这个摄像机非常重要,主要目的是为了让拖动的对象始终显示在最上层!20141011170314_1875.jpg (153.27 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传下面我们需要给场景添加一个 Layer, 我们取名叫 Building Layer,如下图:20141011171246_8281.jpg (143.83 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传20141011171256_3593.jpg (38.96 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传 添加好层之后,我们需要修改 BuildingCamera 摄像机的参数, Layder 设置为 Building Layer,需要修改 BuildingCamera 的 Clear Flags 为 Depth Only,Culling Mask 为 Building,并且要确保 Depth 的值大于 Main Camera 的值,如下图:20141011164521_2500.jpg (148.82 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传我们给 Plane 添加 SceneGrid.cs 脚本,这个脚本什么也没有,主要是为了方便 PhysisUtils.cs 脚本检测对象,如下图:文章来自【狗刨学习网】20141011165022_3593.jpg (149.49 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传SceneGrid.cs 代码如下:1. using UnityEngine;2. using System.Collections;3.4. public class SceneGrid : MonoBehaviour 5.6. / Use this for initialization7. void Start () 8. 9. 10. 11. / Update is called once per frame12. void Update () 13. 14. 15. 复制代码接着,我们给建筑对象(可拖动的对象)添加 SceneBuilding.cs 脚本,如下图:20141011165207_6406.jpg (170.56 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传SceneBuilding.cs 代码如下:1. using UnityEngine;2. using System.Collections;3.4. public class SceneBuilding : MonoBehaviour 5. 6. public string buildingType;7.8. / 9. / 默认材质10. / 11. private Material defaultMaterial;12.13. void Awake()14. 15. this.defaultMaterial = this.gameObject.renderer.sharedMaterial;16. 17.18. / 19. / 设置建筑选中/未选中状态20. / 21. / If set to true status.22. / Material.23. public void ChangeSelect(bool status, Material material)24. 25. if (status) 26. 27. material.SetTexture(_MainTex, this.defaultMaterial.GetTexture(_MainTex);28. this.gameObject.renderer.sharedMaterials = new Material this.defaultMaterial, material;29. else 30. this.gameObject.renderer.sharedMaterials = new Material this.defaultMaterial;31. 32. 33. 复制代码现在我们给前面创建的空对象 SceneController 挂载脚本 SceneController.cs,并且按下图配置:20141011165526_2500.jpg (152.03 KB, 下载次数: 0)下载附件 保存到相册 5天前 上传SceneController 代码如下:1. using UnityEngine;2. using System.Collections;3.4. public class SceneController : MonoBehaviour 5. 6. / 鼠标枚举7. enum MouseTypeEnum8. 9. LEFT = 010. 11.12. / 拖动建筑枚举13. enum BuildingLayerEnum14. 15. BUILDING = 816. 17.18. / 水平移动速度19. /public float horizontalSpeed = 10f;20.21. / 垂直移动速度22. /public float verticalSpeed = 10f;23.24. / 滚轮速度25. /public float mouseScrollSpeed = 10f;26.27. / 拖动状态判断 X 坐标28. /public float moveOffsetX = 1f;29.30. / 拖动状态判断 Y 坐标31. /public float moveOffsetY = 1f;32.33. / 地形高度偏移值34. /public float terrainOffset = 1f;35.36. / 格子偏移值37. /public float gridOffset = 0.2f;38.39. / 发光材质40. /public Material lightMaterial;41.42. / 主摄像机43. /public Camera mainCamera;44.45. / 拖动建筑显示层46. /public Camera buildingCamera;47. 48. / 屏幕顶点信息49. /private Vector3 pointList;50.51. / 鼠标状态52. /private bool mousePressStatus = false;53.54. / 鼠标 X 坐标55. /private float mouseX;56.57. / 鼠标 Y 坐标58. /private float mouseY;59.60. / 滚轮数据61. /private float mouseScroll;62.63. / 建筑信息64. /private SceneBuilding sceneBuilding;65.66. / 上一次鼠标 X 坐标67. /private float prevMouseX;68.69. / 上一次鼠标Y 坐标70. /private float prevMouseY;71.72. / 上一次鼠标滚轮73. /private float prevMouseScroll;74.75. / 上一次点击对象76. /private GameObject prevObject;77.78. / 拖动的建筑对象79. /private GameObject moveObject;80.81. / 移动对象的位置信息82. /private Vector3 movePosition;83.84. / 移动偏移数据85. /private Vector3 moveOffset;86.87. void Awake()88. 89. / 初始化屏幕坐标信息,用于射线检测屏幕是否超出地形之外,个人能力有限,没想到其他的判断方式,90. this.pointList = new Vector391. 92. new Vector3(0f, 0f, 0f),93. new Vector3(Screen.width, 0f, 0f),94. new Vector3(0f, Screen.height, 0f),95. new Vector3(Screen.width, Screen.height, 0f)96. ;97. 98.99. void Update()100. 101. / 按下鼠标、轴102. if (Input.GetMouseButtonDown(int)MouseTypeEnum.LEFT) 103. 104. this.mousePressStatus = true;105.106. / 如果有选中的建筑信息107. if(this.sceneBuilding != null)108. 109. / 重置建筑信息为未选中状态110. this.sceneBuilding.ChangeSelect(false, null);111. / 重置建筑信息对象112. this.sceneBuilding = null;113. 114.115. / 检测鼠标点击区域是否是建筑对象116. this.sceneBuilding = PhysisUtils.GetTByMousePoint(this.mainCamera);117. / 如果是建筑对象118. if (this.sceneBuilding != null) 119. 120. this.prevObject = this.sceneBuilding.gameObject;121. / 设置建筑对象选中效果122. this.sceneBuilding.ChangeSelect(true, this.lightMaterial);123. 124. 125. / 松开鼠标、轴126. if (Input.GetMouseButtonUp (int)MouseTypeEnum.LEFT) 127. 128. this.mousePressStatus = false;129. / 销毁拖动对象130. if(this.moveObject != null)131. 132. string gameName = this.moveO;133. Vector3 targetPosition = this.moveObject.transform.position;134.135. Destroy(this.moveObject);136. this.moveObject = null;137.138. SceneGrid sceneGrid = PhysisUtils.GetTByMousePoint(this.mainCamera);139. / 如果未超出放置区域140. if (sceneGrid != null) 141. 142. if(this.prevObject != null)143. 144. this.prevObject.transform.position = targetPosition;145. 146. 147. 148. 149. / 如果鼠标在按住状态150. if (this.mousePressStatus) 151. 152. this.mouseX = this.horizontalSpeed * Input.GetAxis (Mouse X);153. this.mouseY = this.verticalSpeed * Input.GetAxis (Mouse Y);154. / 当超过一定的偏移坐标,才视为拖动建筑155. if(Mathf.Abs(this.mouseX) = this.moveOffsetX | Mathf.Abs(this.mouseY) = this.moveOffsetY) & this.sceneBuilding != null)156. 157. / 创建一个新的建筑对象158. if(this.moveObject = null)159. 160. / 设置建筑信息的屏幕坐标161. this.movePosition = this.mainCamera.WorldToScreenPoint(this.sceneBuilding.transform.position);162. / 设置建筑信息的坐标偏移值163. this.moveOffset = this.sceneBuilding.transform.position - this.mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, this.movePosition.z);164.165. this.moveObject = (GameObject)Instantiate(this.sceneBuilding.gameObject);166. /Building167. this.moveO = this.sceneBuilding.gameO;168. this.moveObject.layer = (int)BuildingLayerEnum.BUILDING;169.170. this.moveObject.transform.localPosition = this.sceneBuilding.gameObject.transform.localPosition;171. / 以下代码根据设计方法不同会有不同的处理函数,这儿要清除掉无用的对象,保证拖动的对象不接受鼠标事件!172. SceneBuilding moveSceneBuilding = this.moveObject.GetComponent();173. if(moveSceneBuilding != null)174. 175. moveSceneBuilding.ChangeSelect(false, null);176. Destroy(moveSceneBuilding);177. 178. MeshCollider moveMeshCollider = this.moveObject.GetComponent();179. if(moveMeshCollider != null) Destroy(moveMeshCollider);180. 181. 182. / 如果移动摄像机183. if(this.sceneBuilding = null)184. 185. / 检测摄像机是否超出了地形186. if(this.Valid()187. 188. this.prevMouseX = this.mouseX;189. this.prevMouseY = this.mouseY;190. this.mainCamera.transform.localPosition -= new Vector3(this.mouseX, 0f, this.mouseY) * Time.deltaTime;191. else192. / 重置鼠标按下状态193. this.mousePressStatus = false;194. this.mainCamera.transform.localPosition += new Vector3(this.prevMouseX, 0f, this.prevMouseY);195. 196. else197. 198. / 如果移动的是建筑199. if(this.moveObject != null)200. 201. Vector3 currentMovePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, this.movePosition.z);202. Vector3 currentWorldPosition = this.mainCamera.ScreenToWorldPoint(currentMovePosition) + this.moveOffset;203.204. / 获取当前点的地形高度信息205. currentWorldPosition.y = Terrain.activeTerrain.SampleHeight(currentWorldPosition) + this.terrainOffset;206.207. currentWorldPosition.x = currentWorldPosition.x - (currentWorldPosition.x % this.gridOffset);208. currentWorldPosition.z = currentWorldPosition.z - (currentWorldPosition.z % this.gridOffset);209.210. / 设置对象跟随鼠标211. this.moveObject.transform.position = currentWorldPosition;212. 213. 214. 215. / 鼠标滚轮拉近拉远216. this.mouseScroll = this.mouseScrollSpeed * Input.GetAxis (Mouse ScrollWheel);217. if (this.mouseScroll != 0f) 218. 219. / 检测摄像机是否超出了地形220. if(this.Valid()221. 222. this.prevMouseScroll = this.mouseScroll;223. this.mainCamera.transform.localPosition -= new Vector3(0f, mouseScroll, 0f) * Time.deltaTime;224. else225. this.mainCamera.transform.localPosition += new Vector3(0f, this.prevMouseScroll, 0f);226. 227. 228. 229. this.buildingCamera.transform.localPosition = this.mainCamera.transform.localPosition;230. 231.232. / 验证是个顶点是否有元件233. /private bool Valid()234. 235. if (this.pointList = null | this.pointList.Length = 0) return false;236. / 射线检测摄像机是否超出了地形237. foreach (Vector3 rayPoint in pointList) 238. 239. Ray ray = Camera.main.ScreenPointToRay(rayPoint);240. if (!Physics.Raycast (ray, 1000f) 241. 242. return false;243. 244. 245. return true;246. 247. 复制代码上一步中,我们的选中效果使用了外发光 Shader(Mobhero/RimLight): 1. Shader Mobhero/RimLight 2. Properties 3. _MainTex (Base (RGB), 2D) = white 4. _Color (Main Color, Color) = (1,1,1,1)5. _RimColor (Rim Color, Color) = (1, 1, 1, 1)6. _RimWidth (Rim Width, Float) = 0.77. 8. SubShader 9. Pass 10. Lighting Off11. CGPROGRAM12. #pragma vertex vert13. #pragma fragmen
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年工程项目管理专员招聘面试参考题库及答案
- 2025年漫游开发工程师招聘面试题库及参考答案
- 2025年采购管理专员招聘面试题库及参考答案
- 地方医院招聘题库及答案
- 银行常识判断题库及答案
- 2025年启动项目专员招聘面试题库及参考答案
- 2025年大数据架构师招聘面试题库及参考答案
- 2025年环境安全专家招聘面试参考题库及答案
- 2025年房产销售顾问招聘面试题库及参考答案
- 2025年生产经理招聘面试参考题库及答案
- 术中输血安全管理
- 学习回信精神担当青春使命
- 江苏省无锡市江阴市部分学校2025-2026学年高二上学期期中联考数学试卷(无答案)
- 客户关系管理客户关系分级分类模板
- 绿化维护服务保证书
- 榆林镇北台红石峡景区招聘考试真题2024
- 2025年6月浙江省高考历史试卷真题(含答案解析)
- 2024甘肃会考信息技术试题
- 2025秋青岛版(五四制)2024三年级上册科学期中检测卷(附参考答案)
- 2025云南宣富高速楚雄市东南绕城高速元绿高速那兴高速高速公路收费员招聘341人笔试历年参考题库附带答案详解
- 2025医院安全隐患排查治理专项行动的实施方案(详细版)
评论
0/150
提交评论