找回密码
 点一下
查看: 7655|回复: 25

自制界面的两种方法的简单解析

[复制链接]
发表于 2011-7-5 00:12:12 | 显示全部楼层 |阅读模式
说说自制UI吧,这里的自制范围只是在SC2游戏默认的界面元素的基础上进行修改,只稍微涉及到自建界面元素。

我们应该知道,自制UI在分类上可以说有两种方法,一个是将原有的界面元素移动位置来完成,另外一个是使用模板来创建新的界面元素。

这两种方法需要修改的地方并不一样,实际能达到的效果也有一定的区别。

首先,我们先介绍第一种方法,也就是说如何移动原有的界面元素。
    1,准备工作,请先使用MPQEditor将Base.SC2Data中UI\Layout\UI路径内所有的文档都解压出来,这些东西都是有助于大家研究的,有能力和时间的童鞋可以仔细看看它们。

    2,因为我们先要介绍第一种方法,所以大家先打开GameUI.SC2Layout这个文件。这个文件中描述的就是游戏界面内各元素的从属关系、创建顺序、引用模板以及相应的属性。

    3,接下来,我们就试着移动一下小地图的位置,将其从左下角移动到右上角吧。

    4,我们先新建一个文本文档,命名为DIY,将其后缀修改为SC2Layout,在文档中写下如下内容:
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">


    </Frame>
</Desc>
[/codes]
这是一个标准的xml文档,其根节点为Desc,我们在其中新建了一个子节点Frame,游戏中,每个窗体元素都对应了一个Frame节点。注意我填写的3个属性,因为我们只是需要移动原窗体元素的位置,因此请注意type和name需要与你要修改的窗体元素保持一致,另外一个file也请注意不要落下,表示其要覆盖哪个文档的数据。
    将其导入地图中,在数据编辑器中的“游戏UI数据”中“自定义布局文件”将它挂接上,以后DIY.SC2Layout有了变动,请重新将其导入地图,然后再查看效果。

    5,我们要修改小地图的位置,所以在GameUI.SC2Layout中搜索MinimapPanel,然后在DIY.SC2Layout将MinimapPanel的Frame节点复制过去(template属性不要复制了,之后我会讲到它是什么作用)。但是请注意,此时的name属性应当做一下修改,我们向上寻找MinimapPanel的父节点并记录下来,直至找到GameUI为止,如下填写:
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">
            <Frame type="MinimapPanel" name="UIContainer/ConsoleUIContainer/MinimapPanel">
                <BatchImages val="true"/>
                <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
                <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
                <Width val="391"/>
                <Height val="327"/>
            </Frame>
    </Frame>
</Desc>
[/codes]
意思很明显,name中填写的该窗体元素的路径。所以如下的两种写法和上面的写法是等同的,但是我推荐使用下面的第二种,方法以后大家增加修改的元素。
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
        <Frame type="MinimapPanel" name="GameUI/UIContainer/ConsoleUIContainer/MinimapPanel" file="GameUI">
            <BatchImages val="true"/>
            <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
            <Width val="391"/>
            <Height val="327"/>
        </Frame>
</Desc>
[/codes]
[codes=xml]
我推荐大家使用这种方法,不过各个方法相差不大,还是看个人的习惯了。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">
        <Frame type="Frame" name="UIContainer">
            <Frame type="Frame" name="ConsoleUIContainer">
                    <Frame type="MinimapPanel" name="MinimapPanel">
                        <BatchImages val="true"/>
                        <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
                        <Anchor side="Bottom" relative="$parent" pos="Max" offset="0"/>
                        <Width val="391"/>
                        <Height val="327"/>
                    </Frame>
            </Frame>
        </Frame>
        </Frame>
</Desc>
[/codes]

    6,因为我们只是覆盖原来的各项属性,并且只修改小地图的位置,因此我们仅保留下MinimapPanel中的Anchor两个子节点,其他的删除即可,是会自动继承的。
       然后我们来看下Anchor节点中各项属性的意义:
           side指该窗口元素被用来定位的边框,有Left、Right、Top、Bottom四个值。
           relative指该窗口元素将锚点设置于哪个窗口元素,"$parent"是指其父窗口,"$parent/$parent"是指其父窗口的父窗口,"$parent/xxx"是指其父窗口内名为xxx的窗体元素,具体请大家自己体会一下。
           pos有3个值,Min、Mid、Max。指定的是锚点在其所依存的窗口元素的位置。所以,有些元素之需要设置Top和Bottom、Left和Right中的任意两个就可以了。如果有的窗体元素将对应的两个边框位置都设定了,因为它们一般会在中间点显示自己。
           offset就是偏移。窗口左上角位置为(0,0),向右,向下均为正偏移,反向为负偏移。
       所以我们结合<Anchor side="Left" relative="$parent" pos="Min" offset="0"/>来看就可以清楚的知道,小地图的左边框会附着于ConsoleUIContainer的最左边,偏移为0。
       既然我们要把小地图修改到右上角,那么我们修改如下:
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">
        <Frame type="Frame" name="UIContainer">
            <Frame type="Frame" name="ConsoleUIContainer">
                    <Frame type="MinimapPanel" name="MinimapPanel">
                    <Anchor side="Left" relative="$parent" pos="Max" offset="-355"/>
                    <Anchor side="Bottom" relative="$parent" pos="Min" offset="330"/>
                    </Frame>
            </Frame>
        </Frame>
        </Frame>
</Desc>
[/codes]
    至于为什么是修改Left和Bottom,简单的来说是因为我们是覆盖原文件的。大家可以试试修改如下,看看效果。
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">
        <Frame type="Frame" name="UIContainer">
            <Frame type="Frame" name="ConsoleUIContainer">
                    <Frame type="MinimapPanel" name="MinimapPanel">
                    <Anchor side="Right" relative="$parent" pos="Max" offset="0"/>
                    <Anchor side="Top" relative="$parent" pos="Min" offset="0"/>
                    </Frame>
            </Frame>
        </Frame>
        </Frame>
</Desc>
[/codes]
    此时,小地图是在哪里呢?

    7,移动小地图之后,大致一看就会发现有两个副作用,一个是编队按钮的位置移动了,另外就是小地图旁边的3个按钮也跟着过来了。
       第一个问题,我们看一下ControlGroupPanel的属性就可以明白了,因为它的左边挂接着MinimapPanel,至于它要怎么处理,随大家的意了,我的地图中直接将它移动到地图界面外了。
[codes=xml]
<Frame type="ControlGroupPanel" name="ControlGroupPanel" template="ControlGroupPanel/ControlGroupPanelTemplate">
    <BatchImages val="true"/>
    <BatchText val="true"/>
    <Anchor side="Left" relative="$parent/MinimapPanel" pos="Max" offset="0"/>
    <Anchor side="Bottom" relative="$parent/InfoPanel" pos="Min" offset="-5"/>
    <Width val="766"/>
    <Height val="64"/>
</Frame>
[/codes]
       第二个问题就稍微复杂一些了,这三个按钮并不是在GameUI.SC2Layout中定义的,而是在UI\Layout\UI的文件夹内的MinimapPanel.SC2Layout文件内定义的。如何追踪到这个文件的呢?还记得大家刚才复制MinimapPanel这个节点时,它的template属性吧,是“MinimapPanel/MinimapPanelTemplate”,这个路径就是模板的路径,小地图就是以其为模板创建的,其内所有的元素属性与名称均与模板的定义相同。一般来说,“MinimapPanel”是指的文件名,“MinimapPanelTemplate”是该文件内的一个窗体定义的名字。
       我们打开MinimapPanel.SC2Layout文件,搜索MinimapPanelTemplate,就可以看到这个模板的结构了,如下:
[codes=xml]
    <Frame type="MinimapPanel" name="MinimapPanelTemplate">
        <Frame type="MinimapPanelTooltip" name="MinimapPanelTooltip" template="MinimapPanel/MinimapPanelTooltipTemplate"/>

        <Frame type="Minimap" name="Minimap">
            <Anchor side="Top" relative="$parent" pos="Min" offset="25"/>
            <Anchor side="Left" relative="$parent" pos="Min" offset="31"/>
            <Width val="291"/>
            <Height val="286"/>
            <TooltipFrame val="MinimapPanelTooltip"/>
        </Frame>

        <Frame type="Button" name="PingButton" template="MinimapPanel/MinimapButtonTemplate">
            <Anchor side="Right" relative="$parent" pos="Max" offset="-6"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="-226"/>
            <Frame type="Image" name="Icon">
                <Texture val="@UI/MinimapPing"/>
            </Frame>
        </Frame>

        <Frame type="Button" name="TerrainButton" template="MinimapPanel/MinimapButtonTemplate">
            <Anchor side="Right" relative="$parent" pos="Max" offset="-6"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="-176"/>
            <Frame type="Image" name="Icon">
                <Texture val="@UI/MinimapTerrain"/>
            </Frame>
        </Frame>

        <Frame type="Button" name="ColorButton" template="MinimapPanel/MinimapButtonTemplate">
            <Anchor side="Right" relative="$parent" pos="Max" offset="-6"/>
            <Anchor side="Bottom" relative="$parent" pos="Max" offset="-124"/>
            <Frame type="Image" name="Icon">
                <Texture val="@UI/MinimapColor"/>
            </Frame>
        </Frame>

        <Frame type="Image" name="ClearSelectionBackground">
            <Anchor side="Top" relative="$parent/ColorButton" pos="Max" offset="10"/>
            <Anchor side="Left" relative="$parent/ColorButton" pos="Mid" offset="0"/>
            <Anchor side="Right" relative="$parent/ColorButton" pos="Mid" offset="0"/>
            <Texture val="@UI/ClearSelectionBackground" layer="0"/>
        </Frame>

        <Frame type="Button" name="ClearSelectionButton" template="MinimapPanel/MinimapButtonTemplate">
            <Anchor side="Left" relative="$parent/ClearSelectionBackground" pos="Mid" offset="0"/>
            <Anchor side="Right" relative="$parent/ClearSelectionBackground" pos="Mid" offset="0"/>
            <Anchor side="Top" relative="$parent/ClearSelectionBackground" pos="Mid" offset="0"/>
            <Anchor side="Bottom" relative="$parent/ClearSelectionBackground" pos="Mid" offset="0"/>
            <Frame type="Image" name="Icon">
                <Texture val="@UI/ClearSelection"/>
            </Frame>
        </Frame>
    </Frame>
[/codes]
       这三个多余的按钮就是PingButton、TerrainButton和ColorButton,它们是MinimapPanel的子节点,要修改它们的位置,我们可以直接在DIY.SC2Layout中作出修改。比如我想直接将它们移到屏幕外,就做如下修改:
[codes=xml]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Desc>
    <Frame type="GameUI" name="GameUI" file="GameUI">
        <Frame type="Frame" name="UIContainer">
            <Frame type="Frame" name="ConsoleUIContainer">
                <Frame type="MinimapPanel" name="MinimapPanel">
                    <Anchor side="Left" relative="$parent" pos="Max" offset="-355"/>
                    <Anchor side="Bottom" relative="$parent" pos="Min" offset="330"/>
                    <Frame type="Button" name="PingButton">
                        <Anchor side="Right" relative="$parent/$parent" pos="Max" offset="50"/>
                    </Frame>
                    <Frame type="Button" name="TerrainButton">
                        <Anchor side="Right" relative="$parent/$parent" pos="Max" offset="50"/>
                    </Frame>
                    <Frame type="Button" name="ColorButton">
                        <Anchor side="Right" relative="$parent/$parent" pos="Max" offset="50"/>
                    </Frame>
                </Frame>
            </Frame>
        </Frame>
        </Frame>
</Desc>
[/codes]
       大家可以结合上面的要点,来理解这样修改所能达到的效果。


使用覆盖的方法来修改UI到此为止,请大家多多练习,掌握这个真是小意思了。
但是还有一些窗体元素的设置时需要注意的,比如英雄的头像按钮,它们的创建顺序是逆序的,所以摆放它们的位置的时候请务必记住这一点,否则可能会出现令人抓狂的问题。

评分

参与人数 1威望 +4 收起 理由
oneonestar + 4 不错的教程

查看全部评分

 楼主| 发表于 2011-7-5 00:12:26 | 显示全部楼层
使用覆盖的方法重置UI有什么缺陷呢?很明显就是,界面即使重置,它的位置在游戏内依然不能动态修改,所以如果我们想要将窗体元素随心所欲的移动和隐藏时,就需要使用第二种方法了。即使用模板来创建对话框项。

具体的方法,可以看头目的这个演示,http://bbs.islga.org/read-htm-tid-53049-page-1-fpage-1.html

各个模板的路径是什么呢?大家可以在GameUI.SC2Layout中查看各窗体元素的template属性,下面我以创建一个CommandPanel(技能按钮栏)为例。它的模板路径为“CommandPanel/CommandPanelTemplate”。

不要偷懒,还不会创建对话框项模板的童鞋,务必按照链接中头目的演示自己制作一下,在屏幕的中央显示一个CommandPanel界面,不然看下去就没有意义了。



好的,如果成功了的话,咱们就可以继续了,我就偷懒不制作兼截图啦(拍飞...其实是LZ想偷懒)。将CommandPanel独立创建出来以后,大家可能会觉得如果把他们摆成一条直线会比较好看一点,那么如果制作呢?

    1,在UI\\Layout\\UI文件夹中复制一份CommandPanel.SC2Layout出来,我们要修改它,完成之后我们要将其导入到地图中去,路径即为UI\\Layout\\UI。

    2,打开CommandPanel.SC2Layout文件,我们看到的就是CommandPanel的模板了,里面的CommandButtonXX按钮数一数是不是正好是15个呢?没错了,它们就是技能栏的按钮,如果要将它们排列成一个直线应该如何操作呢?
       按照上一贴的方法就可以了,完全一样的。

    3,修改完之后,记得导入CommandPanel.SC2Layout文件,并且将路径设置正确,运行地图看一看是否修改成功了,因为这修改方法依然是上一贴的内容,所以我就不在此方法文档和截图了,这个需要大家自己来练习一下了。


我们来总结一下,这个方法需要用到触发器,使用正常的流程来创建自定义窗体元素,然后在某个Dialog或者Panel内使用模板创建一个窗体元素。需要用到的是以下两个函数:
native int      DialogControlCreateFromTemplate (int dialog, int type, string inTemplate);
native int      DialogControlCreateInPanelFromTemplate (int panel, int type, string inTemplate);


好了,如果对上面的流程十分熟悉了的话,那么我想问大家一个问题,我们刚才创建的以“CommandPanel/CommandPanelTemplate”为模板的窗体元素,其父窗口是哪个?

这个答案大家不需要要在GameUI.SC2Layout中寻找,而是要在触发器中寻找,意思就是如果使用上面的两个api创建了该模板元素的话,其父窗口就是对应的Dialog或Panel。如果你想更精确的知道你所创建的窗体元素的性质时,请务必记得这一点。
回复

使用道具 举报

 楼主| 发表于 2011-7-5 00:15:29 | 显示全部楼层
那么,第二种方法有何缺点呢?就拿刚才创建的CommandPanel为例,你用鼠标与它相互作用时,它一切正常,但是它是不会响应热键的,如果你隐藏了游戏自带的CommandPanel时,你按热键它不会有任何反应;而如果没有隐藏的话,它可以在你单位的技能按钮热键按下时,会与自带的CommandPanel一起改变图标,但是如果你打开建造按钮(就是切换CommandPanel的按钮栏),它不会有任何变化。

知道有上面的一些小瑕疵,我们尽量避免它就好了。

我现在想制作一个可以随时隐藏、改变位置的CommandPanel,但是同时它又是可以响应热键的。那么我们应该如何制作呢?

其实很简单,就是结合上面的两种方法,我们使用第二个方法创建一个新的窗体元素CommandPanel,这样它就可以随时移动了;但是不隐藏游戏自带的CommandPanel,而是使用第一种方法将其移动到界面的外边,这样它就可以响应热键了。

就是这么简单,我附上演示,希望能对大家有所帮助。

Screenshot2011-07-04 20_21_03.jpg Screenshot2011-07-04 20_21_10.jpg Screenshot2011-07-04 20_21_15.jpg Screenshot2011-07-04 20_21_38.jpg

jiemianshezhi.SC2Map

19 KB, 下载次数: 186

回复

使用道具 举报

发表于 2011-7-5 00:30:05 | 显示全部楼层
非常好~~于是我需要写的教程又少了一个呢~~星星来加分吧~~

继续填坑GAx3唉~~

PTR1.4到底啥时候出啊~~
回复

使用道具 举报

 楼主| 发表于 2011-7-5 00:35:37 | 显示全部楼层
可能会有些错字,这个请大家原谅吧,我这里网速实在太渣,修改起来十分费力。
而且打错字的原因是搜狗的智能选词,太渣了。

嗯,严肃点说,帖子内有其他的表述或者实质性的错误的话,还请大家赐教。
回复

使用道具 举报

发表于 2011-7-5 12:07:32 | 显示全部楼层
拜上~这帖子来得太及时了~
回复

使用道具 举报

发表于 2011-7-5 21:30:32 | 显示全部楼层
强大,正是我想要的!
回复

使用道具 举报

发表于 2011-7-6 02:36:54 | 显示全部楼层
我只想知道技能上的快捷键是怎么显示的,望赐教
回复

使用道具 举报

发表于 2011-7-6 02:48:36 | 显示全部楼层
游戏设置里自己选择打开就有显示了。
回复

使用道具 举报

发表于 2011-7-6 12:59:57 | 显示全部楼层
学习学习,谢谢分享~!
回复

使用道具 举报

发表于 2011-7-11 10:08:44 | 显示全部楼层
解救我与水深火热之中啊
回复

使用道具 举报

发表于 2013-1-10 22:14:00 | 显示全部楼层
数据编辑器中的“游戏UI数据”中“自定义布局文件”将它挂接上,以后DIY.SC2Layout 怎么找这个文件?
回复

使用道具 举报

发表于 2013-1-10 22:40:26 | 显示全部楼层
回复楼上:由于新的UI编辑页面的出现,本教程已经过时。
回复

使用道具 举报

发表于 2013-1-10 22:43:33 | 显示全部楼层
难怪我怎么导入也导不进去那个文件。 那我该怎么做啊? 谢谢。
回复

使用道具 举报

 楼主| 发表于 2013-1-10 22:44:44 | 显示全部楼层
12楼你挖我坟了。

现在SC2都1.5了,可以直接使用UI编辑器了。规则与上面描述的覆盖方法一样,不过不需要在“游戏UI数据”中挂接了。
回复

使用道具 举报

发表于 2013-1-10 22:46:42 | 显示全部楼层
200545955330.gif 挖坟了啊,那就顺便上香好了。。
回复

使用道具 举报

发表于 2013-1-10 22:57:36 | 显示全部楼层
UI 编辑器是什么? 哪里可以下?谢谢
回复

使用道具 举报

 楼主| 发表于 2013-1-10 23:00:51 | 显示全部楼层
本帖最后由 cccty1l 于 2013-1-10 23:03 编辑

在 模块 - UI 里面,热键是Shift+F6.

然后右键,添加布局,再把DIY.SC2Layout里面的内容复制进去,然后就可以测试了。

//修改分隔线

我记得没错的话,这个布局文件在SC2升级过一次后,会报错了,因为指令按钮的Tips面板挂接错误了,回头我有时间,再发一份1.5的吧。

点评

能拜托大人写个现在适用的UI教程不?  详情 回复 发表于 2013-1-12 14:48
回复

使用道具 举报

发表于 2013-1-10 23:17:09 | 显示全部楼层
本帖最后由 starusermap 于 2013-1-11 21:04 编辑

Xiexie
回复

使用道具 举报

发表于 2013-1-11 21:23:00 | 显示全部楼层
所有说花音说的是UI编辑页面不是UI编辑器啊……
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-23 20:20 , Processed in 0.423191 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表