Unity - 优化 Vector3.ProjectOnPlane


起因

之前偶然项目中看到过 API Vector3.ProjectOnPlane API 的使用

然在这篇文章也看到:Unity3d那些你不常用但确有其用的方法—Vector3.ProjectOnPlane,该作者使用的是将 UI 的面向和相机的 forward 正向的反向,有点 BB(Billboard)的功能想过

关于 BB,如果你感兴趣,可以参考我之前写的两篇:


好奇

然后我就好奇,这个函数的作用是啥,返回的 Vector3 是什么位置

所以我就使用 Gizmos 来绘制查看


绘制 Vector3.ProjectOnPlane 的参数,与返回结果

// jave.lin 2021/11/13
// 绘制 project on plane 的 gizmos

using UnityEngine;

public class DrawProjectOnPlaneGizmos : MonoBehaviour
{
    public Transform transForward;
    public Transform targetPos;

    private void OnDrawGizmos()
    {
        var forwardStart = transForward.position;
        var forwardEnd = forwardStart + transForward.forward;

        var srcCol = Gizmos.color;

        // forward
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(forwardStart, forwardEnd);

        // point to target pos
        var p2pStart = forwardStart;
        var p2pEnd = targetPos.position;
        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(p2pStart, p2pEnd);

        Vector3 projPos = Vector3.ProjectOnPlane(p2pEnd - p2pStart, transForward.forward);

        Gizmos.color = Color.green;
        Gizmos.DrawLine(forwardEnd, projPos);
        // jave.lin : 从 gizmos 视图上看:p2pEnd->projPos 平行与 transform.forward
        Gizmos.DrawLine(p2pEnd, projPos);

        Gizmos.color = srcCol;
    }
}


绘制结果

在这里插入图片描述


定位作用、优化

从上面的效果图可以看出来,Vector3.ProjectOnPlane(Vector3 vector, Vector3 planeNormal) 的作用就是 返回 vector 向量 相对 planeNormal 上的反向投影

先来看看 该 API Unity C# 的源码:

        //
        // 摘要:
        //     Projects a vector onto a plane defined by a normal orthogonal to the plane.
        //
        // 参数:
        //   planeNormal:
        //     The direction from the vector towards the plane.
        //
        //   vector:
        //     The location of the vector above the plane.
        //
        // 返回结果:
        //     The location of the vector on the plane.
        public static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
        {
            float num = Dot(planeNormal, planeNormal);
            if (num < Mathf.Epsilon)
            {
                return vector;
            }

            float num2 = Dot(vector, planeNormal);
            return new Vector3(vector.x - planeNormal.x * num2 / num, vector.y - planeNormal.y * num2 / num, vector.z - planeNormal.z * num2 / num);
        }

在这里插入图片描述

我能吐槽的是,这运算量,和这可读性,真的不敢恭维~

那么,其实可以优化(减少一个除法):

    private static Vector3 MyProjectOnPlane(Vector3 vector, Vector3 planeNormal)
    {
        var dot = Vector3.Dot(vector, planeNormal);
        return vector + -planeNormal * dot;
    }

完整脚本

// jave.lin 2021/11/13
// 绘制 project on plane 的 gizmos
// 顺便优化

using UnityEngine;

public class DrawProjectOnPlaneGizmos : MonoBehaviour
{
    public Transform transForward;
    public Transform targetPos;
    private float forwardAddLength = 10.0f;

    public bool usingMyFunc = false;

    private void OnDrawGizmos()
    {
        var forwardStart = transForward.position;
        var forwardEnd = forwardStart + transForward.forward;

        var srcCol = Gizmos.color;

        // forward
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(forwardStart, forwardEnd);
        Gizmos.DrawLine(forwardEnd, forwardEnd + transForward.forward * forwardAddLength);

        // point to target pos
        var p2pStart = forwardStart;
        var p2pEnd = targetPos.position;
        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(p2pStart, p2pEnd);

        Vector3 projPos;
        if (usingMyFunc)
        {
            projPos = MyProjectOnPlane(p2pEnd - p2pStart, transForward.forward);
        }
        else
        {
            projPos = Vector3.ProjectOnPlane(p2pEnd - p2pStart, transForward.forward);
        }
        Gizmos.color = Color.green;
        Gizmos.DrawLine(forwardEnd, projPos);
        // jave.lin : 从 gizmos 视图上看:p2pEnd->projPos 平行与 transform.forward
        Gizmos.color = Color.red;
        Gizmos.DrawLine(p2pEnd, projPos);

        Gizmos.color = srcCol;
    }

    private static Vector3 MyProjectOnPlane(Vector3 vector, Vector3 planeNormal)
    {
        var dot = Vector3.Dot(vector, planeNormal); // 得到投影长度
        return vector + -planeNormal * dot; // planeNormal 的反向 * 投影长度
    }
}


Project


References

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Unity-debugging-2018.x.zip是一个Unity版本相关的调试工具包,其中包含了诸如埋点工具和调试插件等功能丰富的工具。这些工具可以帮助Unity开发者在开发自己的游戏时快速、准确地定位和修复代码中的问题,提高了游戏的开发效率和质量。 这个工具包中最值得注意的一点是它的兼容性。它可以与Unity 2018中的许多不同版本一起使用,这意味着无论开发者使用哪个具体版本的Unity,都可以使用这个工具包进行调试。这为开发过程中遇到的问题提供了更为广泛和全面的支持,从而更好地满足了不同开发者的需求和要求。 另外,这个工具包还有一个很不错的特色,就是它的易用性。它提供了直观和易于操作的界面,即使是那些对调试工具很不熟悉的开发者也可以使用它。开发者可以通过它直接在Unity编辑器中观察代码执行过程中的变化,非常方便。 总的来说,Unity-debugging-2018.x.zip是一个非常实用和友好的Unity调试工具包,可以帮助Unity开发者更快速、高效地开发自己的游戏。 ### 回答2: unity-debugging-2018.x.zip是Unity引擎中用于调试的工具包。在程序开发的过程中,会出现各种各样的问题,而调试是解决这些问题的重要手段之一。Unity-debugging-2018.x.zip提供了一系列工具和功能,帮助程序员定位和解决问题。 Unity-debugging-2018.x.zip中包含了各种调试工具,例如调试器、内存分析器、性能分析器等等。这些工具可以帮助开发者监控程序运行的状态,包括内存使用、CPU使用、函数运行时间等等。通过这些信息,开发者可以找到程序中可能存在的性能问题,并对其进行优化。 同时,Unity-debugging-2018.x.zip还提供了调试器,帮助开发者调试程序。开发者可以在调试器中设置断点,一步一步地执行程序,查看变量和函数调用的情况。通过调试器,开发者可以快速定位程序中的错误,减少排错的时间。 总之,Unity-debugging-2018.x.zip是Unity开发中不可或缺的工具包。它可以帮助开发者定位和解决问题,提高程序的稳定性和性能,为游戏开发提供强有力的支持。 ### 回答3: unity-debugging-2018.x.zip是一个用于Unity引擎调试的文件。Unity是一款流行的游戏开发引擎,但在游戏开发过程中难免会遇到各种问题,例如程序崩溃、游戏运行异常等等。此时就需要进行调试。Unity-debugging-2018.x.zip文件中包含了一系列调试工具,可用于分析和诊断Unity游戏/应用程序的问题。其中包括了Unity自带的Profiler(性能分析器)、Debug.Log、断点调试、MonoDevelop等工具,这些工具可以帮助开发者查找问题所在,快速调试程序。一个好的调试工具不仅能帮助开发者快速找到问题,还能提高开发效率,使开发工作更加顺利。总之,Unity-debugging-2018.x.zip文件是Unity调试工具的集合,为开发者解决问题提供了极大的帮助,也是一个值得推广和使用的工具。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值