计算过程如下:

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. VS2008中生成DLL项目

    创建项目 新建项目-> 选择Win32项目 输入项目名称,点击确定.在程序向导中选择下一步 选择DLL. 由于我想创建的是相对独立的DLL,所以不选择ATL和MFC. 点击完成.   Main文 ...

  2. Python访问MongoDB数据库

    #encoding: utf-8 __author__ = 'Administrator' #import pymongo from pymongo import MongoClient,GEO2D ...

  3. leetCode 41.First Missing Positive (第一个丢失的正数) 解题思路和方法

    First Missing Positive  Given an unsorted integer array, find the first missing positive integer. Fo ...

  4. 如何用代码组织多个Storyboard(故事板)

    1. 新建一个Storyboard取名为OtherStoryboard.storyboard 2. 使用下面代码加载 UIStoryboard *newStoryboard = [UIStoryboa ...

  5. ASP.NET伪静态

    http://www.duote.com/tech/5/14543.html 三.伪静态的坏处 当然犹如一篇文章的作者所说的:"如果流量稍大一些使用伪静态就出现CPU使用超负荷,我的同时在线 ...

  6. JavaScript简述一

    一.什么时JavaScript JavaScript是一种具有面向对象能力的,解释型的设计语言,更具体一点,它是基于圣明和事件驱动并具有相对安全必的客户端脚本语言,因为它不需要在一个语言环境下运行,只 ...

  7. Node FS 读取文件中文乱码解决

    1:首先保证源文件编码方式为UTF-8 2:读取代码,设置编码方式rs.setEncoding('utf8') var fs = require('fs'); var rs = fs.createRe ...

  8. 基于apktool项目的android批量打包工具,多平台支持

    好久木有写博客了,今天有点兴致就写一下,献上一个没怎么用的批量打包工具,python实现的,虽然说现在android的批量打包有一个很好的工具可以使用gradle,这个灰常牛叉的工具和android ...

  9. java 类名.class、object.getClass()和Class.forName()的区别 精析

        1.介绍 getClass()介绍 java是面向对象语言,即万物皆对象,所有的对象都直接或间接继承自Object类: Object类中有getClass()方法,通过这个方法就可以获得一个实 ...

  10. 〖Ruby〗Ruby运算符/优先级

    优先级 能否重写 运行符 描述 最高 Y [] []= 数组下标 数组元素赋值 Y ** 冥乘 Y ! ~ + - 非 位非 一元加 负号 Y * / % 乘 除 模 Y + - 加 减 Y > ...