zoukankan      html  css  js  c++  java
  • unity, 让主角头顶朝向等于地面法线(character align to surface normal)

    计算过程如下:

    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));

  • 相关阅读:
    代理信息[Python] 实现网络爬虫
    线程希望IOS开发(67)之简单的线程方法
    生产环境紧急修改表存储引擎:MyISAM 为 InnoDB步骤
    Mysql优化SQL语句的一般步骤
    window 2003 实现多用户远程登录
    XSS的知识普及和预防办法
    免积分下载CSDN软件和新浪资料
    mysql开启慢查询方法
    在线JS/CSS/HTML压缩
    我们项目中需要准备的技术
  • 原文地址:https://www.cnblogs.com/wantnon/p/4380554.html
Copyright © 2011-2022 走看看