计算过程如下:

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. Cognos与Firefox的那些事

    最近怀着一颗好奇的心装了Win10系统,作为一个Coder,或多或少的这么久以来对于它的兼容性还是秉着一颗质疑的态度.但是一切事情都要敢于尝试,毕竟Win10的用户体验还是很好的.和预料的一样,问题马 ...

  2. 在myeclipse中写sql语句的细节问题

    注意类型,varchar 和int  在java中表示为sql语句中的细微区别!! 下面的REGISEAT_NUM为int 类型       custid为varchar类型 String sql1= ...

  3. WebService 与 Socket 区别

    一.WebService 1.什么是WebService Web Service(WEB服务)能够快捷和方便地综合结合各种系统.商务和任何应用平台.利用最新的Web Service 标准能够使任何软件 ...

  4. CheeseZH: Octave basic commands

    1.Basic Operations 5+6 3-2 5*8 1/2 2^6 1 == 2 %false ans = 0 1 ~= 2 %true ans = 1 1 && 0 %AN ...

  5. PHP-7

    PHP 7+ 版本极大地改进了性能,在一些WordPress基准测试当中,性能可以达到PHP 5.6的3倍. PHP 7+ 版本新加特性如下表所示: 序号 内容 1 PHP 标量类型与返回值类型声明 ...

  6. Android:子线程向UI主线程发送消息

    在Android里,UI线程是不同意被堵塞的.因此我们要将耗时的工作放到子线程中去处理. 那么子线程耗时处理后要如何通知UI线程呢? 我们能够在UI主线程中创建一个handler对象,然后通过重写其h ...

  7. 如何开启firebug显示注释?

    如何开启firebug注释显示?

  8. java面试第六天

    集合:保存多个其他对象的对象,不能保存简单类型 List:有序(存放元素的顺序),可重复的集合 ArrayList:实质就是一个会自动增长的数组 查询效率比较高,增删的效率比较低,适用于查询比较频繁, ...

  9. ajax-原理分析

      createTime--2016年9月19日13:59:11Author:Marydon参考链接 http://blog.csdn.net/csh624366188/article/details ...

  10. svn,git,scp,rsync,rake,ssh,wget,axel,aria2,nohup,grep,tail,siege,mitmproxy,ulimit,netstat,lsof

    scp 把本地文件上传到server上 scp -P 1234 config/cert/dev/client.pem dev@xx.xxx.xxx:/srv/rorapps/fgcc/config/c ...