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

  • 相关阅读:
    datatables 自定义排序
    nginx 高并发配置参数
    查看域名https证书到期时间
    Python七大原则,24种设计模式
    scrapy RuntimeError: maximum recursion depth exceeded while calling a Python object 超出python最大递归数异常
    scrapy 用pycharm调试
    修改Mysql 字符集,支持Emoji表情
    redis资料
    mysql 开启日志与性能调优
    python 版本号比较 重载运算符
  • 原文地址:https://www.cnblogs.com/wantnon/p/4380554.html
Copyright © 2020-2023  润新知