游戏小地图方案

作者: 慢慢来比较快_ | 来源:发表于2019-08-09 10:24 被阅读0次

Unity小地图的实现

游戏,特别是RPG类型,基本都需要添加小地图功能来辅助玩家。

实现小地图需解决的问题:

  1. 小地图(贴图)从哪里来?
  2. 如何把场景中单位的坐标转换到小地图上
  3. 小地图视角怎么跟玩家视角一致

思路:

  1. 让美术垂直90°方向以正交视角俯视整个场景,然后截取场景输出成图片,截取的大小让美术设置,一般不超过2048*2048
  2. 保存截图时的矩阵
  3. 通过第2点保存的矩阵,在游戏运行时把场景中单位的世界坐标转换到小地图下的局部坐标

实现:

  1. 根据设置(这里写死了800*600),设定截图窗口的大小,同时Camera视角校准为玩家视角,我这里是直接使用Scene窗口
if (GUILayout.Button("调整截图窗口大小"))
{   
    var windowSize = Vector2(800,600);
    var lastSceneView = SceneView.lastActiveSceneView;

    // 场景的Main Camera
    var mainCamera = UnityEngine.Camera.main;
    // SmoothFollow是镜头跟踪的组件,这里知道SmoothFollow里有个rotationAngle字段是记录玩家视角即可
    XS.SmoothFollow smoothFollow = null;

    if (mainCamera)
    {
        smoothFollow = mainCamera.GetComponent<XS.SmoothFollow>();
    }
    if (smoothFollow == null)
    {
        return;
    }

    lastSceneView.position = new Rect(Vector3.zero, windowSize);

    Quaternion currentRotation = Quaternion.Euler(90, smoothFollow.rotationAngle, 0);
    lastSceneView.LookAt(Vector3.zero, currentRotation, lastSceneView.size, true);
    lastSceneView.isRotationLocked = true;
}
  1. 截图时,以Scene的大小为图片宽高,并预先算出此时的world2Screen矩阵和screen2World矩阵,用于后面的逻辑运算
if (GUILayout.Button("截取小地图"))
{
    var lastSceneView = SceneView.lastActiveSceneView;
    var sceneCamera = lastSceneView.camera;
    if (!sceneCamera.orthographic)
    {
        return;
    }

    var width = sceneCamera.pixelWidth;
    var height = sceneCamera.pixelHeight;
    var cameraPos = sceneCamera.transform.position;
    var camreaSize = sceneCamera.orthographicSize;
    
    Matrix4x4 world2Screen = sceneCamera.projectionMatrix * sceneCamera.worldToCameraMatrix;
    Matrix4x4 screen2World = world2Screen.inverse;

    RenderTexture sceneCameraRT = RenderTexture.GetTemporary((int)width, (int)height, 32, RenderTextureFormat.ARGBFloat);
    sceneCamera.targetTexture = sceneCameraRT;
    sceneCamera.Render();
    sceneCamera.targetTexture = null;

    // targetData是用于保存数据组件,挂载在场景的一个空Object上
    string sceneName = targetData.gameObject.scene.name;

    var path = EditorUtility.SaveFilePanel("Save SmallMap", "", sceneName, "png");
    if (!string.IsNullOrEmpty(path))
    {
        if (SaveRenderTextureToPNG(sceneCameraRT, path))
        {
            targetData.smallMapCameraCenter = cameraPos;
            targetData.smallMapCameraSize = camreaSize;

            targetData.smallMapWorldToScreenMatrix = world2Screen;
            targetData.smallMapScreenToWorldMatrix = screen2World;
            targetData.smallMapCutSize = new Vector2(width, height);

            UnityEditor.EditorUtility.SetDirty(targetData);
            UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(targetData.gameObject.scene);
        }
        else
        {
            Debug.LogError("Save RenderTexture to file error");
        }
    }
    RenderTexture.ReleaseTemporary(sceneCameraRT);
}
  1. 根据第2点保存的两个矩阵和图片大小,通过以下接口(Lua实现)即可完成坐标转换,里面涉及的数学知识请自行查阅。
-- 世界坐标转图片的局部坐标
function manualWorldToScreenPoint(world2Screen, x, z, pixelWidth, pixelHeight)
    local temp = world2Screen * UnityEngine.Vector4(x, 10, z, 1.0)
    if temp.w == 0 then
        return UnityEngine.Vector3.zero
    else
        temp.x = (temp.x/temp.w + 1)*0.5 * pixelWidth
        temp.y = (temp.y/temp.w + 1)*0.5 * pixelHeight
        return temp.x, temp.y
    end
end

-- 图片的局部坐标转世界坐标
function manualScreenPointToWorld(screen2World, x, y, pixelWidth, pixelHeight)
    local in_x = 2.0 * (x / pixelWidth) - 1.0
    local in_y = 2.0 * (y / pixelHeight) - 1.0
    local in_z = 10
    local in_w = 1.0
    local pos = screen2World * UnityEngine.Vector4(in_x,in_y,in_z,in_w)
    if pos.w == 0 then
        return UnityEngine.Vector3.zero
    else
        pos.w = 1.0 / pos.w
        pos.x = pos.x*pos.w
        pos.y = pos.y*pos.w
        pos.z = pos.z*pos.w
        return pos.x, pos.z
    end
end

额外:

小地图一般需要添加小地图寻路功能,这里我使用的方案是给小地图添加PointerClick事件,根据点击的坐标点转换成世界坐标点,然后从在一点(当然是上移到场景上空)通过射线往下检测,得到与路面(路面需要设置特定Layer)的交点,这个交点就是目标点,接下来就是UnityEngine.AI.NavMeshAgent的事情了。

相关文章

  • 游戏小地图方案

    Unity小地图的实现 游戏,特别是RPG类型,基本都需要添加小地图功能来辅助玩家。 实现小地图需解决的问题: 小...

  • unity对接安卓高德地图定位及围栏功能的实现(1)

    1、首先去高德地图开放平台(游戏行业解决方案 | 高德地图API)。 注册自己的账号,并且创建自己的项目,按照高德...

  • 脑洞5

    地图 地图结构 l大地图(一级地图):游戏中展示和进入所有关卡的入口,点击图标即可进入二级地图。 l小地图(二级地...

  • 第十章:游戏地图(一)

    什么是地图?为什么使用地图? 1.游戏地图:为了节省游戏大小,而使用的可以重复利用的地图图片,例如,游戏世界中的地...

  • 有悔

    “小奈。”陈奈打游戏的时候,耳边传来哥哥的低低的唤声。 陈奈眼睛观察着小地图,地图上红色点和蓝色点在迅速靠近——要...

  • 微信小程序图片流&本地图片转base64处理方案

    微信小程序图片流&本地图片转base64处理方案 图片流转base64展示 wxml展示图片 本地图片转base6...

  • Android高德(百度)地图mapview圆角实现

    本文同时适用于高德地图和百度地图。 本人总结下来有三种实现方案,但每种方案都有利弊: 方案一:使用CardView...

  • 景观建筑项目游览地图如何画?

    Ⅰ 考虑项目地图基底参考 方案一,寻找精准的地图原件(政府公示类文件,共享的矢量地图,行政地图,场所精准CAD) ...

  • .Net基础08

    先上个 方法的小练习 飞行棋游戏 先看看大致的界面 整个游戏可以分为以下几个部分:1、画游戏头2、初始化地图(加载...

  • 关于口袋妖怪go

    兄弟们,这游戏是基于google地图,不开google地图就显示无gps信号,也就是说这游戏用的google地图资...

网友评论

    本文标题:游戏小地图方案

    本文链接:https://www.haomeiwen.com/subject/rkhfjctx.html