关于Unity中ARPG游戏人物移动(专题十一)
ARPG:动作型角色扮演类游戏
大多数的ARPG游戏都是使用摇杆操作,以第三人称摄像机的方式来跟随主角,实际上人物只走八个方向,上,下,左,右,左上,左下,右下,右上
控制角色移动的思路
1: 在ARPG游戏中,主角人物在摇杆下控制行走;
2: 主角人物遇到障碍物(碰撞器)将不会穿越过去;
3: 摇杆控制主角人物8个方向的行走;
4: 使用CharacterController 角色控制器组件: 让你在受制于碰撞的情况下很容易的进行运动,而不用处理刚体,实际上没有刚体的物理特性。角色控制器不受力的影响,仅当你调用Move函数时才运动。它执行运动,但是受制于其他碰撞器。
本来以前都是在角色上面挂载刚体(用里面的重力)和碰撞器组件,如果碰到其他的刚体还会受力会受到一些不好的影响,用了CharacterController 就不会有这种不相关的物理力的影响了。
5: 调用角色控制器的Move函数移动角色;
6: 根据摇杆的方向旋转人物动画;
CharacterController组件
1: 属性面板属性:
Slope Limit: 角色碰撞器只能爬比这个指定角度低的斜坡:(单位是degree)
Step Offset: 上楼梯模式,小于Step Offset 的台阶,可以直接上去;
Skin Width: 两个碰撞器可以互相渗透深入皮肤宽度,一般设置成radius的10%;
Min Move Distance: 调用Move函数移动的最小移动量,如果移动距离比这个小,将不移动;
center: 相对与transform的位置角色叫胶囊体中心;
height: 胶囊体高度;
Radius: 胶囊体的半径;
2: 碰撞检测:
void OnControllerColliderHit(ControllerColliderHit hit) {},和一般的碰撞器一样。有碰撞后会调用这个接口。只会在和其他带有CharacterController组件的物体发生碰撞时才调用。
目前已知这个角色控制器的碰撞接口只有这个,如果要持续碰撞,我会加一个BoxCollider组件或者Capsule之类的碰撞器,调用三个碰撞接口
3: 重要方法:
Move(Vec3 offset): 移动的距离;
如果一个角色挂载了CharacterController组件。那么要控制这个角色的移动,其实不必改变角色节点的位置,只需对这个组件进行Move操作,角色就会跟着走。
我把这个组件理解为一个可以牵动节点的可以设置特殊移动属性的胶囊体碰撞器组件Capsule Collider
遥杆编写的基本思路与原理
1:以8个方向为例,将整个圆分为 下,右下,右,右上,上,左上, 左, 左下;
2:当我们的遥感中心点位于某一个方向的范围内,那么就属于这个方向;
3.排除一个无效的摇杆区域,在这个区域内主角不会跟着移动
4.角色移动的距离是一个标量,等于速度乘于时间,而角色移动的整个行为是一个向量,所以还要考虑方向,获得摇杆的角度得知运动方向后还要把角色到最终目的地的标量距离分解成X和Z轴方向上的距离。
根据摇杆的方向算出当前距离所对应的向量的分解的系数
5.前面都是摇杆的坐标轴解析,这里是从人物的Y轴的角度看各个欧拉角,也就是编辑器上的Transform组件的Rotation里面的Y的值对应的该主角节点的旋转方向角度,0度是角色面朝前方
实例
1.创建Unity工程项目和文件目录
2.导入人物模型资源和地图资源,以及摇杆包(79)
3.人物模型的材质球shader使用Mobile Diffuse,关联好贴图,设置模型---->Rig---->Animation Type---->Legacy---->Apply
4.在人物模型的Animation里添加跑动的动画,136-161帧是跑动的帧,Wrap Mode---->Loop---->Apply,角色配置完毕,拖进场景中
5.创建一个平面Plane,关联材质,放大10倍
6.不需要添加碰撞器,只要给主角添加CharacterController组件,调整组件的胶囊体到完全盖住主角,它有碰撞区域但是不受力的影响,千万别再加Rigidbody组件了,会使得CharacterController组件无效。
7.添加摇杆,Hedgehog Team---->Easy Touch---->Add Easy Touch For C#,Hedgehog Team---->Easy Touch---->Extension---->Adding a new joystick
8.调整摄像机的位置,到可以看见主角运动的最佳位置
9.在主角下面挂载一个脚本Person来通过摇杆控制角色移动
Person.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- enum DIR//定义一个枚举来区分角色移动的八个方向
- {
- INVALID_DIR = -,
- UP = ,
- DOWN = ,
- LEFT = ,
- RIGHT = ,
- RU = ,
- LU = ,
- LD = ,
- RD = ,
- }
- public class person : MonoBehaviour
- {
- float move_speed = 8.0f;//角色移动速度
- CharacterController c_ctrl;//角色控制器组件
- public EasyJoystick joystick;//摇杆
- float[] x_set;//八个方向在X轴上的分解系数
- float[] z_set;//八个方向在Z轴上的分解系数
- float[] rot_set;//人物面的朝向的角度表
- Vector3 camera_offset;
- // Use this for initialization
- void Start()
- {
- this.c_ctrl = this.GetComponent<CharacterController>();
- //按照上,下,左,右,右上,左上,左下,右下的顺序配置
- this.x_set = new float[] { , , -, , 0.707f, -0.707f, -0.707f, 0.707f };//cos45=0.707,sin45=0.707
- this.z_set = new float[] { , -, , , 0.707f, 0.707f, -0.707f, -0.707f };
- this.rot_set = new float[] { , , -, , , -, -, };
- this.camera_offset = Camera.main.transform.position - this.transform.position;//获取当前摄像机和人物的三维距离
- }
- int get_dir(float r)
- {
- if (r >= -Mathf.PI && r < - * Mathf.PI / )
- { // 左的一部分
- return (int)DIR.LEFT;
- }
- else if (r >= - * Mathf.PI / && r < - * Mathf.PI / )
- {//左下
- return (int)DIR.LD;
- }
- else if (r >= - * Mathf.PI / && r < - * Mathf.PI / )
- {//下
- return (int)DIR.DOWN;
- }
- else if (r >= - * Mathf.PI / && r < - * Mathf.PI / )
- {//右下
- return (int)DIR.RD;
- }
- else if (r >= - * Mathf.PI / && r < * Mathf.PI / )
- {//右
- return (int)DIR.RIGHT;
- }
- else if (r >= * Mathf.PI / && r < * Mathf.PI / )
- {//右上
- return (int)DIR.RU;
- }
- else if (r >= * Mathf.PI / && r < * Mathf.PI / )
- {//上
- return (int)DIR.UP;
- }
- else if (r >= * Mathf.PI / && r < * Mathf.PI / )
- {//左上
- return (int)DIR.LU;
- }
- else if (r >= * Mathf.PI / && r < * Mathf.PI / )
- {//左的另一部分
- return (int)DIR.LEFT;
- }
- return (int)DIR.INVALID_DIR;//无效的区域
- }
- void walk_update()
- {
- float x = this.joystick.JoystickTouch.x;//摇杆坐标系的X坐标
- float y = this.joystick.JoystickTouch.y;//摇杆坐标系的Y坐标
- float len = (x * x + y * y);//不开根号是因为开销太大,而且是在Update里面,每帧都开根号受不了
- if (len < (0.5f * 0.5f))//摇杆移动到这片区域是无效的
- {
- return;
- }
- // 获取这个方向
- float r = Mathf.Atan2(y, x); // 使用反三角函数, 获取向量的角度, [-PI, PI]
- int dir = this.get_dir(r);
- if (dir != (int)DIR.INVALID_DIR)
- {
- float s = this.move_speed * Time.deltaTime;//每一秒要移动的距离
- Vector3 offset = new Vector3(s * this.x_set[dir], , s * this.z_set[dir]);//把这个距离分解到X和Z方向上
- this.c_ctrl.Move(offset);//每一帧都移动
- // 切换人物行走的朝向
- Vector3 e_rot = this.transform.eulerAngles;
- e_rot.y = this.rot_set[dir];
- this.transform.eulerAngles = e_rot;
- // end
- }
- // end
- }
- // Update is called once per frame
- void Update()
- {
- this.walk_update();
- Camera.main.transform.position = this.transform.position + this.camera_offset;//保持人物和摄像机的距离不变
- }
- }
10.运行效果
关于Unity中ARPG游戏人物移动(专题十一)的更多相关文章
- 关于Unity中的道具拾取(专题六)
原理就是把道具做成触发器,触发器就是当我们有碰撞发生的时候,只会检测碰撞,而不会有任何改变物理运动状态的过程. 触发器非常适合道具拾取,因为它不会改变原本运动物体的任何物理属性,但是依然会检测碰撞,响 ...
- 开发指南专题十一:JEECG微云高速开发平台--基础用户权限
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zhangdaiscott/article/details/26580037 开发指南专题 ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
- 在Unity中使用UGUI修改Mesh绘制几何图形
在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...
- Unity中使用WebView
Unity中使用WebView @(设计) 需求,最近游戏中需要引入H5直播页面和更新比较频繁的赛事页面,需求包括:加密传参数.和Unity交互,在Unity框架下其实有几种方案: 内置函数Appli ...
- Unity中创建二维码
在网络上发现了一个可以把字符串转换成二维码的dll,但是我们要怎么使用他呢.不废话,直接进入主题. 用到的引用 using UnityEngine;using ZXing;using ZXing.Qr ...
- 在Unity中创建可远程加载的.unity3d包
在一个Unity项目中,发布包本身不一定要包括所有的Asset(译为资产或组件),其它的部分可以单独发布为.unity3d,再由程序从本地/远程加载执行,这部分不在本文讨论范围.虽然Unity并没有直 ...
- 【原创翻译】初识Unity中的Compute Shader
一直以来都想试着自己翻译一些东西,现在发现翻译真的很不容易,如果你直接把作者的原文按照英文的思维翻译过来,你会发现中国人读起来很是别扭,但是如果你想完全利用中国人的语言方式来翻译,又怕自己理解的不到位 ...
- 【unity shaders】:Unity中的Shader及其基本框架
shader和Material的基本关系 Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这个输出来将图 ...
随机推荐
- u3d 鼠标点击位置,物体移动过去。 U3d mouse clicks position, objects move past.
u3d 鼠标点击位置,物体移动过去. U3d mouse clicks position, objects move past. 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱: ...
- 项目冲刺Forth
Forth Sprint 1.各个成员今日完成的任务 蔡振翼:修改部分博客 谢孟轩:续借功能和编辑资料功能的实现 林凯:初步实现登录功能 肖志豪:帮助其他人解决一些问题 吴文清:编写完善管理员个人界面 ...
- 随机查出满足条件的5条数据(tp5)
随机查出满足条件的5条数据 public function showQuestion() { $data[; $data[ $data['level'] = (int)$data['level']; ...
- CoordTools
APPLICATION_VERSION="JTNDYXBwbGljYXRpb24lMjBuYW1lJTIwJTNEJTIwJTIyQ29vcmRUb29sc1BybyUyMiUyMHZlcn ...
- Docker网络模式说明
现在的Docker版本不推荐继续使用Link了,而是推荐用网络模式解决问题,简单讲一下最常用的几个网络模式,其他我用到时候再补充. bridge -net不加参数就是默认的bridge模式,这个默认b ...
- [Java web]Spring+Struts2+Hibernate整合过程(2)
摘要 上篇文章介绍了一种整合方式,不妨就叫做有hibernate配置文件的方式,这里介绍一种不用hibernate.cfg.xml的一种配置方式,为了方便,就仍在上篇的demo中,继续修改了. 步骤 ...
- Google+ 团队的 Android UI 测试
https://github.com/bboyfeiyu/android-tech-frontier/tree/master/android-blog/Google%2B%20%E5%9B%A2%E9 ...
- Linux 下安装 Mongodb
mongodb在linux下面的安装应该是很简单的,但是有一个小点需要注意,这也就是我为什么写这篇博客的原因. 首先到其官网上下载最新稳定版,解压到目录,如/usr/local/mongodb 在mo ...
- 奇怪吸引子---LuChen
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- linux设置预留端口号,防止监听端口被占用 ip_local_reserved_ports
1. 背景 linux服务器启动时,会对指定的端口进行监听bind,如果同一个机器上这个端口已经被使用,则监听失败,程序无法启动. linux客户端连接服务器accept时,系统会分配本地临时端口用于 ...