2012-04-24

Unity 3D 在 iOS 上顯示中文字串


之前使用 Unity3D 寫遊戲程式都是以 Dynamic Font 功能來顯示中文字串,最近才發現這功能不支援 iOS,因此若要在 iOS 上使用 Dynamic Font 就得自己做了,幸運的是實作起來並不複雜,底下敘述如何將中文字串轉成圖片 ( Texture2D ) 的方法 : ( 概略是利用 iOS 內建的 Font Renderer 先把字串畫在主記憶體裡,再利用 OpenGL 指令將記憶體裡字串的圖片轉成貼圖 )

全部範例檔案有三個 :
1. main.cs
    a. 放在 Assets 目錄底下
    b. 此 Script 依附在 Main Camera 上

2. dynaFont.cs
    a. 放在 Assets/Plugins 目錄底下
    b. 此檔案為 unity3d 內部 script 與 plugin 之間的介面

3. dynaFont.m
    a. 放在 Assets/Plugins/iOS 目錄底下 (轉成 xcode project 時將自動引入)
    b. 不需事先編譯

首先看 main.cs 檔案內容 :


using UnityEngine;
using System.Collections;

public class main : MonoBehaviour {

    // Use this for initialization
    void Start ()
    {
        int nWidth =128;
int nHeight =128;

        //產生 128x128 (注意大小為2冪次方)之 texture
Texture2D tex =
            new Texture2D(
                nWidth, 
                nHeight, 
                TextureFormat.Alpha8
                false);

        //把中文字畫在 texture 上
        genTexture(
            tex.GetNativeTextureID(), 
            "中文測試"
            "Arial"
            10
            128
            128);
}
}


dynaFont.cs 檔案內容如下 :


using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
//
//此為 unity3d 內部程式呼叫外部 plugin 函數之間的介面
//
public class dynaFont
{
    //指示 getTexture 為外部 plugin 函數
  [DllImport("__Internal")]
  public static extern bool genTexture(
        int nTexID, 
        string strText, 
        string strFontName, 
        int nFontSz, 
        int nTexWidth, 
        int nTexHeight);
}


dynaFont.m 檔案內容如下 :


#import <Foundation/Foundation.h>
//
// 將 char 指標 (對應 C# 的 string) 轉成 iOS 字串格式 (NSString)
//
NSString* dynaFont_GetString(const char* pChar)
{
  if (pChar ==NULL)
      return [NSString stringWithUTF8String:""];
return [NSString stringWithUTF8String:pChar];
}


//
// 利用 NSString 的 drawInRect 畫出字串後再以 glTexImage2D 產生貼圖
//
bool genTexture( int nTexID, 
                 const char* pStrText, 
                 const char* pStrFontName, 
                 int nFontSz, 
                 int nTexWidth, 
                 int nTexHeight)
{
    unsigned char* pData =
        (unsigned char*)calloc(nTexWidth, nTexHeight);

    CGColorSpaceRef pcs =CGColorSpaceCreateDeviceGray();
    CGContextRef pcon =
        CGBitmapContextCreate(
            pData, 
            nTexWidth, 
            nTexHeight, 
            8
            nTexWidth, 
            pcs, 
            kCGImageAlphaNone);
    CGColorSpaceRelease(pcs);

    if (!pcon)
    {
      free(pData);
      return false;
    }
    else
    {
      CGContextSetGrayFillColor(pcon, 1.0f, 1.0f);

    CGSize rc =CGSizeMake(nTexWidth, nTexHeight);
    UIFont* pf =
            [ UIFont
              fontWithName:dynaFont_GetString(pStrFontName) 
              size:nFontSz];

    UIGraphicsPushContext(pcon);
        [ dynaFont_GetString(pStrText)
          drawInRect:CGRectMake(0,0,rc.width, rc.height) 
          withFont:pf lineBreakMode:UILineBreakModeWordWrap 
          alignment:UITextAlignmentLeft];
    UIGraphicsPopContext();

    glBindTexture(GL_TEXTURE_2D, nTexID);
    glTexImage2D(
            GL_TEXTURE_2D, 
            0
            GL_ALPHA, 
           (GLsizei)nTexWidth, (GLsizei)nTexHeight, 
            0
            GL_ALPHA, 
            GL_UNSIGNED_BYTE, 
            pData);
    CGContextRelease(pcon);

    free(pData);
    }
    return true;
}


0 意見 :

張貼留言