学unity也有一段时间了,做了不少东西,但因为没有老师也不知道自己做得对不对。所以拿出一点东西出来让大家批评指正。随带说下我的版本是unity5.x
废话不多说进入主题,第三人称游戏我想大家肯定都接触过,比如魔兽、剑灵、暗黑破坏神这样的游戏,玩家可以通过屏幕看到游戏角色,通过鼠标键盘的操作进行人物控制和视角的转向。现在我要做的就是制作这样的第三人称的人物控制。
当我们要写作这样的人物控制的时候先要做就是导入一个带动画的角色模型,

假设这个模型只有向前奔跑和默认静止两个动画,现在我们要结合animator状态机来进行设置。在Windows菜单下,打开animator状态机。新建一个状态我把它命名为idle&run

然后再在設置參數,speed,speed2分別表示前后和左右两个方向

设置完状态机,然后为默认的状态机添加混合树
关于状态机这里就不细讲了,明眼人都能看出这里混合了前后左右和默认四个状态的混合。
创建脚本,脚本名字为PlayerControl,挂载在人物对象上
接下来代码如下

void Update(){   float v = Input.GetAxis("Vertical");_animator.SetFloat("speed", v);float v2 = Input.GetAxis("Horizontal");_animator.SetFloat("speed2", v2);}

通过获取方向键控制动画播放(WASD或↑←→↓)。动画播放是解决了但是按下后会发现人物只是播放了动画,并没有进行移动,而且人物并没有按照想象的方向进行转向。只是播放了美工给的动画,美工只给了一个向前的动画,我也只设置了一种动画,所以模型会按原有的方向播放动画。
所以现在还要加上移动,要怎么移动我觉得应该由制作的游戏的决定。现在我以摄像机为参考坐标,摄像机的前方就是向前同理还有左右,同时还有上左、上右等共计八个方向。声明一个摄像机的变量public Cameramain Crma;然后在场景里面把摄像机拖到脚本声明的变量上

这里为了后续的扩展我还声明了 人物移动速度speed,和人物重力Gravity,人物跳跃初速度JumpSpeed。
这里我用我SSR级的画图功底说明,前方是哪里

那么向前的向量是这样获取的

Vector3 temppos = gameObject.transform.position -mainCrma.transform.position;
Vector3 Playerforward = new Vector3(temppos.x, 0, temppos.z);

那么玩家向前的代码就这样写

moveDirection = Playerforward .normalized;//向量化模,规范化长度 gameObject.Move(moveDirection * Time.deltaTime);//向前移动

向左呢,我们这里用四元数解决,

 Vector3 Playerleft = Quaternion.Euler(0, -90, 0) * Playerforward;  //向左的向量moveDirection = Playerforward .normalized;//向量化模,规范化长度
gameObject.Move(Playerleft * Time.deltaTime);//向左移动

但是这还是不够的,因为美工给我的是只有1个向前方向的模型,上面脚本可以看到位置模型向左移动但是模型方向是向前的,播放的动画也是向前的。所以当我们改变方向的时候需要旋转模型,这个模型怎么旋转呢。没错,向左旋转就是模型以我上面SSR级的画图功底的B向量的方向旋转90度,代码如下

 Quaternion rotationA = Quaternion.AngleAxis(90, Vector3.up) * rotationS;//向正左方向旋轉

原理基本就这样,我还加了CharacterController碰撞器,接下来上完整代码

public class PlayerControl : MonoBehaviour
{public float speed;private Animator _animator;public Camera mainCrma;// private Ray Cameraray, PlayerRay;// private RaycastHit fromcam, fromplay;private GameObject gameObj, gameObj2;private bool speediszero = true, Ispickup = false;private int keytime1 = 0, keytime2 = 0;public float jumpSpeed = 5.0F;public float gravity = 10.0F;Vector3 moveDirection = Vector3.zero;// Use this for initializationvoid Start(){_animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){    Vector3 moveDirection = Vector3.zero;float v = Input.GetAxis("Vertical");_animator.SetFloat("speed", v);float v2 = Input.GetAxis("Horizontal");_animator.SetFloat("speed2", v2);}void FixedUpdate(){NewgetInput();//设置基本动作// OtherBehaviour();//设置特殊情况下的一些动作}//void OtherBehaviour()//备用//{//    if (Input.GetMouseButton(0))//    {//        keytime1++;//        // if(keytime1>20){Ispickup=true;}//    }//    if (Input.GetMouseButtonUp(0))//    {//        keytime1 = 0;// }//        if (keytime1 == 10)//长按鼠标左键事件//    {//    }//}void moveDirectionvalue(Vector3 currentposition)//把重力和向量规范化封装在这里{CharacterController controller = GetComponent<CharacterController>();moveDirection = currentposition.normalized;//向量化模,规范化长度moveDirection.y -= gravity * Time.deltaTime;//Y方向设置重力controller.Move(moveDirection * Time.deltaTime); }void NewgetInput(){    /*也许下面的变量可以设成枚举,方便扩展*/Vector3 temppos = gameObject.transform.position - mainCrma.transform.position;Vector3 Playerforward = new Vector3(temppos.x, 0, temppos.z);  //获取向前的向量 ↑Vector3 Playerright = Quaternion.Euler(0, 90, 0) * Playerforward;  //→Vector3 Playerleft = Quaternion.Euler(0, -90, 0) * Playerforward;  //←Vector3 Playerbackward = Quaternion.Euler(0, 180, 0) * Playerforward;//↓Vector3 Playerupleft = Quaternion.Euler(0, -45, 0) * Playerforward;//↖Vector3 Playerbackleft = Quaternion.Euler(0, -135, 0) * Playerforward;//↙Vector3 Playerupright = Quaternion.Euler(0, 45, 0) * Playerforward;//↗Vector3 Playerbackright = Quaternion.Euler(0, 135, 0) * Playerforward;//↘Quaternion rotationW = Quaternion.LookRotation(Playerforward);//向正前方旋轉↑Quaternion rotationDW = Quaternion.AngleAxis(45, Vector3.up) * rotationW;//向右前方向旋轉↗Quaternion rotationD = Quaternion.AngleAxis(90, Vector3.up) * rotationW;//向正右方向旋轉→Quaternion rotationAW = Quaternion.AngleAxis(-45, Vector3.up) * rotationW;//向左前方向旋轉↖ Quaternion rotationS = Quaternion.LookRotation(-Playerforward);//向正后方旋轉↓Quaternion rotationDS = Quaternion.AngleAxis(-45, Vector3.up) * rotationS;//向右后方向旋轉↙Quaternion rotationA = Quaternion.AngleAxis(90, Vector3.up) * rotationS;//向正左方向旋轉←Quaternion rotationAS = Quaternion.AngleAxis(45, Vector3.up) * rotationS;//向左后方向旋轉↘float distance=  mainCrma.GetComponent<CameraControl>().distance;//获取摄像机的距离//if (controller.isGrounded)//在地面//{if (Input.GetKey(KeyCode.W)||Input.GetKey(KeyCode.UpArrow)){gameObject.transform.rotation = rotationW;moveDirectionvalue(Playerforward);}if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.RightArrow)){gameObject.transform.rotation = rotationA;//改变角色模型的方向// transform.position += Time.deltaTime * speed * Playerleft.normalized;//角色移动的方向移动moveDirectionvalue(Playerleft);// mainCrma.transform.position += Time.deltaTime * speed * Playerleft.normalized;}if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)){gameObject.transform.rotation = rotationS;//transform.position += Time.deltaTime * speed * Playerbackward.normalized;moveDirectionvalue(Playerbackward);//  mainCrma.transform.position += Time.deltaTime * speed * Playerbackward.normalized;}if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)){gameObject.transform.rotation = rotationD;// transform.position += Time.deltaTime * speed * Playerright.normalized;moveDirectionvalue(Playerright);// mainCrma.transform.position += Time.deltaTime * speed * Playerright.normalized;}if ((Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.A)) || Input.GetKey(KeyCode.UpArrow)&&Input.GetKey(KeyCode.LeftArrow)){gameObject.transform.rotation = rotationAW;//transform.position += Time.deltaTime * speed * Playerupleft.normalized;moveDirectionvalue(Playerupleft);//mainCrma.transform.position += Time.deltaTime * speed * Playerupleft.normalized;}if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.RightArrow)){gameObject.transform.rotation = rotationDW;//transform.position += Time.deltaTime * speed * Playerupright.normalized;moveDirectionvalue(Playerupright);// mainCrma.transform.position += Time.deltaTime * speed * Playerupright.normalized;}if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow) && Input.GetKey(KeyCode.LeftArrow)){gameObject.transform.rotation = rotationAS;//transform.position += Time.deltaTime * speed * Playerbackleft.normalized;moveDirectionvalue(Playerbackleft);//mainCrma.transform.position += Time.deltaTime * speed * Playerbackleft.normalized;}if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.RightArrow) && Input.GetKey(KeyCode.DownArrow)){gameObject.transform.rotation = rotationDS;// transform.position += Time.deltaTime * speed * Playerbackright.normalized;moveDirectionvalue(Playerbackright);// mainCrma.transform.position += Time.deltaTime * speed * Playerbackright.normalized;}//  }if (Input.GetMouseButtonDown(0)){_animator.SetTrigger("lefthand");keytime1 = 0;Ispickup = true;}if (Input.GetKeyDown(KeyCode.F)){_animator.SetTrigger("headattack");}if (Input.GetKeyDown(KeyCode.Space)){_animator.SetTrigger("jump");/*取消了根动作,需要添加位移*/}if (Input.GetKeyDown(KeyCode.Q)){_animator.SetTrigger("leftkick");}if (Input.GetKeyDown(KeyCode.E)){_animator.SetTrigger("rightkick");}}}

总结和注意事项
1、为了熟练四元数,使用了四元数其实因为玩家只在XZ方向上进行操作,不会产生万向锁,所以也可以不用四元数
2、为了方便管理和扩展应使用状态机,但是这里只是实现了八个方向移动,所以我省略了这部分
3、方向向量的计算可能存在重复计算,另外设置成枚举或结构体可以使代码更美观
4、speed需要外部赋值初始默认值是0,还要加上CharacterController
5、这个人物脚本是以摄像机为参照物,所以会进行很多向量运算。如果要做的游戏是2.5D或者摄像机不能自由操作的游戏,可以直接使用世界坐标系,减少不必要的计算。

第三人称游戏人物控制相关推荐

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

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

  2. 使用three.js实现跟随模型的第一人称、第三人称相机控制

    最近在我原有的"室内场景demo"的基础上做了一个跟随模型的第三人称相机控制,以键盘wasd控制模型的行走,以鼠标控制模型的朝向. 在线预览地址​​​​​​​ CSDN下载地址ht ...

  3. Unity3D第三人称摄像机控制脚本

    好久没有敲Blog该.感谢您的留言.注意.私人信件和其他支持,但我似乎没有办法继续自己曾经写了一篇博客系列,因为我在网上找到有关unity3D太少的内容,U3D相关的文章!.. 第三人称视角 第三人称 ...

  4. unity 在图片的指定位置上添加按钮_Unity-利用免费资源快捷实现第三人称角色控制...

    by 临界荷 本例目标:学习使用unity商店免费资源中的模型和代码,轻松快捷实现第三人称视角玩家多种行为的设定.举一反三,可方便灵活地添加到自己的3D模型(绑定了骨骼和动作的人物模型,不支持动物模型 ...

  5. Unity第三人称上帝视角控制

    通过wasd或上下左右键控制位移,鼠标控制视角旋转. public class PlayerMovement : MonoBehaviour {public float moveSpeed = 5f; ...

  6. Unity第三人称控制实现方式

    第三人称移动,主要两个部分,一是人物,二是相机. 先说人物,unity其实提供了一个CharacteController组件可以方便地用于控制人物移动,但是这个组件会与刚体冲突.如果使用Charact ...

  7. Unity第三人称射击游戏的相机控制

    (关于其他几种角色移动的控制在我之前的博客有写到) 首先我们需要先理解一下第三人称相机控制的原理: 我们要实现的效果就是:获取鼠标的移动输入,转化成角色以及相机的旋转,通过鼠标输入Input.GetA ...

  8. 视角设置(第一人称、第三人称)

    从Blank项目开始,利用自带的第三人称游戏人物设置视角 看起来很简单,但是每次做到这里我都要调整好久,那就记录一下吧! 第一人称游戏视角 一.初始准备: 创建一个Blank项目.创建一个Game M ...

  9. Unity 第一人称、第三人称、漫游视角 控制器.

    前言 这是以前写的人物控制器(包含第一人称.第三人称.漫游视角),这里做个记录,方便后续参考使用. 实现 模型使用官方的,操作使用鼠标右键控制视角,键盘WASD.Shift控制人物移动. 切换到漫游视 ...

最新文章

  1. 卧槽!微软Python入门课居然汉化了!
  2. 出现adb连接不上的解决办法(转载)
  3. boost::hana::permutations用法的测试程序
  4. 微服务宏观把控与深入剖析
  5. POJ 2263 Heavy Cargo 多种解法
  6. [导入]PropertyGrid代码示例(Ext1.x)
  7. 员工为什么缺乏执行力?
  8. Android基于讯飞语音SDK实现语音识别
  9. 清华大学操作系统OS学习(十四)——文件系统和文件描述符
  10. 手把手,从零开始搭建个人博客网站(附源码)
  11. 【工具使用】SecureCRT的下载、安装图文详细过程介绍
  12. 计算机无法获取正常的ip地址,教你轻松解决Win7系统经常获取不到IP地址问题
  13. pdf文件如何转换成dwg文件
  14. 新MAC苹果M1芯片简要分析(是不是地表最强呢??)
  15. 在移动硬盘中安装win10和macos双系统
  16. [ipsec][crypto] 什么是AEAD加密算法中的AAD 及aad length
  17. 《Learn python3 the hard way》ex14 Prompting and Passing
  18. tkMapper插件的详细讲解
  19. Excel与PowerBI 之PowerQuery 编辑界面异同-PowerQuery 系列文章之三
  20. 追风筝的人 第九章

热门文章

  1. 水下图像融合增强Enhancing Underwater Images and Videos by Fusion
  2. 苏州新区c语言培训,苏州哪些地方可以培训C语言
  3. 求一个已知二维数组的最大子数组和(廖强,司宇)
  4. 企微私域运营销售额如何提升?
  5. PyTorch可视化工具-Tensorboard在线查看训练曲线、网络结构图等
  6. stata:stata软件教程(人大十八讲)(1) 第一章 stata入门
  7. 让FX DocuPrint P225 db激光打印机打印时不遗漏细节
  8. 【论文阅读】FC-Net: A Method of Few-Shot Network Intrusion Detection Based on Meta-Learning Framework
  9. 从TargetApi22升级到TargetApi26注意事项
  10. 3 2计算机专业学校有哪些,3十2学校有哪些好专业可以选择