• Unity相机拖拽


    最近工作遇到个需求,主要是针对2D地图的相机拖拽,具体的实现也花了点时间去思考,整体的实现算法效率还算可以。

    1.相关需求

    • 对于地图相机,需要在地图上实现可上下左右的滑动,并且对于不同的分辨率,不能使相机的滑动穿帮

    2.实现

    • 点乘和叉乘

      • 点乘
        点乘的几何意义是可以用来表征或计算两个向量之间的夹角,以及在b向量在a向量方向上的投影。


        当a·b > 0时,向量a与向量b方向基本相同,夹角在0°到90°之间
        当a·b = 0时,向量a与向量b为垂直
        当a·b < 0时,向量a与向量b方向基本相反,夹角在90°到180°之间

      • 叉乘
        叉乘的几何意义可以用来计算两个向量围成的平面的法线,这个在3维空间的计算中是非常实用的。

        由法向量我们可以延伸,去计算平面的平行或者相交等等。(补充一点,一个点和一个法向量就可以确定一个平面)

    • 思路

      • 确定相机移动空间
        首先确定屏幕的四个点,然后根据相机和屏幕的四个点来确定出相机的射线。

        然后确定游戏中可视的地图的最大平面,由最大平面的四个点,和上一步得出来的四条射线方向,我们可以一一确定出新的射线(由地图可视平面点出发,射向移动到边界的相机)。
        根据计算出来的四条射线,以及相机的视口深度,计算出相机的移动空间,如下图(远平面可能为一个点,也有可能是一条直线)

      • 确定相机待滑动的平面
        根据近平面(地图背景面)计算出对应的法线(我们知道相机滑动的平面必然跟近平面平行)。这里已知条件:平面A与平面B平行,平面A法线,过平面B的点C,由此可以计算出平面B(相机待滑动平面)。为什么叫待滑动平面呢?这里我们要考虑到相机是否超出了相机的移动空间。这里我们通过计算待滑动平面与相机移动空间的交点,围成一个相机待滑动的平面区域(区分:平面是无限空间,平面区域是有限制范围)。

      • 确定滑动平面区域
        如图绿色为第二步相机待滑动平面是我们需要确定的。由上面两个步骤的计算我们可以知道点A和点B坐标,由此可以知道AB直线方程,待滑动平面方程也已知,由此可以计算出直线与平面的交点P。具体方法可以戳着。然后判断交点P是否在线段AB上,这个判断是为了保证平面区域在合理的移动空间内。如何判断点是否在线段上,可以通过计算向量AP与AB的点乘来判断。如果有点没在线段上,则默认将滑动平面区域定义到远平面,回到步骤二重新计算。 如果都在线段上,那么根据四条直线,可以得到四个交点,这四个交点就可以围成相机的滑动平面区域。

      • 确定相机位置
        确定好平面区域后,我们需要确定相机是否在平面范围内。可以根据叉乘的方式确定,具体可以参考[这个博客]。
        a.如果在平面范围内。相机位置不用改变
        b.如果在平面范围外。平面区域有四条线段,根据点到四条线段的最短距离,取四个最短距离中的最短,然后把点移动到线段上。如何确定线段上的点到线段外的一个点的距离最短呢?如图可对应三种情况,根据这个方法可以计算出最近的点,然后在相机移动到这个点上。

      • 滑动起来
        我们在Mono脚本的Update上每一帧通过步骤(确定相机位置)来计算相机位置,这样就能保证我们的相机看到的不会出现穿帮的情况。

      • 效果图

  • 相关阅读:
    Servant:基于Web的IIS管理工具
    mono-3.4.0 源码安装时出现的问题 [do-install] Error 2 [install-pcl-targets] Error 1 解决方法
    使用 OWIN Self-Host ASP.NET Web API 2
    Xamarin和微软发起.NET基金会
    SQLite vs MySQL vs PostgreSQL:关系型数据库比较
    Mono 3.2.7发布,JIT和GC进一步改进
    如何使用Microsoft技术栈
    c#开源消息队列中间件EQueue 教程
    通过一组RESTful API暴露CQRS系统功能
    NEsper Nuget包
  • 原文地址:https://www.cnblogs.com/fzuljz/p/13179652.html
Copyright © 2020-2023  润新知