unity 赛车相机跟随物体移动

Wesley13
• 阅读 941

对于unity 赛车相机跟随物体移动的问题,我之前做了一个人物的相机跟随着物体移动,所以就把这个来分享出来,两个的原理基本是一样的,所以大家可以参考下。

今天做了一个人物点击鼠标移动的Demo,还有方向键的移动。

    人物点击鼠标移动自然要用到NavMeshAgent寻路组件了

    首先我先说说把人物素材导入进去遇到的问题:

    1.导入进去的时候人物模型是白的,没有皮肤,即使把材质球贴了也一样,这样我才发现是模型的缩放比例太小了,才0.01,正常是0.5,0.01导致了两个问题,第一,模型的材质贴图显示不出来,二,模型拖到场景视图上根本看不见。所以要记得改改缩放比例Scale Factor这个

    2.一开始我倒进来的动画类型是Generic,然后我在角色中添加动画组件,在代码中写播放动画,结果代码提示动画不存在。我就把模型和所有的动画都改成Legacy,结果是所有的动画都自动倒进Animation组件中去了,而且在代码中也能识别了,真不错.

      上网查了一下Unity 动画类型,才发现Legacy是老的动画系统,下面有一篇关于动画系统的分析写得不错,有空我再学习学习
http://www.360doc.com/content/13/1216/12/12282510\_337556448.shtml
   
  接着说说,我在做人物自动寻路的问题,这个问题可能也会在unity 赛车相机跟随物体移动中产生,所以大家可以看一下:

   正确步骤是这样子的,对地板plane属性面板的static勾上,然后Layer 选择default(我这里选择的是第八层,随便取个名字abc 因为我在后面的寻路代码中加入了射线的参数mask==1<<8,这里的8是后面的第八层,后面我再解释),当然你选择default括号的不用再看了,只是如过要使用我的代码可能要注意一下了呵呵。。。。继续,然后直接bake一下,会生成蓝色的地板,提示你要保存场景,保存完了就地板的就制作好了。然后再给主角添加一个寻路组件NavMeshAgent组件,整个寻路步骤就此完成

   我遇到的问题是属性面板旁边的那个Navigation选项卡经常会不见了,只要在菜单栏windows上面选择Navigation就出现了。

人物自动寻路代码如下:

  1. playerControl.cs:

  2. using UnityEngine;

  3. using System.Collections;

  4. public class PlayerControl : MonoBehaviour

  5. {

  6. //这个代表要寻路的主角

  7. NavMeshAgent m_player;

  8. //这个是主角的动作动画

  9. Animation m_animation;

  10. //主角在跑时候的速度

  11. public float speed;

  12. //照相机要跟上主角移动

  13. Transform m_Camera;

  14. public float m_MoveFactor = 4.0f;

  15. public float m_RotateFactor = 10.0f;

  16. Vector3 nowPosition;

  17. void Start()

  18. {

  19. //通过这个函数可以找到套在主角身上的所有组件,这次找的是寻路组件哈

  20. m_player = GetComponent();

  21. //获取主角身上的动画数组

  22. m_animation = animation;

  23. //获取照相机的位置-----transform是位置信息,可以平移,缩放,旋转。

  24. m_Camera = Camera.main.transform;

  25. //这个是我为了获取主角当前位置所设的

  26. nowPosition = transform.position;

  27. }

  28. void Update()

  29. {

  30. nowPosition = transform.position;

  31. //有任何键盘按下的时候会中断当前的寻路:原理很简单,只要把寻路目标换成主角当前的位置就好了

  32. if (Input.anyKeyDown)

  33. {

  34. m_player.SetDestination(nowPosition);

  35. }

  36. //主角如果到了目的地,播放待机动作

  37. if (m_player.remainingDistance == 0)

  38. {

  39. m_animation.CrossFade("idle");

  40. }

  41. 否则,播放跑步动作

  42. else

  43. {

  44. m_animation.CrossFade("run");

  45. }

  46. //难点来了,鼠标为什么不能通过一个三维像两个直接捕获鼠标的点击位置:因为鼠标点击的坐标是屏幕坐标,这时要用射线做成空间坐标

  47. //左击鼠标开始移动

  48. if (Input.GetMouseButtonDown(0))

  49. {

  50. Debug.Log(" clickLeftMouseButton! ");

  51. Ray ray;

  52. RaycastHit hit;

  53. //这个mask就是我选择Layers改为第八层的原因

  54. LayerMask mask = 1 << 8;

  55. ray = Camera.main.ScreenPointToRay(Input.mousePosition);

  56. if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))

  57. {

  58. Debug.DrawLine(ray.origin, hit.point, Color.red, 2);

  59. m_player.SetDestination(hit.point);

  60. }

  61. }

  62. }

  63. }

  64. 2.相机功能:

  65. 1.跟随主角移动;

  66. 2.  按住鼠标右键拖动能够移动过视图

  67. 3.滚动鼠标滚轮能够放大缩小游戏视图

  68. 4.用我的代码要改动一处, target = GameObject.Find("nanzhujueSCJ");红色的改成你的角色名称

  69. 代码如下

  70. c1.cs

  71. using UnityEngine;

  72. using System.Collections;

  73. [AddComponentMenu("Camera-Control/Mouse Look")]

  74. public class c1 : MonoBehaviour

  75. {

  76. public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }

  77. public RotationAxes axes = RotationAxes.MouseXAndY;

  78. public float sensitivityX = 15F;

  79. public float sensitivityY = 15F;

  80. public float minimumX = -360F;

  81. public float maximumX = 360F;

  82. public float minimumY = -85F;

  83. public float maximumY = 4F;

  84. public float rotationY = 0F;

  85. public GameObject target;

  86. public float theDistance = -10f;

  87. public float MaxDistance = -10f;

  88. public float ScrollKeySpeed = 100.0f;

  89. void Update()

  90. {

  91. //这里的target要改成你主角的名字

  92. target = GameObject.Find("nanzhujueSCJ");

  93. // 滚轮设置 相机与人物的距离.

  94. if (Input.GetAxis("Mouse ScrollWheel") != 0)

  95. {

  96. theDistance = theDistance + Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * ScrollKeySpeed;

  97. }

  98. // 鼠标中间滚动得到的值是不确定的,不会正好就是0,或 -10,当大于0时就设距离为0,小于MaxDistance就设置为MaxDistance

  99. if (theDistance > 0)

  100. theDistance = 0;

  101. if (theDistance < MaxDistance)

  102. theDistance = MaxDistance;

  103. //按下鼠标右键

  104. if (Input.GetMouseButton(1))

  105. {

  106. transform.position = target.transform.position;

  107. if (axes == RotationAxes.MouseXAndY)

  108. {

  109. float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;

  110. rotationY += Input.GetAxis("Mouse Y") * sensitivityY;

  111. rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

  112. transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);

  113. }

  114. else if (axes == RotationAxes.MouseX)

  115. {

  116. transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);

  117. }

  118. else

  119. {

  120. rotationY += Input.GetAxis("Mouse Y") * sensitivityY;

  121. rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

  122. transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);

  123. }

  124. SetDistance();

  125. }

  126. else

  127. {

  128. transform.position = target.transform.position;

  129. SetDistance();

  130. }

  131. }

  132. void Start()

  133. {

  134. if (rigidbody)

  135. {

  136. rigidbody.freezeRotation = true;

  137. transform.position = target.transform.position;

  138. }

  139. }

  140. //设置相机与人物之间的距离

  141. void SetDistance()

  142. {

  143. transform.Translate(Vector3.forward * theDistance);

  144. }

  145. }

  146. 3.人物方向键移动,这里做了优化,同时兼容两个按键,旋转的时候显得很自然过度

  147. 代码如下:

  148. playerKeyMove.cs:

  149. using UnityEngine;

  150. using System.Collections;

  151. public class playerKeyMove: MonoBehaviour

  152. {

  153. //动画对象

  154. Animation m_Animation;

  155. //移动的速度

  156. public float speed;

  157. //平移对象(照相机)

  158. Transform m_Camera;

  159. //移动大小

  160. public float m_MoveFactor = 4.0f;

  161. //旋转大小

  162. public float m_RotateFactor = 10.0f;

  163. void Start()

  164. {

  165. //获取装有寻路功能的对象

  166. m_NavmeshAgent = GetComponent();

  167. //实例化animation动画

  168. m_Animation = animation;

  169. //平移对象相机是主相机的平移

  170. m_Camera = Camera.main.transform;

  171. }

  172. // Update is called once per frame

  173. void Update()

  174. {

  175. //这部分内容是主角键盘移动

  176. //如果WSAD键松开的时候是处于正常状态

  177. if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D)) {

  178. m_Animation.CrossFade("idle");

  179. }

  180. //当W键按下的时候,又有其他键按下的时候主角应该出现旋转

  181. if (Input.GetKey(KeyCode.W))

  182. {

  183. //按下左键的时候逆时针旋转45度

  184. if (Input.GetKey(KeyCode.A)) {

  185. Move(-45.0f);

  186. }

  187. else if (Input.GetKey(KeyCode.D)){

  188. Move(45.0f);

  189. }

  190. else

  191. //这个键值不旋转

  192. Move(0.0f);

  193. }

  194. else if (Input.GetKey(KeyCode.S))

  195. {

  196. if (Input.GetKey(KeyCode.A)) {

  197. Move(-135.0f);

  198. }

  199. else if (Input.GetKey(KeyCode.D)){

  200. Move(135.0f);

  201. }

  202. else

  203. Move(-180.0f);

  204. }

  205. else if (Input.GetKey(KeyCode.A))

  206. {

  207. Move(-90.0f);

  208. }

  209. else if (Input.GetKey(KeyCode.D))

  210. {

  211. Move(90.0f);

  212. }

  213. else if(Input.GetKey(KeyCode.Space))

  214. {

  215. //m_Animation.CrossFade("attack01");

  216. Debug.Log("攻击");

  217. }

  218. }

  219. //这个函数的功能是实现

  220. void Move(float delta)

  221. {

  222. //Quaternion是四元数,先计算角度angle是主相机的欧拉角

  223. //transform.eulerAngles(x,y,z)表示分别绕x,y,z旋转的角度

  224. float angle = m_Camera.eulerAngles.y + delta;

  225. Quaternion rotate = Quaternion.Euler (0, angle, 0);

  226. //主角开始移动,移动的距离是旋转角度rotate*3维向量向前Vector.forward*一秒Time.deltaTime*移动的速度m_MoveeFactor

  227. m_NavmeshAgent.Move(rotate * Vector3.forward * Time.deltaTime * m_MoveFactor);

  228. //主角旋转transform.rotation=

  229. //Quaternion.Lerp意思是四元数的插值

  230. transform.rotation = Quaternion.Lerp(transform.rotation, rotate, Time.deltaTime * m_RotateFactor);

  231. //播放跑的动作

  232. //Animation.CrossFade 淡入淡出动画

  233. m_Animation.CrossFade("run");

  234. }

  235. }

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这