涉及方法:

  1. 本文分别采用了 ‘collider+rigidbody’ / ‘character controller’ 两种方式共四种情况来分享

  2. 在代码中input采用unity基本的“Horizontal”+“Vertical”输入获取(unity新的那个input system用过包但还没自己实际了解过嘿嘿(●ˇ∀ˇ●))

  3. 如果是collider+rigidbody的话,使用的是rigidbody的MovePosition()方法

    如果是character controller的话使用的是该控制器的simplemove函数(对应还有一个move函数,区别在于simplemove在被调用时将使物体具备重力,move函数则和translate相似。)

  4. 对于鼠标控制方向的情况通过raycast+getpoint方法获取当前主摄像机与鼠标产生的射线找到与平面的交点,然后使用transform组件的LookAt方法调整朝向。

【使用character controller】准备:

  1. 在unity中创建好基本的平面和胶囊作为场景和角色(蓝色为z轴,代表transform.forward,即正面)
  2. 为平面添加collider(带2d的是2D项目使用的组件),为胶囊(角色)添加character controller(新建的胶囊会自带一个collider1,在添加character controller后会自带另一个collider2,所以可以将collider1删掉)

【使用character controller】编写move脚本:

第一种情况:角色移动方向与角色朝向一致:

{一些细节和注意事项都写在代码注释中辣~}

using UnityEngine;/*** 功能:角色移动控制[角色移动时永远朝正面]* */
public class move : MonoBehaviour
{//速度变量public float speed;//定义角色控制器public CharacterController cc;void Start(){//组件cc变量cc = transform.GetComponent<CharacterController>();//速度赋值speed = 10;}void Update(){//调用移动方法move_by_cc();}void move_by_cc(){//水平方向的输入获取(即A-D键或←→键)float x = Input.GetAxisRaw("Horizontal");//垂直方面的输入获取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始为0,在-1到1之间变化,对应的GetAxisRaw()则不会变化,直接返回1或-1 *//*上面的input使用GetAxis()时在松开按键后角色会继续移动一小部分距离,会产生一种“冰面滑动”的效果,使用GetAxisRaw()的话则即按即动,即松即停*/if (Mathf.Abs(x)>0.1f || Mathf.Abs(z) > 0.1f){//移动方向Vector3 toward_dir = new Vector3(x, 0, z);//角色朝向与移动方向一致transform.LookAt(transform.position + toward_dir);//不同于move函数,这里以秒为单位不能*Time.deltatime,不然会无法移动cc.SimpleMove(transform.forward * speed);}}
}

第二种情况:角色移动方向可以不与角色朝向一致(键盘控制移动,鼠标控制朝向):

{一些细节和注意事项都写在代码注释中辣~}

using UnityEngine;/*** 功能:角色移动控制[键盘控制移动,鼠标控制朝向]* */
public class move2 : MonoBehaviour
{//速度变量public float speed;//定义角色控制器public CharacterController cc;//摄像机public Camera viewCamera;void Start(){//组件cc变量cc = transform.GetComponent<CharacterController>();//速度赋值speed = 5;//当前主摄像机viewCamera = Camera.main;}void Update(){//调用移动方法move_by_cc();}void move_by_cc(){/*移动部分*///水平方向的输入获取(即A-D键或←→键)float x = Input.GetAxisRaw("Horizontal");//垂直方面的输入获取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始为0,在-1到1之间变化,对应的GetAxisRaw()则不会变化,直接返回1或-1 *//*上面的input使用GetAxis()时在松开按键后角色会继续移动一小部分距离,会产生一种“滑滑”的效果,使用GetAxisRaw()的话则即按即动,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移动方向Vector3 toward_dir = new Vector3(x,0,z);//不同于move函数,这里以秒为单位不能*Time.deltatime,不然会无法移动//(normalized指单位化,即此时该向量不具备大小仅具备方向)cc.SimpleMove(toward_dir.normalized * speed);}/*鼠标朝向部分*///生成从摄像机发射的射线,该射线穿过当前鼠标位置【因为视角透视原因,鼠标位置并不能代表实际我们希望的朝向,所以需要通过射线找到与平面的实际交点】Ray ray = viewCamera.ScreenPointToRay(Input.mousePosition);//创建一个平面,第一个参数和第二个参数构成法线,且平面穿过第二个参数点Plane groundPlane = new Plane(Vector3.up, Vector3.zero);//平面与射线相交返回发射点到相交点的距离float rayDistance;Vector3 point = Vector3.zero;//Raycast计算相交点并返回距离if (groundPlane.Raycast(ray, out rayDistance)){//获取到射线与平面的相交点,耶~point = ray.GetPoint(rayDistance);//指示线打印-用于测试//Debug.DrawLine(ray.origin, point, Color.red);}//角色朝向-鼠标预期方向Vector3 heightCorrectedPoint = new Vector3(point.x, transform.position.y, point.z);transform.LookAt(heightCorrectedPoint);}
}

------------------------------------------------------------------另一种方式------------------------------------------------------------------

【使用collider+rigidbody】准备:

  1. 在unity中创建好基本的平面和胶囊作为场景和角色(蓝色为z轴,代表transform.forward,即正面)
  2. 为平面添加collider(带2d的是2D项目使用的组件),为胶囊(角色)添加collider和rigidbody(带2d的是2D项目使用的组件)并锁定x,z轴的旋转防止角色倒下。


【使用collider+rigidbody】】编写move脚本:

第一种情况:角色移动方向与角色朝向一致:

{一些细节和注意事项都写在代码注释中辣~}

using UnityEngine;/*** 功能:角色移动控制[角色移动时永远朝正面]* */
public class move3 : MonoBehaviour
{//速度变量public float speed;//Rb刚体public Rigidbody rb;void Start(){//组件rb变量rb = transform.GetComponent<Rigidbody>();//速度赋值speed = 7;}
//【将Update函数修改为FixedUpdate,并且deltaTime修改为fixedDeltatime移动似乎会流畅一些,感觉有一点点变化,但是也不确定是不是心理作用】void Update(){//调用移动方法move_by_rb();}void move_by_rb(){//水平方向的输入获取(即A-D键或←→键)float x = Input.GetAxisRaw("Horizontal");//垂直方面的输入获取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始为0,在-1到1之间变化,对应的GetAxisRaw()则不会变化,直接返回1或-1 *//*上面的input使用GetAxis()时在松开按键后角色会继续移动一小部分距离,会产生一种“滑滑”的效果,使用GetAxisRaw()的话则即按即动,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移动方向Vector3 toward_dir = new Vector3(x, 0, z);//角色朝向移动方向transform.LookAt(transform.position + toward_dir);//MovePosition方法,以帧为单位,记得*Time.deltaTime哦~(normalized指单位化,即此时该向量不具备大小仅具备方向)rb.MovePosition(rb.position + toward_dir.normalized * speed * Time.deltaTime);}}
}

第二种情况:角色移动方向可以不与角色朝向一致(键盘控制移动,鼠标控制朝向):

{一些细节和注意事项都写在代码注释中辣~}

using UnityEngine;/*** 功能:角色移动控制[角色移动时永远朝正面]* */
public class move4 : MonoBehaviour
{//速度变量public float speed;//Rb刚体public Rigidbody rb;//摄像机public Camera viewCamera;void Start(){//组件rb变量rb = transform.GetComponent<Rigidbody>();//速度赋值speed = 7;//主摄像机viewCamera = Camera.main;}//【将Update函数修改为FixedUpdate,并且deltaTime修改为fixedDeltatime移动似乎会流畅一些,感觉有一点点变化,但是也不确定是不是心理作用】void Update(){//调用移动方法move_by_rb();}void move_by_rb(){/*移动部分*///水平方向的输入获取(即A-D键或←→键)float x = Input.GetAxisRaw("Horizontal");//垂直方面的输入获取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始为0,在-1到1之间变化,对应的GetAxisRaw()则不会变化,直接返回1或-1 *//*上面的input使用GetAxis()时在松开按键后角色会继续移动一小部分距离,会产生一种“滑滑”的效果,使用GetAxisRaw()的话则即按即动,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移动方向Vector3 toward_dir = new Vector3(x, 0, z);//MovePosition方法,以帧为单位,记得*Time.deltaTime哦~(normalized指单位化,即此时该向量不具备大小仅具备方向)rb.MovePosition(rb.position + toward_dir.normalized * speed * Time.deltaTime);}/*鼠标朝向部分*///生成从摄像机发射的射线,该射线穿过当前鼠标位置【因为视角透视原因,鼠标位置并不能代表实际我们希望的朝向,所以需要通过射线找到与平面的实际交点】Ray ray = viewCamera.ScreenPointToRay(Input.mousePosition);//创建一个平面,第一个参数和第二个参数构成法线,且平面穿过第二个参数点Plane groundPlane = new Plane(Vector3.up, Vector3.zero);//平面与射线相交返回发射点到相交点的距离float rayDistance;Vector3 point = Vector3.zero;//Raycast计算相交点并返回距离if (groundPlane.Raycast(ray, out rayDistance)){//获取到射线与平面的相交点,耶~point = ray.GetPoint(rayDistance);//指示线打印-用于测试//Debug.DrawLine(ray.origin, point, Color.red);}//角色朝向-鼠标预期方向Vector3 heightCorrectedPoint = new Vector3(point.x, transform.position.y, point.z);transform.LookAt(heightCorrectedPoint);}
}

以上就是本次的分享内容辣~(●ˇ∀ˇ●),可以看到两种方式的本质操作是没有什么较大的区别的,仅在于准备部分的不同和代码中对应组件的调用不同而已,不过这里还要告诉大家的是,一般使用character controller是为了自定义一些更‘游戏化’的物理效果,而collider+rigidbody的方法则更偏向于真实物理世界,但是很多时候游戏不一定越真实就越舒服。

unity3d俯视角简易移动控制脚本及其易错点小分享相关推荐

  1. locust安装成功为什么运行脚本后打不开页面或运行脚本会报错

    locust安装成功为什么运行脚本后打不开页面或运行脚本会报错? 小编之前安装环境后还用过一段时间,后面准备继续用的时候,却发现运行脚本都会报错,所以页面也打开不开啰. 安装locust成功 locu ...

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

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

  3. unity判断鼠标移动方向_【反向元气骑士】用unity实现俯视角射击是一种怎样的体验...

    哈喽大家好我是yumir. 最近沉迷元气骑士,自从官方把各种"bug"修复之后,这个游戏对我这种手残玩家来说实在是太难了.既然打不过,那我就自己写一个,不就是俯视角射击吗,分分钟给 ...

  4. 【unity实战】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(一)(附源码)

    文章目录 本期目标 前言 欣赏 开始 1. 角色移动和场景搭建 2. 绑定枪械 2.1 首先将各种枪械的素材添加给人物作为子物体 2.2 给枪械也分别添加两个子物体用作标记枪口和弹仓位置 3. 枪械动 ...

  5. unity fixedupdate_3D俯视角射击——用Unity还原东方弹幕(上)

    前言 之前我们的专栏中介绍过2D的俯视角射击,这次就来试试在3D场景下的实现.移动射击的实现方法差不多,所以本次的主要目标是在3D场景下还原东方的符卡(弹幕)效果. 我们先来看看最终结果: 可配置的弹 ...

  6. creator 跳跃弧线_(转)CocosCreator零基础制作游戏《极限跳跃》四、添加游戏主场景控制脚本...

    CocosCreator零基础制作游戏<极限跳跃>四.添加游戏主场景控制脚本 前面简单的实现了主界面的UI设置,现在我们开始制作游戏的控制脚本. 在资源管理器的Script文件夹中,点击右 ...

  7. dotween unity 延时_3D俯视角射击——用Unity还原东方弹幕(上)

    作者:QXYO 前言 之前我们的专栏中介绍过2D的俯视角射击,这次就来试试在3D场景下的实现.移动射击的实现方法差不多,所以本次的主要目标是在3D场景下还原东方的符卡(弹幕)效果. 我们先来看看最终结 ...

  8. Unity填坑之俯视角相机水平面方向移动

    Unity填坑之俯视角相机水平面方向移动 文章目录 Unity填坑之俯视角相机水平面方向移动 前言 一.需求分析 二.解决方案有两种 1.模拟一个小人 2.通过四元数旋转的方式 总结 前言 碰到一个需 ...

  9. Unity3D教程:用快捷键控制物体的激活状态

    Unity3D中我们在调试的时候,经常会把一些物体设置成未激活状态,如下图一样,但是当物体有子物体的时候总会有这个提示框,让后再去点这个框,总会觉的有些麻烦,以下快捷键就会很快实现这个功能: Unit ...

最新文章

  1. 微服务中的网关到底是个什么鬼?
  2. IOS CALayer
  3. Matlab小波包分解后如何求各频带信号的能量值?
  4. MySQL 4到5的快速升级
  5. Matlab三种归一化方法
  6. 高级软件工程第七次作业:东理三剑客团队作业-随笔2
  7. 微课|玩转Python轻松过二级(1.1节):Python命令式编程与函数式编程模式
  8. Hangover C语言 UVA2294
  9. GIT在Linux上的安装和使用简介
  10. win、linux下tomcat内存的修改
  11. concat oracle 多个字符串_12个常用的JavaScript字符串方法
  12. MATLAB 2018a安装
  13. Android项目导入高德地图
  14. n1盒子当无线打印服务器,n1下ubuntu安装cups配置airprint网络打印服务器
  15. 信号与系统MATLAB版pdf,信号与系统基础(MATLAB版)
  16. 只会纯硬件,让我有点慌
  17. gnu coreutils4.5.1 hostid.c源码解读
  18. 北京国际学校IB考试均分稳得一匹,IB考试结果揭秘
  19. 52单片机课程设计——利用52单片机的智能窗帘设计论文+源码
  20. 《生活,是很好玩的》读书日记

热门文章

  1. Cent OS借助YUM快速安装MySQL
  2. 网络协议之:基于UDP的高速数据传输协议UDT
  3. 杨辉三角队列c语言程序,C语言完整队列 与链式队列实现杨辉三角
  4. Biotin/生物素-蛋白交联剂/CHO aldehyde醛基乙醛-蛋白交联剂/OPSS邻吡啶二硫巯基吡啶-蛋白交联剂
  5. 考虑线程安全的List集合选择
  6. 默然日记20151123
  7. vs编写java_vs code编写java
  8. 计算机系统配置有哪些,电脑配置低装什么系统比较好?(16个回答)
  9. 山西大学计算机研究生考纲,2020考研大纲
  10. GA/百度统计/Piwik/JYC:网站分析工具的Cookie设置和访次切分规则