计算过程如下:

1,通过由主角中心raycast一条竖直射线获得主角所在处地面法线,用作主角的newUp。

注:一定要从主角中心raycast,而不要从player.transform.position,因为如果player的模型原点在脚上,则player.transform.position可能就在地面以下了,向下raycast得不到与地面的交点了就。

2,根据主角forward和newUp计算newForward。

3,使用Quaternion.LookRotation (newForward, newUp)获得主角新的rotation。

结果如图:

   

代码:

     //note, the code here suppose our character use a capsuleCollider and the floors' layerMask is "floor"..

     //..if yours' is not, you should make some change.

RaycastHit hitInfo;
        Vector3 capsuleColliderCenterInWorldSpace=GetComponent<CapsuleCollider> ().transform.TransformPoint (GetComponent<CapsuleCollider>().center);
        bool isHit=Physics.Raycast (capsuleColliderCenterInWorldSpace,new Vector3(0f,-1f,0f),out hitInfo,100f,LayerMask.GetMask("floor"));

Vector3 forward=GetComponent<Rigidbody>().transform.forward;
       
        Vector3 newUp;
        if (isHit) {
            newUp = hitInfo.normal;
        } else {
            newUp = Vector3.up;
        }

     //limit lean angle (if do not need to limit lean angle, remove the code block below)

     {

       const float maxDegreeFromWorldUp = 45.0f;//lean angle limited to 45 degree
            //clamp newUp to let is not exceed 45 degree from WorldUp(Vector3.up)
            newUp=Vector3.RotateTowards (Vector3.up, newUp, maxDegreeFromWorldUp / 180.0f * Mathf.PI, 0.0f);

     }
        Vector3 left = Vector3.Cross (forward,newUp);//note: unity use left-hand system, and Vector3.Cross obey left-hand rule.
        Vector3 newForward = Vector3.Cross (newUp,left);
        Quaternion oldRotation=GetComponent<Rigidbody>().transform.rotation;
        Quaternion newRotation = Quaternion.LookRotation (newForward, newUp);

     float kSoftness=0.1f;//if do not want softness, change the value to 1.0f
        GetComponent<Rigidbody> ().MoveRotation (Quaternion.Lerp(oldRotation,newRotation,kSoftness));

unity, 让主角头顶朝向等于地面法线(character align to surface normal)的更多相关文章

  1. 【OpenGL】法线变换详解(Normal Transform)[转]

    http://blog.csdn.net/xiajun07061225/article/details/7762711 在图形学中,同样的一个模型视图变换矩阵可以用来变换点.线.多边形以及其它几何体, ...

  2. Unity Shader入门教程(二)最基本的Diffuse和Normal样例

    本教程参考了<猫都能学会的Unity3dShaderLab教程.CHM>, 1.请上网搜索并下载此文件. 2.随后再下载里面提到的素材: http://vdisk.weibo.com/s/ ...

  3. 【Unity Shaders】法线纹理(Normal Mapping)的实现细节

    写在前面 写这篇的目的是为了总结我长期以来的混乱.虽然题目是"法线纹理的实现细节",但其实我想讲的是如何在shader中编程正确使用法线进行光照计算.这里面最让人头大的就是各种矩阵 ...

  4. 【Unity Shaders】Reflecting Your World —— Unity3D中的法线贴图和反射

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  5. 【Unity Shader】(四) ------ 纹理之法线纹理、单张纹理及遮罩纹理的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...

  6. Unity 用户手册用户指南二维纹理 (Texture 2D)

    http://www.58player.com/blog-2327-953.html 二维纹理 (Texture 2D) 纹理 (Textures) 使您的 网格 (Meshes).粒子 (Parti ...

  7. cocos2d-x 3.0游戏实例学习笔记 《跑酷》第四步--地图循环&amp;主角加入动作

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  8. 【Unity Shader】新书封面 — Low Polygon风格的渲染

    写在前面 最近又开心又担心,因为我的书马上就要上市了,开心当然是因为等了这么久终于可以如愿了,担心是因为不少人对它的期待都很大,我第一次写书,能力也有限,不知道能不能让大家满意,让大家也都喜欢上它.不 ...

  9. unity surface shader 1

    Unity ShaderLib :  CGPROGRAM  ENDCG之间是CG代码,之外的代码功能都由ShaderLib提供,CG中的一些方法比如tex2D(...)也是ShaderLib对CG进行 ...

随机推荐

  1. Oracle设置为自启动

    Oracle设置为自启动 学习了:http://blog.itpub.net/31015730/viewspace-2148412/ oracle自带dbstart命令,主要进行系统启动设置: 在/e ...

  2. Jmeter-Maven-Plugin高级应用:Log Levels

    Log Levels Pages 12 Home Adding additional libraries to the classpath Advanced Configuration Basic C ...

  3. 【问题&解决】还原数据库提示“介质集有2个介质簇,但只提供了1个。必须提供所有成员”的解决办法

    今天在对数据库备份与还原的过程中,我遇到一个问题“介质集有2个介质簇,但只提供了1个.必须提供所有成员”,下面详细的介绍一下遇到问题的经过与问题解决的方法! 一.备份与还原遇到的问题描述与解决方法: ...

  4. Java从零开始学四(数据类型)

    一.Java数据类型划分 二.基本数据类型 No. 数据类型 大小/位 可表示的数据范围 1 long(长整数) 64 -9223372036854775808 ~ 92233720368547758 ...

  5. Emmet初探2

    关于Emmet Emmet插件的前身是Zen coding,可以大幅度提高前端开发效率的一个工具,也有人说类似于jade(高性能的模板引擎,它深受 Haml 影响,它是用 JavaScript 实现的 ...

  6. Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

    一.简单介绍 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一 ...

  7. eclipse tomcat路径更改后启动报错

      eclipse tomcat路径更改后启动报错 CreateTime--2018年5月3日14:48:22 Author:Marydon 1.情景还原 2.原因 本地的tomcat路径修改后,ec ...

  8. 〖Linux〗Qt5.2.0+gsoap开发Android的NDK程序遇到错误的解决

    1.  error: cannot convert ‘int*’ to ‘hostent**’ for argument ‘5’ to.. 原因分析: 缺少的宏定义,导致使用了错误的函数原型. 被调用 ...

  9. PLY格式介绍

    PLY是一种电脑档案格式,全名为多边形档案(Polygon File Format)或 斯坦福三角形档案(Stanford Triangle Format).  史丹佛大学的 The Digital ...

  10. Centos6.5搭建dhcpd服务

    dhcpd动态获取ip地址,对于小型局域网很便利的.在不大的网络社会静态ip也是不错的! 环境 centos6.5  10.10.24.1 (dns-server)   winxp sp3 (clie ...