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

  • 相关阅读:
    差分放大电路分析及运放单双电源供电对输出的影响
    反相加法器与同相加法器对比分析
    高频变压器绕组绕制方式与漏感大小分析与计算
    高频变压器绕组绕制方式与分布电容大小分析与计算
    反激电路开关管电流尖峰分析
    涡流效应产生原因及分析
    磁路-电路通用变换方法及电路对偶变换
    反激电路RCD缓冲电路参数设计分析
    STM32 CUBE
    TEB 系统综合误差
  • 原文地址:https://www.cnblogs.com/wantnon/p/4380554.html
Copyright © 2011-2022 走看看