文档章节

unity 赛车相机跟随物体移动

 柠栀
发布于 2015/01/23 15:03
字数 1783
阅读 145
收藏 1

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

对于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<NavMeshAgent>();

  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. }




  65. 2.相机功能:

  66. 1.跟随主角移动;

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

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

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

  70. 代码如下

  71. c1.cs

  72. using UnityEngine;

  73. using System.Collections;


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


  75. public class c1 : MonoBehaviour

  76. {




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


  78.     public RotationAxes axes = RotationAxes.MouseXAndY;


  79.     public float sensitivityX = 15F;


  80.     public float sensitivityY = 15F;




  81.     public float minimumX = -360F;


  82.     public float maximumX = 360F;




  83.     public float minimumY = -85F;


  84.     public float maximumY = 4F;




  85.     public float rotationY = 0F;




  86.     public GameObject target;




  87.     public float theDistance = -10f;


  88.     public float MaxDistance = -10f;


  89.     public float ScrollKeySpeed = 100.0f;


  90.     void Update()

  91.     {

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

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


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


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

  96.         {


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


  98.         }


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


  100.         if (theDistance > 0)


  101.             theDistance = 0;


  102.         if (theDistance < MaxDistance)


  103.             theDistance = MaxDistance;

  104. //按下鼠标右键

  105.         if (Input.GetMouseButton(1))

  106.         {


  107.             transform.position = target.transform.position;


  108.             if (axes == RotationAxes.MouseXAndY)

  109.             {


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




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


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


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


  114.             }


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

  116.             {


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


  118.             }


  119.             else

  120.             {


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


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


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


  124.             }


  125.             SetDistance();


  126.         }


  127.         else

  128.         {


  129.             transform.position = target.transform.position;


  130.             SetDistance();


  131.         }


  132.     }




  133.     void Start()

  134.     {


  135.         if (rigidbody)

  136.         {


  137.             rigidbody.freezeRotation = true;


  138.             transform.position = target.transform.position;


  139.         }


  140.     }




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


  142.     void SetDistance()

  143.     {


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


  145.     }


  146. }

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

  148. 代码如下:

  149. playerKeyMove.cs:



  150. using UnityEngine;

  151. using System.Collections;


  152. public class playerKeyMove: MonoBehaviour

  153. {


  154.     //动画对象

  155.     Animation m_Animation;

  156.     

  157.     //移动的速度

  158.     public float speed;

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

  160.     Transform m_Camera;


  161.     

  162.     //移动大小

  163.     public float m_MoveFactor = 4.0f;

  164.     //旋转大小

  165.     public float m_RotateFactor = 10.0f;


  166.     void Start()

  167.     {

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

  169.         m_NavmeshAgent = GetComponent<NavMeshAgent>();

  170.         //实例化animation动画

  171.         m_Animation = animation;

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

  173.         m_Camera = Camera.main.transform;

  174.     }

  175.     

  176.     // Update is called once per frame

  177.     void Update()

  178.     {


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

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

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

  182.             m_Animation.CrossFade("idle");

  183.         }

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

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

  186.         {

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

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

  189.                 Move(-45.0f);

  190.             }

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

  192.                 Move(45.0f);

  193.             }

  194.             else

  195.                 //这个键值不旋转

  196.                 Move(0.0f);

  197.         }

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

  199.         {

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

  201.                 Move(-135.0f);

  202.             }

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

  204.                 Move(135.0f);

  205.             }

  206.             else

  207.                 Move(-180.0f);

  208.         }

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

  210.         {

  211.             Move(-90.0f);

  212.         }

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

  214.         {

  215.             Move(90.0f);

  216.         }

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

  218.         {

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

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

  221.         }     

  222.     }

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

  224.     void Move(float delta)

  225.     {

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

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

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

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

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

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

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

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

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

  235.         //播放跑的动作

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

  237.             m_Animation.CrossFade("run");    

  238.     }

  239. }


© 著作权归作者所有

上一篇: cocos2d-x 解析XML
下一篇: unity sprite renderer
粉丝 0
博文 7
码字总数 5130
作品 0
宝鸡
私信 提问
Unity开发《一起来捉妖》教程 | 2.用摄像头图像做背景

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhenghongzhi6/article/details/90082519 洪流学堂,让你快人几步。你好,我是郑洪智。 洪流学堂公众号回复,...

关尔Manic
05/10
0
0
Unity3D 游戏引擎之控制模型移动旋转与碰撞(七)

Unity3D 游戏引擎之控制模型移动旋转与碰撞 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6901154 上一章介绍了模型的...

彭博
2012/03/09
470
0
Unity 3D 开发《王者荣耀》:英雄移动

王者荣耀资源 资源来自网络 链接: https://pan.baidu.com/s/1iNo7MXO1bfNi1rvp6Mc4WQ 密码: h1q6 地图 导入地形资源包,拖动一个 5V5 的地图到 Unity 上面,reset 重置地图位置。 导入模型资...

iOSDevLog
2018/05/23
0
0
Cinemachine丨介绍插件的功能

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/weixin38239050/article/details/100189163 本篇文章根据Unity直播来...

橙子va
09/01
0
0
Unity开发《一起来捉妖》教程 | 4.抛掷封妖灵珠

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/zhenghongzhi6/article/details/93194854 洪流学堂,让你快人几步。你...

关尔Manic
06/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周四乱弹 —— 浙江台的电话号码倒是记得挺牢

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :《Out On The Streets》 一直不理解北欧人对重金属和死亡摇滚的热情,听完这首歌好像理解了。#今日歌曲推荐# 《Out On The Stre...

小小编辑
今天
6
0
Leetcode PHP题解--D121 21. Merge Two Sorted Lists

D121 21. Merge Two Sorted Lists 题目链接 21. Merge Two Sorted Lists 题目分析 合并两个有序链表。 思路 逐个遍历两个链表,把小的数字塞入数组里。之后再拼起来。 最终代码 <?php/** *...

skys215
今天
5
0
mars-config 动态配置管理

mars-config 码云地址:https://gitee.com/fashionbrot/mars-config 介绍 spring mvc 、springboot 动态配置系统。http 轮训方式 更新 动态配置 软件架构 软件架构说明 后端使用技术 :sprin...

fashionbrot
今天
14
0
女朋友玩吃鸡手游被开挂老哥骗炮,我见义勇为将骗子绳之以法

大家好,我是乔哥。 晚上10点以后下班后我回到自如出租房里面,开始处理公众号粉丝发来的消息,一条一条处理,突然看到了这么几条消息,吸引了我的眼球: 然后我就和这位女粉丝小红(化名)聊...

gzc426
今天
9
0
两款软件

fadetop保护眼睛软件 Snipaste截图软件

伟大源于勇敢的开始
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部