UDN
Search public documentation:

DevelopmentKitGemsCanvasKismetNodesCH
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

UE3 主页 > 虚幻开发工具包精华文章 > 创建画布 Kismet 节点
UE3 主页 > Kismet 可视化脚本 > 创建画布 Kismet 节点

创建画布 Kismet 节点


最后一次测试是在2011年4月份的UDK版本上进行的。
可以与 PC 和 iOS 兼容

概述


Kismet 是一个非常优秀的工具,在开发者需要/想要尽快迅速创建一个可以正常工作的原型时使用。这篇精华文章将简单的 Canvas 绘制功能添加给可以使绘制材质、贴图和文本变得容易的 Kismet。如果您需要更多的功能,可以进一步扩充与这篇文章相关的内容。使用这篇精华文章比使用现有的 MobileHUD 方法的一个好处是,这种方法适用于任何游戏类型,无论您是否具有您自己的 HUD 子类。

HUDKismetExampleCanvas.jpg

HUDKismetSeqEvent_RenderHUD


每当 HUD 渲染一个帧的时候会调用这个 Kismet 序列事件节点。您想要有多少个节点都可以,但是很难确定调用每个 Render HUD 事件的时间顺序(在一个游戏中一致,但是可能游戏和游戏之间不一致)。

HUDKismetRenderHUDNode.jpg

源代码

这个序列事件的原理是:
  • 在注册序列事件的时候,如果没有发现一个渲染代理,那么创建一个。
  • 如果发现了一个渲染代理,那么它会将自己本身添加到渲染代理的渲染序列数列
  • 在调用渲染代理渲染帧的时候,它会在每个 Render HUD 序列事件中调用 Render 函数。Render HUD 序列事件可以遍历每个渲染序列动作,同时调用在它找到的每个渲染序列动作中调用 Render 函数。

HUDKismetSeqEvent_RenderHUD.uc
class HUDKismetSeqEvent_RenderHUD extends SequenceEvent;

var Object PlayerController;
var Vector CameraPosition;
var Vector CameraDirection;

event RegisterEvent()
{
  local WorldInfo WorldInfo;
  local HUDKismetRenderProxy RenderProxy, FoundRenderProxy;

  // 获取世界信息
  WorldInfo = class'WorldInfo'.static.GetWorldInfo();

  // 如果没有找到世界信息,那么中止
  if (WorldInfo == None)
  {
    return;
  }

  // 查找渲染代理,与这个渲染 HUD 事件关联
  ForEach WorldInfo.DynamicActors(class'HUDKismetRenderProxy', FoundRenderProxy)
  {
    RenderProxy = FoundRenderProxy;
    break;
  }

  // 如果没有找到渲染代理,那么创建一个渲染代理
  if (RenderProxy == None)
  {
    RenderProxy = WorldInfo.Spawn(class'HUDKismetRenderProxy');
  }

  // 将这个 HUD 渲染序列添加到渲染代理
  if (RenderProxy != None)
  {
    RenderProxy.AddRenderHUDSequenceEvent(Self);
  }
}

function Render(Canvas Canvas)
{
  local int i, j;
  local HUDKismetSeqAct_RenderObject RenderObject;

  // 渲染输出链接
  if (OutputLinks.Length > 0)
  {
    for (i = 0; i < OutputLinks.Length; ++i)
    {
      if (OutputLinks[i].Links.Length > 0)
      {
        for (j = 0; j < OutputLinks[i].Links.Length; ++j)
        {
          RenderObject = HUDKismetSeqAct_RenderObject(OutputLinks[i].Links[j].LinkedOp);

          if (RenderObject != None)
          {
            RenderObject.Render(Canvas);
          }
        }
      }
    }
  }
}

defaultproperties
{
  ObjName="Render HUD"
  ObjCategory="ExtHUD"

  MaxTriggerCount=0
  bPlayerOnly=false

  OutputLinks(0)=(LinkDesc="Out")

  VariableLinks(0)=(ExpectedType=class'SeqVar_Object',bHidden=true,LinkDesc="PlayerController",bWriteable=true,PropertyName=PlayerController)
  VariableLinks(1)=(ExpectedType=class'SeqVar_Vector',bHidden=true,LinkDesc="Camera Position",bWriteable=true,PropertyName=CameraPosition)
  VariableLinks(2)=(ExpectedType=class'SeqVar_Vector',bHidden=true,LinkDesc="Camera Direction",bWriteable=true,PropertyName=CameraDirection)
}

添加 Render HUD 序列事件

HUDKismetAddRenderHUDEvent.jpg

HUDKismetRenderProxy


渲染代理是创建与 HUD 内找到的 PostRenderActor 数列相关联的 actor。

源代码

这个渲染代理的原理是:
  • 一个可以将渲染 HUD 序列事件添加到它的内部数列中的辅助函数 (AddRenderHUDSequenceEvent)。它由 HUDKismetSeqEvent_RenderHUD 进行调用。
  • 单独使用 Tick,它可以将自身添加给所有 Player Controller 的 HUD PostRender actor 并将 ShowOverlays 设置为 true,PostRenderActor 需要它才能接收渲染调用。
  • 在 HUD 的 PostRender 调用结束的时候调用 PostRenderFor。它可以将渲染传递给所有注册的渲染 HUD 序列事件。

HUDKismetRenderProxy.uc
class HUDKismetRenderProxy extends Actor;

// 已经将代理赋给玩家控制器了吗?
var bool HasAddedToAllControllers;
// HUD 渲染事件列表
var PrivateWrite array<HUDKismetSeqEvent_RenderHUD> RenderHUDSequenceEvents;

function AddRenderHUDSequenceEvent(HUDKismetSeqEvent_RenderHUD RenderHUDSequenceEvent)
{
  local int i;

  // 检查渲染 HUD 序列事件是否已经存在
  if (RenderHUDSequenceEvents.Length > 0)
  {
    for (i = 0; i < RenderHUDSequenceEvents.Length; ++i)
    {
      if (RenderHUDSequenceEvents[i] == RenderHUDSequenceEvent)
      {
        return;
      }
    }
  }

  // 将渲染 HUD 序列事件添加到数列中
  RenderHUDSequenceEvents.AddItem(RenderHUDSequenceEvent);
}

function Tick(float DeltaTime)
{
  local PlayerController PlayerController;

  if (!HasAddedToAllControllers)
  {
    // 将渲染代理添加给所有本地玩家控制器
    ForEach WorldInfo.AllControllers(class'PlayerController', PlayerController)
    {
      if (PlayerController != None && PlayerController.MyHUD != None)
      {
        PlayerController.MyHUD.bShowOverlays = true;
        PlayerController.MyHUD.AddPostRenderedActor(Self);
        HasAddedToAllControllers = true;
      }
    }
  }

  Super.Tick(DeltaTime);
}

simulated event PostRenderFor(PlayerController PC, Canvas Canvas, Vector CameraPosition, Vector CameraDir)
{
  local int i;

  // 如果画布无效或者没有可以渲染的序列事件,那么中止
  if (Canvas == None || RenderHUDSequenceEvents.Length <= 0)
  {
    return;
  }

  // 对于每个 HUD 渲染序列,传递渲染
  for (i = 0; i < RenderHUDSequenceEvents.Length; ++i)
  {
    if (RenderHUDSequenceEvents[i] != None)
    {
      // 为 Kismet 传递玩家控制器
      RenderHUDSequenceEvents[i].PlayerController = PC;
      // 为 Kismet 传递相机位置
      RenderHUDSequenceEvents[i].CameraPosition = CameraPosition;
      // 为 Kismet 传递相机方向
      RenderHUDSequenceEvents[i].CameraDirection = CameraDir;
      // 传递渲染调用
      RenderHUDSequenceEvents[i].Render(Canvas);
    }
  }
}

defaultproperties
{
  bPostRenderIfNotVisible=true
}

HUDKismetSeqAct_RenderObject


这是一个所有其他渲染 kismet 序列动作可以继承的抽象 kismet 序列动作。

源代码

这个抽象序列动作的原理是:
  • 在调用渲染函数的时候,它会将其传递给所有连接的子代。

HUDKismetSeqAct_RenderObject.uc
class HUDKismetSeqAct_RenderObject extends SequenceAction
  abstract;

function Render(Canvas Canvas)
{
  local int i, j;
  local HUDKismetSeqAct_RenderObject RenderObject;

  // 将渲染调用传递给所有其他子代链接
  if (OutputLinks.Length > 0)
  {
    for (i = 0; i < OutputLinks.Length; ++i)
    {
      if (OutputLinks[i].Links.Length > 0)
      {
        for (j = 0; j < OutputLinks[i].Links.Length; ++j)
        {
          RenderObject = HUDKismetSeqAct_RenderObject(OutputLinks[i].Links[j].LinkedOp);

          if (RenderObject != None)
          {
            RenderObject.Render(Canvas);
          }
        }
      }
    }
  }
}

defaultproperties
{
  VariableLinks.Empty
}

HUDKismetSeqAct_RenderTexture


这个 Kismet 序列动作可以将贴图渲染到画布上。

HUDKismetRenderTextureNode.jpg

源代码

这个序列动作的原理是:
  • 在进行渲染之前,检查 Canvas 是否有效,使用实际或相对估测,使用实际或相对位置。
  • 如果已经将用户连接到 Texture Kismet 变量节点,那么它会覆盖这个 Texture 属性值
  • 计算渲染位置
  • 计算渲染大小
  • 计算贴图渲染边界
  • 根据已经由用户设置的各种属性对贴图进行拉伸渲染、旋转渲染或者是正常渲染

HUDKismetSeqAct_RenderTexture.uc
class HUDKismetSeqAct_RenderTexture extends HUDKismetSeqAct_RenderObject;

struct TextureRotation
{
  // 贴图要进行旋转的量,以虚幻单位计算(65536 == 360 度)
  var() int Rotation;
  // 要进行旋转的相对点(0.5f 位于中心)
  var() Vector2D Anchor;

  structdefaultproperties
  {
    Anchor=(X=0.5f,Y=0.5f)
  }
};

struct TextureCoords
{
  var() float U;
  var() float V;
  var() float UL;
  var() float VL;

  structdefaultproperties
  {
    U=0.f
    V=0.f
    UL=-1.f
    VL=-1.f
  }
};

struct TextureStretched
{
  var() bool StretchHorizontally;
  var() bool StretchVertically;
  var() float ScalingFactor;

  structdefaultproperties
  {
    ScalingFactor=1.f
  }
};

// 使用实际尺寸坐标的条件
var bool UsingActualSize;
// 使用相对尺寸坐标的条件
var bool UsingRelativeSize;
// 使用实际位置坐标的条件
var bool UsingActualPosition;
// 使用相对位置坐标的条件
var bool UsingRelativePosition;
// 使用拉伸的方法的条件
var bool UsingStretched;
// 重载 blend 模式的条件
var bool OverrideBlendMode;

// 要渲染的贴图。在用户设置贴图变量链接的情况下会被覆盖
var(RenderTexture) Object Texture;
// 渲染这个贴图的实际尺寸
var(RenderTexture) IntPoint ActualSize<EditCondition=UsingActualSize>;
// 渲染这个贴图相对视窗分辨率的尺寸
var(RenderTexture) Vector2D RelativeSize<EditCondition=UsingRelativeSize>;
// 渲染这个贴图的实际位置
var(RenderTexture) IntPoint ActualPosition<EditCondition=UsingActualPosition>;
// 渲染这个贴图相对视窗分辨率的位置
var(RenderTexture) Vector2D RelativePosition<EditCondition=UsingRelativePosition>;
// 要渲染的贴图的旋转量
var(RenderTexture) TextureRotation Rotation;
// 要渲染的贴图的坐标
var(RenderTexture) TextureCoords Coords;
// 要渲染给这个贴图的颜色
var(RenderTexture) Color RenderColor<DisplayName=Color>;
// 渲染贴图时拉伸的属性
var(RenderTexture) TextureStretched Stretched<EditCondition=UsingStretched>;
// 如果贴图有一部分在渲染边界外面,我们要对它进行剪裁吗? (只针对那些没有旋转、没有拉伸的贴图)
var(RenderTexture) bool ClipTile;
// 渲染贴图的 Blend 模式(只针对那些没有旋转、没有拉伸的贴图块)(通常为 iOS 上的材质进行重载)
var(RenderTexture) EBlendMode BlendMode<EditCondition=OverrideBlendMode>;

function Render(Canvas Canvas)
{
  local IntPoint RenderPosition;
  local IntPoint RenderSize;
  local Texture2D RenderTexture;
  local int UL;
  local int VL;
  local Rotator R;
  local SeqVar_Object SeqVar_Object;

  if (Canvas != None && (UsingActualSize || UsingRelativeSize) && (UsingActualPosition || UsingRelativePosition))
  {
    // 检查用户是否已经设置贴图 kismet 节点链接
    if (VariableLinks[0].LinkedVariables.Length > 0)
    {
      SeqVar_Object = SeqVar_Object(VariableLinks[0].LinkedVariables[0]);

      if (SeqVar_Object != None)
      {
        RenderTexture = Texture2D(SeqVar_Object.GetObjectValue());
      }
    }
    else
    {
      RenderTexture = Texture2D(Texture);
    }

    if (RenderTexture != None)
    {
      // 计算位置
      if (UsingRelativePosition)
      {
        RenderPosition.X = Canvas.ClipX * RelativePosition.X;
        RenderPosition.Y = Canvas.ClipY * RelativePosition.Y;
      }
      else
      {
        RenderPosition = ActualPosition;
      }

      // 计算尺寸
      if (UsingRelativeSize)
      {
        RenderSize.X = Canvas.ClipX * RelativeSize.X;
        RenderSize.Y = Canvas.ClipY * RelativeSize.Y;
      }
      else
      {
        RenderSize = ActualSize;
      }

      // 计算贴图宽度
      UL = (Coords.UL == -1) ? RenderTexture.SizeX : int(Coords.UL);
      // 计算贴图高度
      VL = (Coords.VL == -1) ? RenderTexture.SizeY : int(Coords.VL);

      // 设置要渲染的位置
      Canvas.SetPos(RenderPosition.X, RenderPosition.Y);
      // 设置绘制颜色
      Canvas.SetDrawColor(RenderColor.R, RenderColor.G, RenderColor.B, RenderColor.A);

      if (UsingStretched)
      {
        // 以拉伸方式渲染贴图
        Canvas.DrawTileStretched(RenderTexture, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL,, Stretched.StretchHorizontally, Stretched.StretchVertically, Stretched.ScalingFactor);
      }
      else
      {
        if (Rotation.Rotation == 0)
        {
          // 以正常方式渲染贴图
          if (OverrideBlendMode)
          {
            Canvas.DrawTile(RenderTexture, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL,, ClipTile, BlendMode);
          }
          else
          {
            Canvas.DrawTile(RenderTexture, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL,, ClipTile);
          }
        }
        else
        {
          // 以旋转方式渲染贴图
          R.Pitch = 0;
          R.Yaw = Rotation.Rotation;
          R.Roll = 0;
          Canvas.DrawRotatedTile(RenderTexture, R, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL, Rotation.Anchor.X, Rotation.Anchor.Y);
        }
      }
    }
  }

  Super.Render(Canvas);
}

defaultproperties
{
  RenderColor=(R=255,G=255,B=255,A=255)

  ObjName="Render Texture"
  ObjCategory="ExtHUD"

  VariableLinks(0)=(ExpectedType=class'SeqVar_Object',LinkDesc="Texture",PropertyName=Texture)
}

添加 Render Texture 序列动作

HUDKismetAddRenderTextureAction.jpg

渲染贴图属性

  • Texture - 要渲染的贴图。在用户设置 Texture Kismet 变量节点的时候会重载它。
  • Actual Size - 要渲染这个贴图的尺寸(以像素为单位)。
  • Relative Size - 要渲染这个贴图的尺寸(相对于视窗分辨率)。
  • Actual Position - 要渲染这个贴图的位置(以像素为单位)。
  • Relative Position - 要渲染这个贴图的位置(相对于视窗分辨率)。
  • 旋转
    • Rotation - 要旋转这个贴图的角度(以虚幻单位计算) 65536 uu = 360 度
    • Anchor - 要旋转这个贴图的相对位置。0.5f = 中心
  • Coords - 要渲染的细分贴图的坐标。保留默认值,渲染整个贴图。
  • Color - 要渲染给这个贴图的颜色
  • 拉伸方式
    • StretchHorizontal - 允许在水平方向上拉伸贴图
    • StretchVertically - 允许在垂直方向上拉伸贴图
    • ScalingFactor - 修改拉伸缩放比例
  • ClipTile - 如果贴图块有一部分在屏幕外面,会剪裁贴图块渲染。
  • BlendMode - 允许您重载混合模式,否则 Canvas 会检测贴图类型并相应地进行混合。

HUDKismetRenderTextureProperties.jpg

相关主题

HUDKismetSeqAct_RenderMaterial


这个 Kismet 序列动作可以将材质渲染到画布上。

HUDKismetRenderMaterialNode.jpg

源代码

这个序列动作的原理是:
  • 在调用 Render 函数后,检查确保 Canvas 有效,使用实际或相对尺寸,或者使用实际或相对位置。
  • 检查用户是否已经设置 Material Kismet 变量节点。如果用户使用的是 MaterialInstanceActor,那么在其中检索材质实例常量。否则,获取材质界面设置。
  • 计算位置。
  • 计算尺寸。
  • 计算坐标。
  • 平台检测
    • 如果平台是移动平台或 iOS,按照 Material 中定义重载这个混合模式。然后如果适用,使用存储在 Material 中 MobileBaseTexture 参数回复到 RenderTexture 渲染函数。
    • 除此之外,以正常方式或旋转方式渲染材质。

HUDKismetSeqAct_RenderMaterial.uc
class HUDKismetSeqAct_RenderMaterial extends HUDKismetSeqAct_RenderTexture;

// 要渲染的材质。在用户设置材质变量链接的情况下会被覆盖
var(RenderMaterial) Object Material;

function Render(Canvas Canvas)
{
  local IntPoint RenderPosition;
  local IntPoint RenderSize;
  local MaterialInterface RenderMaterialInterface;
  local Material RenderMaterial;
  local int UL;
  local int VL;
  local Rotator R;
  local SeqVar_Object SeqVar_Object;
  local WorldInfo worldInfo;

  // 检查是否允许我们在这个平台上运行
  WorldInfo = class'WorldInfo'.static.GetWorldInfo();
  if (WorldInfo != None && (WorldInfo.IsConsoleBuild(CONSOLE_Mobile) || WorldInfo.IsConsoleBuild(CONSOLE_IPhone)))
  {
    // 检查用户是否已经设置材质 kismet 节点链接
    if (VariableLinks[0].LinkedVariables.Length > 0)
    {
      SeqVar_Object = SeqVar_Object(VariableLinks[0].LinkedVariables[0]);

      if (SeqVar_Object != None)
      {
        if (MaterialInterface(SeqVar_Object.GetObjectValue()) != None)
        {
          RenderMaterialInterface = MaterialInterface(SeqVar_Object.GetObjectValue());
        }
        else if (MaterialInstanceActor(SeqVar_Object.GetObjectValue()) != None)
        {
          RenderMaterialInterface = MaterialInstanceActor(SeqVar_Object.GetObjectValue()).MatInst;
        }
      }
    }
    else
    {
      if (MaterialInterface(Material) != None)
      {
        RenderMaterialInterface = MaterialInterface(Material);
      }
      else if (MaterialInstanceActor(Material) != None)
      {
        RenderMaterialInterface = MaterialInstanceActor(Material).MatInst;
      }
    }

    if (RenderMaterialInterface != None)
    {
      RenderMaterial = Material(RenderMaterialInterface);
      if (RenderMaterial != None)
      {
        OverrideBlendMode = true;
        BlendMode = RenderMaterial.BlendMode;
      }

      Texture = RenderMaterialInterface.MobileBaseTexture;

      if (Texture != None)
      {
        Super.Render(Canvas);
      }
    }
  }
  else
  {
    if (Canvas != None && (UsingActualSize || UsingRelativeSize) && (UsingActualPosition || UsingRelativePosition))
    {
      // 检查用户是否已经设置材质 kismet 节点链接
      if (VariableLinks[0].LinkedVariables.Length > 0)
      {
        SeqVar_Object = SeqVar_Object(VariableLinks[0].LinkedVariables[0]);

        if (SeqVar_Object != None)
        {
          if (MaterialInterface(SeqVar_Object.GetObjectValue()) != None)
          {
            RenderMaterialInterface = MaterialInterface(SeqVar_Object.GetObjectValue());
          }
          else if (MaterialInstanceActor(SeqVar_Object.GetObjectValue()) != None)
          {
            RenderMaterialInterface = MaterialInstanceActor(SeqVar_Object.GetObjectValue()).MatInst;
          }
        }
      }
      else
      {
        if (MaterialInterface(Material) != None)
        {
          RenderMaterialInterface = MaterialInterface(Material);
        }
        else if (MaterialInstanceActor(Material) != None)
        {
          RenderMaterialInterface = MaterialInstanceActor(Material).MatInst;
        }
      }

      if (RenderMaterialInterface != None)
      {
        // 计算位置
        if (UsingRelativePosition)
        {
          RenderPosition.X = Canvas.ClipX * RelativePosition.X;
          RenderPosition.Y = Canvas.ClipY * RelativePosition.Y;
        }
        else
        {
          RenderPosition = ActualPosition;
        }

        // 计算尺寸
        if (UsingRelativeSize)
        {
          RenderSize.X = Canvas.ClipX * RelativeSize.X;
          RenderSize.Y = Canvas.ClipY * RelativeSize.Y;
        }
        else
        {
          RenderSize = ActualSize;
        }

        // 计算贴图宽度
        UL = (Coords.UL == -1) ? 1.f : Coords.UL;
        // 计算贴图高度
        VL = (Coords.VL == -1) ? 1.f : Coords.VL;

        // 设置要渲染的位置
        Canvas.SetPos(RenderPosition.X, RenderPosition.Y);

        if (Rotation.Rotation == 0)
        {
          // 以正常方式渲染材质
          Canvas.DrawMaterialTile(RenderMaterialInterface, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL);
        }
        else
        {
          // 以旋转方式渲染材质
          R.Pitch = 0;
          R.Yaw = Rotation.Rotation;
          R.Roll = 0;
          Canvas.DrawRotatedMaterialTile(RenderMaterialInterface, R, RenderSize.X, RenderSize.Y, Coords.U, Coords.V, UL, VL, Rotation.Anchor.X, Rotation.Anchor.Y);
        }
      }
    }

    Super(HUDKismetSeqAct_RenderObject).Render(Canvas);
  }
}

defaultproperties
{
  ObjName="Render Material"
  ObjCategory="ExtHUD"

  VariableLinks(0)=(ExpectedType=class'SeqVar_Object',LinkDesc="Material",PropertyName=Material)
}

添加 Render Material 序列动作

HUDKismetAddRenderMaterialAction.jpg

渲染材质属性

  • Material - 要渲染的材质。它在用户设置 Material Kismet 节点的时候会被覆盖。

HUDKismetRenderMaterialProperties.jpg

相关主题

HUDKismetSeqAct_RenderText


这个 Kismet 序列动作可以将文本渲染到画布上。

HUDKismetRenderTextNode.jpg

源代码

这个序列动作的原理是:
  • 在调用渲染函数的时候,检查画布是否有效,字体是否有效,使用非本地化文本或本地化文本或使用实际或相对定位方式。
  • 渲染这个文本。它会在用户设置文本/本地化文本 Kismet 变量节点的情况下被覆盖。如果您使用其中任意一个,那么请记住分别标记边界框并将字段留空。
  • 根据左对齐和上对齐计算初始位置。
  • 设置字体并获取文本大小。
  • 根据水平和垂直对齐属性偏离这个位置。
  • 渲染文本。

HUDKismetSeqAct_RenderText.uc
class HUDKismetSeqAct_RenderText extends HUDKismetSeqAct_RenderObject;

// 水平对齐选项
enum EHorizontalAlignment
{
  EHA_Left<DisplayName=Left>,
  EHA_Center<DisplayName=Center>,
  EHA_Right<DisplayName=Right>
};

// 垂直对齐选项
enum EVerticalAlignment
{
  EVA_Top<DisplayName=Top>,
  EVA_Middle<DisplayName=Middle>,
  EVA_Bottom<DisplayName=Bottom>
};

// 使用实际位置坐标的条件
var bool UsingActualPosition;
// 使用相对位置坐标的条件
var bool UsingRelativePosition;
// 使用非本地化文本(未加工输入)的条件
var bool UsingNonLocalizedText;
// 使用本地化文本的条件
var bool UsingLocalizedText;

// 渲染这个贴图的实际位置
var(RenderText) IntPoint ActualPosition<EditCondition=UsingActualPosition>;
// 渲染这个贴图相对视窗分辨率的位置
var(RenderText) Vector2D RelativePosition<EditCondition=UsingRelativePosition>;
// 要渲染给这个文本的颜色
var(RenderText) Color RenderColor<DisplayName=Color>;
// 要渲染的未经加工的文本
var(RenderText) String Text<EditCondition=UsingNonLocalizedText>;
// 可以得到文本进行渲染的本地化路径
var(RenderText) String LocalizedText<EditCondition=UsingLocalizedText>;
// 水平对齐
var(RenderText) EHorizontalAlignment HorizontalAlignment;
// 垂直对齐
var(RenderText) EVerticalAlignment VerticalAlignment;
// 要渲染这个文本的字体
var(RenderText) Font Font;

function Render(Canvas Canvas)
{
  local IntPoint RenderPosition;
  local float TextWidth, TextHeight;
  local String RenderText;
  local SeqVar_String SeqVar_String;

  if (Canvas != None && Font != None && (UsingNonLocalizedText || UsingLocalizedText) && (UsingActualPosition || UsingRelativePosition))
  {
    // 获取渲染文本
    if (UsingNonLocalizedText)
    {
      // 检查用户是否已经设置文本变量链接
      if (Text ~= "" && VariableLinks[0].LinkedVariables.Length > 0)
      {
        SeqVar_String = SeqVar_String(VariableLinks[0].LinkedVariables[0]);

        if (SeqVar_String != None)
        {
          RenderText = SeqVar_String.StrValue;
        }
      }
      else
      {
      RenderText = Text;
      }
    }
    else
    {
      // 检查用户是否已经设置本地化文本变量链接
      if (LocalizedText ~= "" && VariableLinks[1].LinkedVariables.Length > 0)
      {
        SeqVar_String = SeqVar_String(VariableLinks[1].LinkedVariables[0]);

        if (SeqVar_String != None)
        {
          RenderText = ParseLocalizedPropertyPath(SeqVar_String.StrValue);
        }
      }
      else
      {
        RenderText = ParseLocalizedPropertyPath(LocalizedText);
      }
    }

    if (RenderText != "")
    {
      // 计算位置
      if (UsingRelativePosition)
      {
        RenderPosition.X = Canvas.ClipX * RelativePosition.X;
        RenderPosition.Y = Canvas.ClipY * RelativePosition.Y;
      }
      else
      {
        RenderPosition = ActualPosition;
      }

      // 设置字体
      Canvas.Font = Font;
      // 计算文本大小
      Canvas.TextSize(RenderText, TextWidth, TextHeight);

      // 处理水平对齐
      if (HorizontalAlignment == EHA_Center)
      {
        RenderPosition.X -= (TextWidth * 0.5f);
      }
      else if (HorizontalAlignment == EHA_Right)
      {
        RenderPosition.X -= TextWidth;
      }

      // 处理垂直对齐
      if (VerticalAlignment == EVA_Middle)
      {
        RenderPosition.Y -= (TextHeight * 0.5f);
      }
      else if (VerticalAlignment == EVA_Bottom)
      {
        RenderPosition.Y -= TextHeight;
      }

      // 设置画布位置
      Canvas.SetPos(RenderPosition.X, RenderPosition.Y);
      // 设置文本颜色
      Canvas.SetDrawColor(RenderColor.R, RenderColor.G, RenderColor.B, RenderColor.A);
      // 渲染文本
      Canvas.DrawText(RenderText);
    }
  }

  Super.Render(Canvas);
}

defaultproperties
{
  RenderColor=(R=255,G=255,B=255,A=255)

  ObjName="Render Text"
  ObjCategory="ExtHUD"

  VariableLinks(0)=(ExpectedType=class'SeqVar_String',LinkDesc="Text",MaxVars=1,PropertyName=Text)
  VariableLinks(1)=(ExpectedType=class'SeqVar_String',LinkDesc="Localized Text",MaxVars=1,PropertyName=LocalizedText)
}

添加 Render Text 序列动作

HUDKismetAddRenderTextAction.jpg

渲染文本属性

  • Actual Position - 要渲染这个材质的位置(以像素为单位)。
  • Relative Position - 要渲染这个材质的位置(相对于视窗分辨率)。
  • Color - 要渲染给这个文本的颜色
  • Text - 要渲染的文本。它在用户设置 Text Kismet 变量节点的时候会被覆盖。
  • Localized Text - 要渲染的本地化文本。它在用户设置本地化的 Text Kismet 变量节点的时候会被覆盖。
  • Horizontal Alignment - 要渲染文本的水平对齐方式。
  • Vertical Alignment - 要渲染文本的垂直对齐方式。
  • Font - 要渲染给这个文本的字体。

HUDKismetRenderTextProperties.jpg

相关主题

示例使用情况


可以使用这个 Kismet 布局在这篇精华文章顶部生成屏幕截图。

HUDKismetExampleKismet.jpg

相关主题


下载


  • 下载内容/源代码。(CanvasKismetNodes.zip)