UDN
Search public documentation:
CLIKChatBoxCH
English Translation
日本語訳
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
日本語訳
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
怎样创建一个简易的聊天框
使用2011年9月的UDK进行了最后测试
概述
这一中级到高级水平的教程会包括一些在游戏运行中所需要的初级多玩家多行聊天窗口步骤,这些步骤会捕捉所有的键盘输入,并在聊天窗口处于聚焦状态下禁止游戏捕捉键盘进入。 它会提供两种方法来访问聊天输入——鼠标点击和键盘指令。 这个教程假设您已经十分熟悉对Scaleform和CLIK控件的设置和使用,并且您在一个基于HUD的Scaleform中已有一个可正常工作的鼠标指针。 该教程同样要求熟悉 replication(复制) 。 重要: 该教程同样要求熟悉 toggle-able mouse tutorial(可切换鼠标教程) 。
Flash设置
文本输入框
- 将一个CLIK TexInput(CLIK文本输入)控件放到您的HUD上。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\TextInput.FLA )
- 赋予它一个chatInput的实例名。
- 打开Component Inspector(组件查看器)(CS4),或者展开Component Parameter(组件参数)(CS5)并启用"actAsButton"。
Send(发送)按钮
- 下一步将一个CLIK Button(CLIK按钮)控件放到TextInput组件的旁边。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\Button.FLA)
- 赋予它一个实例名chatSendBtn。
- 打开Component Inspector(组件查看器)(CS4),或者展开Component Parameter(组件参数)(CS5)并在按钮的标签域里键入"Send"。
多行可滚动聊天日志
- 将一个CLIK Text Area(CLIK文本区域)控件放到TexInput控件上方。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\TextArea.FLA)
- 赋予它一个chatLog的实例名。
- 打开Component Inspector(组件查看器)(CS4),或者展开Component Parameter(组件参数)(CS5)并禁用"editable"。
- 将一个CLIKScroll Bar(CLIK滚动栏)控件放到TextInput控件的右边。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\Scrollbar.FLA )
- 赋予它一个chatScrollBar的实例名。
- 选中该Text Area(文本区)并打开Component Inspector(组件查看器)(CS4)或展开Component Parameter(组件参数)(CS5)并将Text Area(文本区)的scrollBar(滚动栏)设置为chatScrollBar。
聊天框形状
- 在页面中对齐这四个控件,使它们紧挨着对方,构成一个方框。 您可以根据需要延展(不均匀缩放)这些控件。
- 选中在页面中所有的四个控件,右击并选择Convert to Symbol(转换成标记)。
- 将名称设置为chatForm
- 将Type(种类)设置为Movie Clip(视频短片)
- 启用Export for ActionScript(动作脚本输出)和Export in frame 1(在第一帧输出)。
- 将Identifier(标识符)设置为chatForm
- 将Class(类)设置为gfx.core.UIComponent
- 点击OK。
- 从页面中删除chatForm视频短片,将它保留在库中。
聊天窗口
- 复制位于\Development\Flash\CLIK\demos\com\Scaleform\Window .as 的文件到\Development\Flash\CLIK\gfx\controls\Window.as
- 将这个类文件打开,将第七行(类的声明行)修改成如下:
class gfx.controls.Window extends UIComponent {
- 打开文件\Development\Flash\CLIK\demos\WindowDemo.FLA.
- 进入这个文件的库面板。
- 选中WindowSkinned标记。
- 右击WindowSkinned标记并选择Copy(复制)。
- 回到您的HUD.FLA文件。
- 在页面上右击并选择Paste(粘帖)在合适的地方粘帖Window标记。
- 将窗口对齐到页面左下角附近。
- 赋予它一个实例名chatWindow。
- 在页面上选中chatWindow,打开Component Inspector(组件查看器)(CS4)或展开Component Parameters(组件参数)(CS5)。
- 将formSource设置为chatForm。
- 请确保formType设置成标记。
- 将maxHeight和maxWidget设置成400。
- 将minHeight和minWidget设置成200。
- 将offsetBottom设置成24、offsetLeft设置成20、offsetRight设置成20、offsetTop设置成46,或者您可以在测试后根据情况自行设置。
- 将标题设置成Chat。
- 在库面板中右击WindowSkinned标记并选中Properties(属性)。
- 将Class(类)域设置成gfx.controls.Window并按OK。
- 再次右击该标记并选择Component Definition(组件定义)。
- 将Class(类)域设置成gfx.controls.Window并按OK。
- 保存、发布并将您的SWF文件跟以往一样导入UDK。 您在页面上应该可以有一个可拖曳的聊天窗口了,它包含了聊天输入、聊天区域、发送按钮和滚动栏。
HUD类的虚幻脚本
您的HUD Class(HUD类)可以继承GFxMoviePlayer。 将这些新的变量添加到您的虚幻脚本HUD类文件:
var WorldInfo ThisWorld; var SFPlayerController PC; var array<string> chatMessages; // this will hold all the chat messages var bool bChatting; // These are our CLIK widgets for the chat system var GFxClikWidget MyChatInput, MyChatSendButton, MyChatLog;
function Init(optional LocalPlayer player) { super.Init(player); ThisWorld = GetPC().WorldInfo; Start(); Advance(0); // ... other initialization code here ... // Register the HUD with the PlayerController PC = SFPlayerController(GetPC()); PC.registerHUD(self); }
/** Toggles mouse cursor on/off */ function ToggleCursor(bool showCursor, float mx, float my) { if (showCursor) { MouseContainer = CreateMouseCursor(); MouseCursor = MouseContainer.GetObject("my_cursor"); MouseCursor.SetPosition(mx,my); MouseContainer.SetBool("topmostLevel", true); } else { MouseContainer.Invoke("removeMovieClip", args); MouseContainer = none; } if (!bChatting) { bCaptureInput = showCursor; bIgnoreMouseInput = !showCursor; } else { bCaptureInput = true; bIgnoreMouseInput = false; } }
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget) { switch(WidgetName) { case ('chatInput'): MyChatInput = GFxClikWidget(Widget); MyChatInput.AddEventListener('CLIK_press', OnChat); break; case ('chatSendBtn'): MyChatSendButton = GFxClikWidget(Widget); MyWidget.AddEventListener('CLIK_press', OnClickHandler); break; case ('chatLog'): MyChatLog = GFxClikWidget(Widget); break; default: break; } return true; }
// Event Handler - handles when the player clicks on the chat box text input field. function OnChat(GFxClikWidget.EventData ev) { bChatting = true; }
function OnChatSend(GFxClikWidget.EventData ev) { local string Msg; Msg = MyChatInput.GetString("text"); if (Msg != "") { PC.SendTextToServer(PC, Msg); } MyChatInput.SetString("text", ""); self.bCaptureInput = false; bChatting = false; }
function UpdateChatLog(string message) { local string displayMsg; local int i; chatMessages.AddItem(message); displayMsg = ""; for (i = 0; i < chatMessages.length; i++) { displayMsg @= chatMessages[i]; displayMsg @= "\n"; } MyChatLog.SetString("text", displayMsg); MyChatLog.SetFloat("position", MyChatLog.GetFloat("maxscroll")); }
defaultproperties { WidgetBindings.Add((WidgetName="chatInput",WidgetClass=class'GFxClikWidget')) WidgetBindings.Add((WidgetName="chatSendBtn",WidgetClass=class'GFxClikWidget')) WidgetBindings.Add((WidgetName="chatLog",WidgetClass=class'GFxClikWidget')) bIgnoreMouseInput = true; bCaptureInput = false; }
GameInfo类的设置
打开您的GameInfo类。 如果它不扩展UTGame或UTGame的子项,比如UTDeathmatch,就只将这些变量添加到您的game info类。 如果已经声明了这些变量,您将会收到编译警告。 如果收到了警告,请将它们从您的game info类中移除。
var class<BroadcastHandler> BroadcastHandlerClass; var BroadcastHandler BroadcastHandler; // handles message (text and localized) broadcasts
event InitGame( string Options, out string ErrorMessage ) { Super.InitGame(Options, ErrorMessage); BroadcastHandler = spawn(BroadcastHandlerClass); }
event Broadcast(Actor Sender, coerce string Msg, optional name Type) { local SFPlayerController PC; local PlayerReplicationInfo PRI; // This code gets the PlayerReplicationInfo of the sender. 我们会使用它得到带有PRI.PlayerName的发送者的名字。 if (Pawn(Sender) != None) { PRI = Pawn(Sender).PlayerReplicationInfo; } else if (Controller(Sender) != None) { PRI = Controller(Sender).PlayerReplicationInfo; } // This line executes a "Say" BroadcastHandler.Broadcast(Sender, Msg, Type); // This is where we broadcast the received message to all players (PlayerControllers) if (WorldInfo != None) { ForEach WorldInfo.AllControllers(class'SFPlayerController',PC) { `Log(Self$":: Sending "$PC$" a broadcast message from "$PRI.PlayerName$" which is '"$Msg$"'."); PC.ReceiveBroadcast(PRI.PlayerName, Msg); } } }
defaultproperties { PlayerControllerClass=class'SFPlayerController' BroadcastHandlerClass=class'Engine.BroadcastHandler' HUDType=class'SFTutorial.SFHudWrapper' bUseClassicHUD=true }
PlayerController(玩家控制器)类设置
新建/打开PlayerController类(在这个示例中: 为SFPlayerController):
class SFPlayerController extends UTPlayerController;
var SFHud MySFHud; function registerHUD(SFHud hud) { MySFHud = hud; }
exec function SendTextToServer(SFPlayerController PC, String TextToSend) { `Log(Self$":: Client wants to send '"$TextToSend$"' to the server."); ServerReceiveText(PC, TextToSend); }
reliable server function ServerReceiveText(SFPlayerController PC, String ReceivedText) { WorldInfo.Game.Broadcast(PC, ReceivedText, 'Say'); }
reliable client function ReceiveBroadcast(String PlayerName, String ReceivedText) { `Log(Self$":: The Server sent me '"$ReceivedText$"' from "$PlayerName$"."); MySFHud.UpdateChatLog(PlayerName @ ": " @ ReceivedText); }
通过键盘命令启用Chatting(聊天功能)(按下Enter回车键)
对这一步骤来说,我们会使用Enter(回车键)开启对话并发送(完成)聊天信息。 您也可以使用您喜欢的按键。添加按键绑定
打开DefaultInput.ini并添加以下代码:.Bindings=(Name="Enter",Command="ChatHandler")
.Bindings=(Name="Enter",Command="GBA_Use")
HUDWrapper类设置
打开您的HUDWrapper(HUD封装)。 这就是实例化该HUD的类。 添加这个在按下键时将被执行的函数:exec function ChatHandler() { HudMovie.ToggleChat(); // Replace HudMovie with the reference name of your HUD movie. }
HUD类设置
打开您的HUD类。 首先我们必须要确保所选的键永远不会被我们的HUD短片捕捉为输入。 我们通过将它添加到聚焦忽略键位列表的方法达到目的。 将这些代码添加到您的Start()/Init()函数中。AddFocusIgnoreKey('Enter');
function ToggleChat() { if (!bChatting) { bCaptureInput = true; OnChat(); } else { bCaptureInput = false; OnChatSend(); } }
function OnChat(optional GFxClikWidget.EventData ev) function OnChatSend(optional GFxClikWidget.EventData ev)
MyChatInput.SetBool("focused", true);
MyChatLog.SetBool("focused", true);
下载
- Download(下载) UDK_September2011_ScaleformSandboxFiles.zip.