UDN
Search public documentation:

ScriptedTexturesCH
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 主页 > 渲染 > 脚本化贴图
UE3 主页 > 虚幻脚本 > 脚本化贴图

脚本纹理


概述


脚本纹理可以在 UnrealScript 运行期间任意绘制到纹理上。在我们的案例中,这个时间可以在替代的 2 分钟范围内,这其中考虑了使用该文档中讨论的 HW 可以节省长达 30 秒的链接时间,可以非常快速地节约同步时间。这意味着可以将文本、材质、其他纹理等等全部绘制到手绘纹理中。

使用该功能可以进行任何您想进行的操作。在运动的游戏中,某些示例可能会将玩家的名称绘制在他们的制服上,在世界表面上显示排行榜,显示通过 TCPLink 或 DLLBind 源获取的外部源中的文本在线馈源,或者甚至是某些像允许玩家直接在游戏内部表面上绘制的复杂操作。

ScriptedTexture 类


通过 TextureRenderTarget2D 类扩展 ScriptedTexture 类。它由以下几个重要部分组成:

属性

  • Size[X/Y] - 纹理分别在水平方向和垂直方向上的大小。由 TextureRenderTarget2D 继承而来。
  • Format - 纹理数据的 EPixelFormat 格式。由 TextureRenderTarget2D 继承而来。
  • ClearColor - LinearColor 过去常常清除纹理。由 TextureRenderTarget2D 继承而来。
  • bNeedsUpdate - 如果是 true,在更新结束的时候会调用 Render() 代理,刚好在进行所有其他渲染之前。
  • bSkipNextClear - 如果是 true,在下一次调用 Render() 代理之前不会清除该纹理。如果您想要通过多帧绘制到纹理上,那么可以使用这个属性。

函数

  • 创建 [InSizeX] [InSizeY] [InFormat] [InClearColor] [bOnlyRenderOnce] - 静态。使用指定的参数新建一个 TextureRenderTarget2D。由 TextureRenderTarget2D 继承而来。
    • InSizeX - 设置新纹理在水平方向上的大小。
    • InSizeY - 设置新纹理在垂直方向上的大小。
    • InFormat - 可选。将 EPixelFormat 设置为供纹理使用。
    • InClearColor - 可选。设置 =LinearColor=,清除纹理。
    • bOnlyRenderOnce - 可选。如果是 true,纹理将只会更新一次,它创建的第一帧。
  • Render [C] - 调用该代理可以绘制到纹理上。
    • C - 使用 Canvas 对象可以绘制到当前帧的纹理上。

ScriptedTexture 设置


为了创建并使用 ScriptedTexture,要执行一些步骤,可能不会立即看到明显的效果。在此要详细说明的要点是在您的游戏中使用 ScriptedTextures 的方法。

ScriptedTexture 创建

第一步,必须在您的类中新建一个 ScriptedTexture。可以使用 Create() 函数进行这项操作,但是由于它会返回一个 TextureRenderTarget2D 而不清楚它的使用方法。

var ScriptedTexture CanvasTexture;

...

CanvasTexture = ScriptedTexture(class'ScriptedTexture'.static.Create(1024, 1024,, ClearColor));

通过 ScriptedTexture 类调用 Create() 静态函数,然后转换为 Scriptedtexture。这样就可以将它赋给一个 ScriptedTexture 变量,引用新的 ScriptedTexture。

分配 ScriptedTexture

只要 ScriptedTexture 创建完成后,需要将其赋给一个材质,以便使用。这需要在 UnrealEd 中稍微设置一下,因为我们需要一个具有 TextureSampleParameter2D 表达式的材质,我们可以将 ScriptedTexture 赋给这个表达式。

ex_material_param.jpg

var StaticMeshCompeonent Mesh; //使用 Mesh 显示游戏中材质
var MaterialInstanceConstant CanvasMaterial; //赋给 ScriptedTexture 的新材质实例
var MaterialInterface CanvasMaterialTemplate; //在 UnrealEd 中使用 TextureSampleParameter2D 创建的材质
var Int CanvasMaterialIndex; //赋给新材质的网格物体上的材质索引
var Name CanvasMaterialParameterName; //在 CanvasMaterialTemplate 中 TextureSampleParameter2D 的名称

...

CanvasMaterial = Mesh.CreateAndSetMaterialInstanceConstant(CanvasMaterialIndex);
if(CanvasMaterial != none)
{
   CanvasMaterial.SetParent(CanvasMaterialTemplate);

   if(CanvasMaterialParameterName != '')
   {
      CanvasMaterial.SetTextureParameterValue(CanvasMaterialParameterName, CanvasTexture);
   }
}

新建一个 MaterialInsatnceConstant 并将其赋给静态网格物体。然后将该材质的父代设置为 CanvasMaterialTemplate,它应该引用将纹理参数设置为接收 ScriptedTexture 的模板材质。最后,将 ScriptedTexture 赋给纹理参数。

渲染代理

ScriptedTexture 全部设置完成可以进行显示后,最后一个步骤是绘制到纹理上。这需要将一个函数赋给 ScriptedTexture 的 Render() 代理。然后,在绘制函数内部,可以使用标准 Canvas 绘制命令绘制到 ScriptedTexture 上。

CanvasTexture.Render = OnRender;

...

function OnRender(Canvas C)
{
   ...Drawing Commands...
}

ScriptedTexture 示例


该示例显示了 ScriptedTexture 的整个实现过程,它会显示在游戏中网格物体上文本的水平滚动部分。当然,该示例只会反复地显示一个字符串,但是它可以引入新字符串。可以进行扩展,引入文本的新字符串,然后将其添加到缓存数组中,以便显示正在进行的文本载入,例如此类的 IRC 聊天室。

关注的要点是 PostBeginPlay()ConsoleRender() ,因为它们分别控制着 ScriptedTexture 的设置和渲染。

scriptedtexture_preview.gif

TextConsole.uc

class TextConsole extends Actor placeable;

var() int ConsoleMaterialIndex;
var() MaterialInterface ConsoleMaterialTemplate;
var() name CanvasTextureParamName;

var MaterialInstanceConstant ConsoleMaterial;
var ScriptedTexture CanvasTexture;
var() float ScrollAmount;
var() float TextScale;
var() LinearColor ClearColor;
var() Color TextColor;

var string ConsoleText;
var Vector2D Pos;

var() editinline const StaticMeshComponent Mesh;

function PostBeginPlay()
{
   super.PostBeginPlay();

   CanvasTexture = ScriptedTexture(class'ScriptedTexture'.static.Create(1024, 1024,, ClearColor));
   CanvasTexture.Render = OnRender;

   if(ConsoleMaterialTemplate != none)
   {
      ConsoleMaterial = Mesh.CreateAndSetMaterialInstanceConstant(ConsoleMaterialIndex);
      if(ConsoleMaterial != none)
      {
         ConsoleMaterial.SetParent(ConsoleMaterialTemplate);

         if(CanvasTextureParamName != '')
         {
            ConsoleMaterial.SetTextureParameterValue(CanvasTextureParamName, CanvasTexture);
         }
      }
   }

   SetConsoleText("Console Display Text");
   Pos.X = CanvasTexture.SizeX;
}

function SetConsoleText(string text)
{
   ConsoleText = text;
}

function OnRender(Canvas C)
{
   local Vector2D TextSize;

   C.TextSize(ConsoleText, TextSize.X, TextSize.Y);
   TextSize *= TextScale;
   Pos.Y = (CanvasTexture.SizeY / 2) - (TextSize.Y / 2);
   Pos.X -= WorldInfo.DeltaSeconds * ScrollAmount;
   if(Pos.X < -TextSize.X)
   {
      Pos.X = CanvasTexture.SizeX;
   }

   C.SetOrigin(0,0);
   C.SetClip(CanvasTexture.SizeX + TextSize.X, CanvasTexture.SizeY + TextSize.Y);
   C.SetPos(Pos.X, Pos.Y);

   C.SetDrawColorStruct(TextColor);

   C.DrawText(ConsoleText,, TextScale, TextScale);

   CanvasTexture.bNeedsUpdate = true;
}

defaultproperties
{
   ClearColor=(R=0.0,G=0.0,B=0.0,A=0.0)
   TextColor=(R=255,G=255,B=255,A=255)
   ScrollAmount=150.0
   TextScale=1.0

   Begin Object class=StaticMeshComponent Name=StaticMeshComp1
      StaticMesh=StaticMesh'dwStaticMeshes.Plane'
   End Object

   Mesh = StaticMeshComp1
   Components.Add(StaticMeshComp1)
}