0x0.引言

在一些游戏内的星球体积是很小的,但是小小的星球仍然有引力。游戏内的物体是可以贴在其表面上的,如同文学作品《小王子》中所形容的小小星球那样。

图片来源点击此处

对于静态物体(如上图的小树苗小花等)而言,可以将其直接放置在小小星球上的固定位置,但是对于动态可移动的物体呢?如果需要实现动态的物体沿着球面行走呢?注意到上图的星球并非一个规则的球体,其存在凸起等。那么如何在Unity中实现这样的效果?

本文介绍如何使用Unity制作一个球面行走的效果,其最终效果如下图所示:

0x1.思路

要实现这样的效果,其思路并非是使得需要绕面行走的物体单纯去计算其绕某一个点旋转。因为其表面并非一个规则球体。

那么如何着手解决这个问题?

思考一下现实中物体是如何贴在星球表面的呢?其主要原因便是重力。在Unity的物理引擎中对重力是实现了的,并且可以通过Rigidbody组件去修改其是否受重力影响。对于重力的整体设置则可以在ProjectSetting的Physics选项卡中找到。

但是Unity的重力方向默认是朝向世界坐标-y轴方向的,仅仅调节此处的设置是并不能满足需求的。那么从这个地方思考开去,我们就能得到其解决思路:模拟重力。

0x2.编码实现

对于重力模拟,仍然通过Rigidbody组件来实现,首先需要将上面默认的useGravity选项取消防止物体受到默认重力设置的影响。

然后需要确定一个重力的方向,这里可以通过对场景中某个物体的位置引用来计算重力方向,也就是说,加入场景中存在一个物体作为引力中心,它对其他物体产生重力影响,其好处是可以通过调整其位置来动态更改引力中心,也可以通过更换引用来实现。

在这种方式下,重力方向为从物体的位置到引力中心位置的方向向量。如下图中黄色箭头所示:

这里的实现方式比较简单,其代码也就一句话:

//gravityCenter为引力中心

Vector3 gravityDir = (transform.position - gravityCenter.position).normalized;

但是对于其物体如何“站立”的问题,可以分为两种计算方式,其不同的计算方式导致的效果也是不一样的。其一是可以将物体站立的方向设置为上图中重力方向的反方向。这样粗略看上去的效果是没有问题的,但是对于一些细节还是会有错误。如果物体站立在一个斜坡上,这样的物体站立的朝向会出现错误,会出现下图的结果:

这样是不太符合常理的,虽然现实生活中是通过摩擦力重力等等各种力的相互作用导致我们站在斜坡上,但是很明显不应该是这样的站立方向。

这种方向的编码实现也是非常简单的:

transform.rotation = Quaternion.FromToRotation(transform.up, gravityDir) * transform.rotation;

另外一种计算方式则比较符合现实情况,站立方向朝向脚下地面的法线方向,也就是下图中橙色箭头方向。

要实现这样的站立方向需要用到碰撞检测,需要获取到脚下的方向与碰撞体的碰撞点,然后对其进行法线方向的计算,好在Unity中是直接提供了碰撞点的,我们可以在OnCollisionEnter/OnCollisionStay方法中对其进行计算。

private void OnCollisionEnter(Collision collision)

{

transform.rotation = Quaternion.FromToRotation(transform.up,

//这里只取第一个碰撞点,如果没有穿透,一般只有一个碰撞点,但是如果是墙角等情况还是要分开处理

collision.contacts[0].normal) * transform.rotation;

}

这样处理的方式也是可以的,但是在凹凸不平的表面行走时,可能出现非常鬼畜的情况。故需要对其碰撞角度做出一定限制,在角度未达到某一个阈值的时候不需要进行法线站立。其编码可以改成如下形式:

private void OnCollisionEnter(Collision collision)

{

float angle = Vector3.Angle(transform.up, collision.contacts[0].normal);

if (angle > 45f)

transform.rotation = Quaternion.FromToRotation(transform.up, collision.contacts[0].normal) * transform.rotation;

else

transform.rotation = Quaternion.FromToRotation(transform.up, (transform.position - gravityCenter.position).normalized) * transform.rotation;

}

这样做在一定程度上缓解了鬼畜问题,但是距离“好用”的程度还差不少,此处仅提供思路,具体优化可以自行去调试实现。

0x2.示例代码

使用第一种站立方式的移动代码具体脚本可以点击此处下载。

0x3.使用方法

将脚本挂载在移动物体上,赋值上正确的GravityCenter,运行后按下w/s键移动即可预览效果。

unity 画球面_Unity实现球面行走相关推荐

  1. Unity学习日志_Unity地形系统简介

    Unity学习日志_Unity地形系统简介 地形创建: Terrain中的组件: Transform Terrain 四大功能: paint Terrain,可以选择下面几种具体的模式: Create ...

  2. 通过unity画弧线

    using UnityEngine; using System.Collections;public class Test : MonoBehaviour {public int a;//a>0 ...

  3. 基于UGUI的Unity画线工具

    基于UGUI的Unity画线工具 最近项目里需要做一个画线的小游戏,LineRenderer不是很好用,自己撸了一个小工具,效果如下 下面上代码 using System.Collections.Ge ...

  4. Unity学习日志_Unity父子关系与Camera

    Unity学习日志_Unity父子关系与Camera ​ 本次组件简单介绍将不包含monoBehaviour类及其向上回溯的父类. 1. 关于父子物体 ​ 首先需要声明的一点是所有游戏物体的Trans ...

  5. unity 画球面_unity中实现Mesh画球体、半球体、四分之一球体以及任意弧面

    感谢两篇文章: mesh绘制模型:https://blog.csdn.net/qq_29579137/article/details/77369734?depth_1-utm_source=distr ...

  6. unity 画球面_Unity Gizmos教程之一 设置颜色绘制正方体球体

    GizmosTest 脚本具体内容如下: using UnityEngine; public class GizmosTest : MonoBehaviour { // Use this for in ...

  7. unity 画球面_unity3d第一个例子--制作一个简单的球体碰撞墙面

    思路 当然首先应该先新建立一个地面,有地面才有一切(floor) 再建立一面墙WaLl,一面墙也就是用100个预制的正方体组成 我们不可能让发射的子弹bullet,朝着一个方向射击shoot 所以需要 ...

  8. ugui unity 取消选择_Unity暑期萌新入门:环境篇

    大家好,新一期又跟大家见面了. 上一节我们完成了角色的移动控制,然而John只能在空白的场景中移动.因此接下来这一节我们将添加关卡.调节光照,让John来到阴森的鬼屋.然后设置NavMesh(导航网格 ...

  9. unity 平移图片_Unity 两张背景的切换平移

    两张背景图片向左移动,当屏幕看见的时候. 使用的是Unity自带的Sprite,当然也可以使用NGUI Sprite using UnityEngine; using System.Collectio ...

  10. unity 粒子插件_unity的基本认识——走进unity

    今后一个月小编将围绕unity游戏开发进行总结,这是第一篇.这一篇将围绕什么是unity以及它的初步认识(用途和优势)敬请期待下一篇(我的第一个unity文件). 什么是Unity? 是一个游戏引擎. ...

最新文章

  1. 谷歌大脑新算法,不折腾TPU就能加快AI训练速度
  2. ZOJ1563 (动态规划)
  3. VB 6.0中如何访问EXCEL 2007及EXCEL 2010
  4. Oracle下scott用户无法登录
  5. suse linux下交叉编译,阐述SUSE 10.1交叉编译环境构建方法
  6. 2021“MINIEYE杯”中国大学生算法设计超级联赛(10)Pty loves string(Border+二维数点)
  7. PostgreSQL 安装 用户配置
  8. java ee 三层架构_JavaEE的三层架构
  9. 超宽屏幕比例_显示器屏幕比例与分辨率对照表
  10. TFT工业串口屏方案
  11. CRM客户关系管理系统的设计与实现
  12. 如何成为技术大牛 ?
  13. java毕业设计水果网店管理系统mybatis+源码+调试部署+系统+数据库+lw
  14. 22-5 论如何将标准中国地图矢量化并且导入arcgis中
  15. cad抠图 lisp_[原创]几个超级有用的裁剪用autocad--lisp程序
  16. 【POJ 3580】 SuperMemo
  17. 从零开始仿写一个抖音App——音视频开篇,移动安全入门
  18. 笨办法学Python 25
  19. 11月末.wang域名总量15强:易名中国榜首 份额涨5%
  20. css 高度随宽度比例变化

热门文章

  1. [每日一题]10、一道关于九宫格的面试题
  2. native mysql 分区_MySQL-表分区
  3. 考研数学(二)知识点回顾及笔记(第五章 定积分及应用)
  4. python自动添加微信好友_Python实现微信自动通过好友申请并发送加群链接!
  5. Python re库match(),serach(),findall()和finditer()方法使用
  6. 平面设计师okr_还在头疼怎么写OKR,这可能是最全的落地指导手册了
  7. 三相桥式全控整流电路simulink仿真_三相二极管桥式整流电路分析与仿真
  8. datax(25):插件加载原理
  9. 小郡肝火锅点餐系统——测试部署发布
  10. @submit.native.prevent作用