最新补充。

         一般在做鼠标选择时是从摄像机向目标点发送一条射线,然后取得射线与对象相交的点来计算3D目标点。后来在开发中发现了一个问题(射线被别的对象挡住了),就是如果主角的前面有别的游戏对象挡着。此时如果使用射线的原理,鼠标选择被档的对象,这样主角就会向被当的对象的方向行走。为了解决这个问题,我放弃使用发送射线的方法,最后通过2D的方法完美的处理了这个问题。

   如下图所示,我们先把主角的3D坐标换算成屏幕中的2D坐标,当鼠标在屏幕中点击的时候取得一个目标点的2D坐标,根据这2个坐标换算出主角的2D向量。

然后我们在看看代码。

//将世界坐标换算成屏幕坐标

Vector3 vpos3 = Camera.main.WorldToScreenPoint(transform.position);

Vector2 vpos2 = new Vector2 (vpos3.x,vpos3.y);

//取得鼠标点击的屏幕坐标

Vector2 input = new Vector2 (Input.mousePosition.x,Input.mousePosition.y);

//取得主角到目标点的向量

Vector2 normalied = ((vpos2 – input)).normalized;

注意normalized是格式化向量,以为vpos2 – input是计算两个向量之间的距离,格式化后才是它们的方向。格式化后向量的取值范围在 -1 到 +1 之间。

//我们忽略Y轴的向量,把2D向量应用在3D向量中。

Vecotr3 targetDirection = new Vector3(normalied.x,0.0f,normalied.y) ;

//根据照相机的角度计算真实的方向

float y = Camera.main.transform.rotation.eulerAngles.y;

targetDirection = Quaternion.Euler(0f,y – 180,0f) * targetDirection;

摄像机的角度决定着主角移动的方向,y是摄像机当前角度,180是摄像机默认的角度,摄像机在旋转的时候y是会动态改变的,所以需要 y – 180 。用Quaternion.Euler()方法计算一个rotation ,然后乘以默认的向量targetDirection就是主角在3D中真实需要移动的方向。

//最后使用角色控制器移动主角就可以

Vector3 movement = targetDirection * moveSpeed + new Vector3 (0, verticalSpeed, 0) + inAirVelocity;

CharacterController controller = GetComponent<CharacterController>();

collisionFlags = controller.Move(movement);

不知道大家理解了没有?如果没有理解就在我的博客下面留言,我回即时的解答的、OK继续忙碌拉。

详细代码示例请看这篇文章. Unity3D研究院之处理摄像机跟随避免相机穿墙拉近的方法(四十四)

———————————————————–华丽的分割线—————————————-

       看到这个标题我相信大家应该并不陌生,一般在PC网络游戏中玩家通过鼠标左键在游戏世界中选择角色目标移动位置,接着主角将面朝点击的那个方向移动。首先就本文来说我们应当掌握的知识点是“鼠标拣选”。这是什么概念呢?其实很简单,就是玩家通过鼠标在Game视图中选择了一个点,需要得到该点在3D世界中的三维坐标系。Game视图是一个2D的平面,所以鼠标拣选的难点就是如何把一个2D坐标换算成3D坐标。我们可以使用射线的原理很好的解决这个问题,在平面中选择一个点后从摄像机向该点发射一条射线。判断:选择的这个点是否为地面,如果是地面拿到这个点的3D坐标即可。如下图所示,在场景视图中我们简单的制作了带坡度的地形,目标是用户点击带坡度或不带坡度的地形都可以顺利的到达目的地。

         
         本文依然使用角色控制器组件,不知道这个组件的朋友请看MOMO之前的文章。因为官方提供的脚本是JavaScript语言。MOMO比较喜欢C#所以放弃了在它的基础上修改,而针对本文的知识点重写编写脚本,这样也方便大家学习,毕竟官方提供的代码功能比较多,代码量也比较多。废话不多说了进入正题,首先在将模型资源载入工程,这里没有使用官方提供的包,而直接将模型资源拖拽入工程。如下图所示,直接将角色控制器包中的模型资源拖拽如层次视图当中。

在Project视图中鼠标右键选择Import  Package ->Script引入官方提供的脚本,这些脚本主要是应用于摄像机朝向的部分。首先在Hierarchy视图中选择摄像机组件,接着在导航栏菜单中选择Compont -> Camera-Control ->SmoothFollow脚本。实际意义是将跟随脚本绑定在摄像机之上,目的是主角移动后摄像机也能跟随主角一并移动。如下图所示,脚本绑定完毕后可在右侧监测面板视图中看到Smooth Follow脚本。Target 就是射向摄像机朝向的参照物,这里把主角对象挂了上去意思是摄像机永远跟随主角移动。
         
         由于官方提供的脚本并不是特别的好,摄像机永远照射在主角的后面,以至于控制主角向后回头时也无法看到主角的面部表情,所以MOMO简单的修改一下这条脚本,请注意一下我修改的地方即可。
SmootFollow.js
01 // The target we are following
02 var target : Transform;
03 // The distance in the x-z plane to the target
04 var distance = 10.0;
05 // the height we want the camera to be above the target
06 var height = 5.0;
07 // How much we
08 var heightDamping = 2.0;
09 var rotationDamping = 3.0;
10  
11 // Place the script in the Camera-Control group in the component menu
12 @script AddComponentMenu("Camera-Control/Smooth Follow")
13  
14 function LateUpdate () {
15     // Early out if we don't have a target
16     if (!target)
17         return;
18  
19     // Calculate the current rotation angles
20     var wantedRotationAngle = target.eulerAngles.y;
21     var wantedHeight = target.position.y + height;
22  
23     var currentRotationAngle = transform.eulerAngles.y;
24     var currentHeight = transform.position.y;
25  
26     // Damp the rotation around the y-axis
27     currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
28  
29     // Damp the height
30     currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
31  
32     // Convert the angle into a rotation
33  
34     //下面是原始代码。
35     //var currentRotation = Quaternion.Euler (0, currentRotationAngle, 0);
36  
37     //这里是我修改的,直接让它等于1,
38     //摄像机就不会旋转。
39     var currentRotation = 1;
40  
41     // Set the position of the camera on the x-z plane to:
42     // distance meters behind the target
43     transform.position = target.position;
44     transform.position -= currentRotation * Vector3.forward * distance;
45  
46     // Set the height of the camera
47     transform.position.y = currentHeight;
48  
49     // Always look at the target
50     transform.LookAt (target);
51 }
           
          OK ! 下面我们给主角模型添加角色控制器组件,请先把自带的控制摄像机与镜头的控制脚本删除。如下图所示主角对象身上挂着Character Controller(角色控制器组件)即可,Controller是我们自己写的脚本,用来控制主角移动。
  
        下面看一下Controller.cs完整的脚本,脚本中我们将主角共分成三个状态:站立状态、行走状态、奔跑状态。默认情况下主角处于站立状态,当鼠标选择一个目标时,主角将进入行走状态面朝目标方向行走。当连续按下鼠标左键时主角将进入奔跑状态朝向目标方向奔跑。
001 using UnityEngine;
002 using System.Collections;
003  
004 public class Controller : MonoBehaviour
005 {
006  
007     //人物的三个状态 站立、行走、奔跑
008     private const int HERO_IDLE = 0;
009     private const int HERO_WALK = 1;
010     private const int HERO_RUN = 2;
011  
012     //记录当前人物的状态
013     private int gameState = 0;
014  
015     //记录鼠标点击的3D坐标点
016     private Vector3 point;
017     private float time;
018  
019     void Start ()
020     {
021         //初始设置人物为站立状态
022         SetGameState(HERO_IDLE);
023  
024     }
025  
026     void Update ()
027     {
028         //按下鼠标左键后
029         if(Input.GetMouseButtonDown(0))
030         {
031             //从摄像机的原点向鼠标点击的对象身上设法一条射线
032             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
033             RaycastHit hit;
034             //当射线彭转到对象时
035             if (Physics.Raycast(ray, out hit))
036             {
037                 //目前场景中只有地形
038                 //其实应当在判断一下当前射线碰撞到的对象是否为地形。
039  
040                 //得到在3D世界中点击的坐标
041                 point = hit.point;
042  
043                 //设置主角面朝这个点,主角的X 与 Z轴不应当发生旋转,
044                 //注解1
045                 transform.LookAt(new Vector3(point.x,transform.position.y,point.z));
046  
047                 //用户是否连续点击按钮
048                 if(Time.realtimeSinceStartup - time <=0.2f)
049                 {
050                         //连续点击 进入奔跑状态
051                         SetGameState(HERO_RUN);
052                 }else
053                 {
054                         //点击一次只进入走路状态
055                         SetGameState(HERO_WALK);
056                 }
057  
058                 //记录本地点击鼠标的时间
059                 time = Time.realtimeSinceStartup;
060             }
061         }
062     }
063  
064     void FixedUpdate()
065     {
066  
067         switch(gameState)
068         {
069         case HERO_IDLE:
070  
071             break;
072         case HERO_WALK:
073             //移动主角 一次移动长度为0.05
074             Move(0.05f);
075             break;
076  
077         case HERO_RUN:
078             //奔跑时移动的长度为0.1
079             Move(0.1f);
080             break;
081         }
082  
083     }
084  
085     void SetGameState(int  state)
086     {
087         switch(state)
088         {
089         case HERO_IDLE:
090             //播放站立动画
091             point = transform.position;
092             animation.Play("idle");
093             break;
094         case HERO_WALK:
095             //播放行走动画
096             animation.Play("walk");
097             break;
098         case HERO_RUN:
099             //播放奔跑动画
100             animation.Play("run");
101             break;
102         }
103         gameState = state;
104     }
105  
106     void Move(float speed)
107     {
108  
109         //注解2
110         //主角没到达目标点时,一直向该点移动
111         if(Mathf.Abs(Vector3.Distance(point, transform.position))>=1.3f)
112         {
113             //得到角色控制器组件
114             CharacterController controller  = GetComponent<CharacterController>();
115             //注解3 限制移动
116             Vector3 v = Vector3.ClampMagnitude(point -  transform.position,speed);
117             //可以理解为主角行走或奔跑了一步
118             controller.Move(v);
119         }else
120         {
121             //到达目标时 继续保持站立状态。
122             SetGameState(HERO_IDLE);
123         }
124     }
125  
126 }

 
注解1:transform.LookAt()这个方法是设定主角对象的面朝方向,这里设定的方向是鼠标选择的目标点在游戏世界中点中的3D坐标。为了避免主角X与Z轴发生旋转(特殊情况)所以我们设定朝向的Y轴永远是主角自身的Y轴。

注解2:在这里判断主角当前位置是否到达目标位置,然后取得两点坐标差的绝对值。未到达目的继续向前行走或奔跑,达到目的主角进入站立状态等待下一次移动。
注解3:在选中目标点后主角并不是直接移动过去,应当是经过一段行走或奔跑的时间才移动过去。所以我们需要得知主角行走或奔跑下一步的坐标,那么通过Vertor3.ClampMagnitude()方法即可取得。参数1为两个坐标点之间的距离差,参数2表示行走或奔跑一步的距离,最后通过角色控制器组件提供的Move方法来移动主角。
MOMO祝大家学习愉快哇咔咔!如上图所示,MOMO双击鼠标在3D中选择了一个目标点,主角正在努力的向该点奔跑。
工程的下载地址如下:http://vdisk.weibo.com/s/abU_3
http://www.xuanyusong.com/archives/841

Unity3D研究院之鼠标控制角色移动与奔跑示例相关推荐

  1. C语言+EasyX 鼠标控制角色移动

    昨天的角色移动是键盘控制角色,今天做了改进,用鼠标控制角色移动 #include<graphics.h> #include<stdio.h> #include<conio ...

  2. Unity3D中,鼠标控制相机视角并且跟随玩家的几种方法(第三人称)的学习整理

    第一种,  按住鼠标的右键进行移动视角,同时滚轮调正视角大小. public Transform target; //相机追随目标public float xSpeed = 200; //X轴方向拖动 ...

  3. 【Unity3D】键盘鼠标控制视角的移动

    在3D游戏里面,视角是一个很重要的因素,部分玩家对锁视角嗤之以鼻,因此视角也是游戏制作里面需要努力的方面.其实也不难,换到Unity3D里面是想办法控制摄像机的移动.下面举一个简单的例子说明在Unit ...

  4. 【unity3d游戏开发之基础篇】利用射线实现鼠标控制角色转向和移动(角色移动一)...

    由于最近搞2D游戏, 下面的代码配合NGUI来使用 ... 将代码拖到角色身上就OK, 实现了角色转向.移动 ,想看效果的可以将代码下下来~ 用到了向量来计算角度 以及方向,   得恶补下向量知识了 ...

  5. C#鼠标控制控件移动的示例

    //鼠标点击控件按住不放,控件跟随移动.施放则不移动 //这里的控件可以更换为其他控件. using System; using System.Collections.Generic; using S ...

  6. Unity3D游戏开发第三人称角色控制的模式

    众所周知,在Unity3D游戏开发中,经常会用到角色控制,一般情况下角色控制有第一人称和第三人称两种,在 RPG 游戏中通常以第三人称的形式出现.而对于第三人称角色控制而言,通常有 2 种模式,我们今 ...

  7. Unity3d实现鼠标控制相机绕物体旋转(带阻尼)

    Unity3d实现鼠标控制相机绕物体旋转(带阻尼) 本来想的是用四元数实现球性插值实现阻尼效果,但是不知道四元数怎么绕定点旋转.因此用速度衰减的方法进行实现. 1.实现鼠标控制相机带阻尼旋转 2.实现 ...

  8. unity3d 摄像机跟随鼠标和键盘的控制

    鼠标控制: using UnityEngine; using System.Collections; public class shubiao : MonoBehaviour { //public T ...

  9. Unity3D游戏编程-鼠标打飞碟

    Unity3D游戏编程-鼠标打飞碟 文章目录 Unity3D游戏编程-鼠标打飞碟 一.作业要求 二.项目配置 三.项目演示 视频演示 项目下载 文字说明 项目截图 四.前置内容 MVC模式 动作管理器 ...

最新文章

  1. [WorldWind学习]17.视域调度(视域体裁剪)
  2. 项目十大管理及5大过程组概览
  3. 删文97篇!前UCLA教授竟是民科?不看好量子通信被禁言
  4. 好心酸!三星可折叠屏手机Galaxy Fold下月也无法发货
  5. 中国特威兹勒行业市场供需与战略研究报告
  6. centos6.9终端命令
  7. jsp中的session和上下文
  8. 宠物医院app开发的功能有哪些?
  9. 使用onvif协议操作设备
  10. 【AVR单片机】【Microchip Studio】01项目创建
  11. 批处理删除文件文件夹相关指令
  12. html的富文本有什么用,html中怎样使用富文本
  13. 手机端上传照片实现 压缩、拖放、缩放、裁剪、合成拼图等功能
  14. 计算机图形学算法总结
  15. 压力变送器和差压变送器的区别
  16. 绕过安卓的唯一机会,可能是利用EMUI中沉睡的AI藏宝图
  17. 《黄帝内经》的理论体系
  18. 解决阿里云存在未支付订单请支付或作废后再下单
  19. 项目数据字典数据导入导出
  20. [Oracle] 几本重要的电子图书下载

热门文章

  1. 度假式联合办公是创业者流行的新工作方式
  2. OS X Eagle Peak,据说这是Mac新系统的名字
  3. 如何客制化某两个activity切换时的窗口动画?
  4. 基于Pytorch的热轧钢带表面缺陷分类挑战
  5. 交通标志数据集-整理
  6. python动态横道图_python的matplotlib.pyplot绘制甘特图
  7. 文件系统灵活用——智能家居DIY连载教程3
  8. 程序员就非要科班出身
  9. 5款Android版Office简评
  10. 《疯狂拇指》 官方介绍