欢迎来到淼淼之森的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

unity滑动地图上气泡随之移动旋转

  |   0 评论   |   0 浏览

前言

最近在做世界地图,需要实现一个气泡提示的功能。大概描述:地图上可上下左右滑动,地图上有若干个资源点,玩家最多可开采1个资源点
当玩家有正在开采的资源点时,需要在资源点上方显示带有方向的气泡提示,当资源点滑动到
显示屏幕外时,气泡需要在可视屏幕边缘,且指向资源点。通俗来讲:气泡方向需要随着地图的滑动,一直指向目标点。

预想效果

UI搭建

1.创建可滑动的地图,如下:
在这里插入图片描述

2.在地图面板创建tips,作为气泡的父物体,如下:
在这里插入图片描述
3.制作器气泡预制:bg为带箭头指向的气泡背景,icon为气泡内容,可根据需要增加或减少,如图:
在这里插入图片描述

代码

1.获取组件及数据初始化

ui.maplist = base:findobj("SV/BG")
ui.scroll = base:findobj("SV")
utils.addchangeevent(ui.scroll, base.OnValueChanged)
ui.renderPrefab = utils.loadprefab("map", "MineMapItem")
ui.tipsParent = base:findobj("tips")
ui.tips = {}
--数据
list = {
    [1] = {position = {100,100},icon = "1"},
}--每个资源点的信息,包含位置,icon等

2.创建资源点并刷新资源点信息

function view.CreatItem()
    Util.DestroyAllChild(ui.maplist)
   
    item_render = {}
    for i,v in ipairs(list) do
        local render = {}
        render.go = Util.Instance(ui.renderPrefab)
        Util.SetParent(render.go, ui.maplist)
        local trans = render.go.transform
        render.icon = render.go:GetComponent("Image")--icon
        render.icon.sprite = utils.loadsprite("map", v.icon)
        render.go.transform.localPosition = v.pos
        
        item_render[i] = render
        utils.addclickevent(render.go, base.OpenItemDetail,i)
    end
end

3.代码加载气泡

function view.CreatBubble()
    if ui.tips.obj then
        return
    end
    ui.tips.obj = utils.loadinstobj("minemap","BubbleTips",ui.tipsParent)
    ui.tips.bg = utils.findobj(ui.tips.obj,"bg")
    ui.tips.icon = utils.findimage(ui.tips.obj,"icon")
end

4.设置气泡位置

function view.GetViewPort()
    local viewport = Vector4.New()
    local screensize = Layer.UIRoot:GetComponent("RectTransform").sizeDelta
    viewport.x = screensize.x / 2
    viewport.y = -viewport.x
    viewport.w = screensize.y / 2
    viewport.z = -viewport.w
    return viewport
end

function view.SetBubblePos()
    if not ui.tips.obj then
        return
    end
    local bol = true--是否占领
    if not bol then
        --没有占领
        Util.DestroyAllChild(ui.tipsParent)
        ui.tips = {}
        return
    end
    local idx = 1--占领的第几个资源点
    local contentPos = ui.maplist.transform.localPosition
    local itemPos =  list[idx].position
    local bubblePos = Vector3.New(contentPos.x+itemPos.x,contentPos.y+itemPos.y+90,0)
    local viewport = base.GetViewPort()
    local x = utils.clamp(bubblePos.x,viewport.y+50,viewport.x-50)
    local y = utils.clamp(bubblePos.y,viewport.z+150,viewport.w-100)
    bubblePos = Vector2.New(x,y)
    ui.tips.obj.transform.localPosition = bubblePos--设置气泡位置
end

5.设置气泡方向
首先需要正确计箭头的旋转角度,分为下main四种情况:
在这里插入图片描述

function view.SetBubbleDir()
    local idx = 1--占领的第几个资源点
    local pos = list[idx].position
    local contentPos = ui.maplist.transform.localPosition
    local itemPos = Vector3.New(pos.x + contentPos.x,pos.y + contentPos.y,0)
    bubblePos = ui.tips.obj.transform.localPosition

    local offY = math.floor(itemPos.y - bubblePos.y)
    local offX = math.floor(itemPos.x - bubblePos.x)
    if offX >= 0 then--方向向右/重叠
        if offX ==  0 then--x轴位置重叠
            if offY > 0 then--方向向上
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,180)
            elseif offY < 0 then--方向向下
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,0)
            else--// y轴位置重叠
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,180)
            end
        else--方向向右
            if offY > 0 then
            	--一些必要的数学知识
            	--Mathf.Atan()和Mathf.Atan2()都返回一个弧度值,表示反三角函数中的arctanx。
				--Mathf.Atan()返回的值的范围是[-π/2,π/2],
				--Mathf.Atan2()返回的值的范围是[-π,π]。
				--Mathf.Abs()返回绝对值。
				--Mathf.Atan2()求出弧度,乘180°/π得出角度。
                local z = math.atan2(math.abs(offY), math.abs(offX)) * 180 / math.pi
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,z+90)
            elseif offY < 0 then
                local z = math.atan2(math.abs(offY), math.abs(offX)) * 180 / math.pi
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,-z+90)
            else
                ui.tips.bg.transform.localEulerAngles = Vector3.New(0,0,180)
            end
        end
    else
        if offY > 0 then
            local z = math.atan2(math.abs(offY), math.abs(offX)) * 180/ math.pi
            ui.tips.bg.transform.localEulerAngles =  Vector3.New(0, 0, 270-z )
        elseif offY < 0 then
            local z = math.atan2(math.abs(offY), math.abs(offX)) * 180/ math.pi
            ui.tips.bg.transform.localEulerAngles =  Vector3.New(0, 0, 360+z-90)
        else
            ui.tips.bg.transform.localEulerAngles =  Vector3.New(0, 0, 90)
        end
    end
end

6.滑动过程中检测资源点是否出现在可视区域,从而调整气泡位置和方向

function view.OnValueChanged(value)
    local offX = ui.maplist.transform.localPosition.x
    base.SetBubblePos()
    base.SetBubbleDir()
end

运行效果

在这里插入图片描述


标题:unity滑动地图上气泡随之移动旋转
作者:shirlnGame
地址:https://www.mmzsblog.cn/articles/2023/04/11/1681177893012.html

如未加特殊说明,文章均为原创,转载必须注明出处。均采用CC BY-SA 4.0 协议

本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。若本站转载文章遗漏了原文链接,请及时告知,我们将做删除处理!文章观点不代表本网站立场,如需处理请联系首页客服。
• 网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
• 公众号转载请联系网站首页的微信号申请白名单!

个人微信公众号 ↓↓↓                 

微信搜一搜爱上游戏开发