2012年9月1日 星期六

Unity優化整理


1.非必要請少用Update,如一定需要使用可改為非每次讀取

//五格讀一次
function Update() {
    if(Time.frameCount % 5 == 0) { 
        DoSomeThing(); 
    }
}

2.主動回收垃圾
這是我在某處找到的資料,實際運作的成效我感覺不出來

function Update() {
    if(Time.frameCount % 50 == 0) { 
        System.GC.Collect();
    }
}

3.一個模型一張貼圖,不使用復合材質

4.在不影響效果下,壓縮貼圖

5.如果一個腳本多處有使用的話,盡量委派

private var _EffectScript:EffectScript;
function Start() {
    _EffectScript=GameSingleton.Effect.GetComponent(EffectScript);
}

6.一直Instantiate是非常消耗CPU,建議創造出來的物件能重複利用

7.小習慣 能使用int就不要使用float


各位大大,如果有相關的優化資料,也可交流一下!!
待捕完........

更容易的存取場景中的GameObject


不知道這是不是大家都會用的方法!!

之前要在腳本存取場景中的GameObject
就必須

public var TestObject:GameObject;
然後聯結場景中的物件,
有多少腳本要使用就必須拉幾次,
我就想說能不能只要做一次就好

以下是我現在使用的方法
建一個全域的腳本

GameSingleton.js
================================
#pragma strict
static var TestObject:GameObject;//全域變數
================================

然後有個一開始要執行的腳本

StartGame.js
================================
#pragma strict
public var TestObject:GameObject;//聯結場景中的物件
function Awake(){
GameSingleton.TestObject= TestObject;//將全域的TestObject委派到場景中的TestObject
}
================================

之後在任一地方都可以用GameSingleton.TestObject讀取到場景中的該物件!!

2012年8月26日 星期日

Real Escape 場景3D分享


Real Escape 場景 基本上不是一個很難的3D
值得一提的是
一開始貼圖沒優化,效能極差
由於我想要效能好,
3D模型貼圖重整好幾次
以下是調整的細節

1.模型的面數只有約6000


































2.整個場景沒用到任何燈光,而是用LightMap取代

























3.另外在網上找到一個模型只用一個Shader的效能較好




Real Escape 創作概念


我來介紹一下這遊戲
















如同遊戲名稱,一目了然這遊戲就是個"真實"的密室脫逃遊戲
基本上我不是個密室脫逃遊戲迷
只是我覺得密室脫逃遊戲很適合做出"真實"的感覺


Real1
我運用iPhone/iPad的陀螺儀,讓遊戲可以隨著玩家的旋轉而改變鏡頭

















Real2
要讓玩家能更融入整個情境,所以我選擇恐怖風格,整體風格參考Silent Hill

















Real3
謎題儘量設計的"真實",符合邏輯,當然只能盡量,如果完全符合邏輯應該很難設計謎題
















Real4
遊戲中的提示有精心設計過,當你卡住時,可以按右上角的頭腦回憶,回憶會有三種結果,得不得到提示完全憑運氣
1.得到有用的提示
2.想到之前發生的事
3.完全想不到東西

Real Escape 創作分享



想要做一種新體驗的遊戲,在這樣的想法下,產出我第一個ios App

從剛開始只有自己很熱,到中間一直被澆息熱情,最後無論如何還是要把它做出來,讓我體會到,做一個遊戲真的要有耐心,信心和決心

我是第一次做ios App
剛開始完全不知所措,因為我只會3D與Flash
本來想把程式外發,但是外發程式應該會做不到我想要的水平
第二個想法是學IOS的原生程式,我買了二本很厚的書,看沒二頁就放棄了,
畢竟要用IOS的原生程式寫3D這不是一個人可以做的事,
最後找到了unity3D,那時台灣應該還沒很流行,市面上也只有一本很淺的書
決定用它最主要有以下幾個原因:
1.當然是因為他免費(這個軟體商行銷方式真的不錯,先讓軟體免費而達到普及,再用Pro或轉到其他平台來收費)
2.他的界面與MAYA大致相同,連快捷鍵也差不多,好上手
3.程式方面我使用的是javaScript,程式語法貼近Flash As3

當然程式方面我剛開始還是寫得很痛苦,畢竟當時台灣還不是很普及,中文資料不是很多,我英文又不好
最痛苦的是陀螺儀的程式,unity3D沒有內建
我翻遍所有的中英文資料,才找到外掛 Prime31 DeviceMotion http://prime31.com/unity/
又花了二個月才完整了解陀螺儀概念,一度我還以為我寫不出來了><"

在行銷方面:
畢竟是第一個案子,我們天真的拍了一個宣傳影片,想要用另類搞笑的手法來讓宅男注意到這個遊戲
這個影片只花了5萬元(包括演員,道具,攝影),剪接與特效我們自己來
我是覺得整體感還不錯,就是不夠B級,沒達到病毒的效果


遊戲上架後的結果:
台面上的結果看起來還不錯,台灣的AppStore有二天是付費不分類第一,日本也有衝到遊戲類前15
但營收卻比想像差很多,讓我有點失望
幸好有很多人對這個遊戲給予很高的評價,還有人說這是他玩過最好的密室脫逃遊戲

大部份的負評都是整個故事太短
在此我對覺得遊戲太短的玩家說聲抱歉
畢竟開發人力有限(大多都是我一個人)
我覺得如果人力有限寧願遊戲短但是精緻,有趣,細節多
也不要遊戲長但是粗糙,一看就不想玩

試著把自己關在房間把燈關掉,玩這個遊戲
透過iPhone/iPad看出去,想像自己被關在密室
我想賣的就是這種遊戲的體驗!!

2012年8月17日 星期五

實踐 unity event listener for javaScript And C#

我上網找過許多的資料,基本上javaScript 實踐 event listener 有困難,必須搭配C#
以下是我測試成功的結果


EventManager.cs  (放於Plugins資料夾裡)
===================================


using UnityEngine;
using System;
using System.Collections.Generic;
using System.Collections;

public class EventManager : MonoBehaviour{
public static event Action<string> TestEvent;
public static void TestEventError(string error){
 if( TestEvent != null )
  TestEvent(error);
 }
}


===================================



TestEvent.js
===================================


function Start () {
 EventManager.TestEvent += onTestEvent;//偵聽事件
 EventManager.TestEventError("Message");//傳送事件,可於任何地方
}

function onTestEvent(error:String){
 print(error);
 EventManager.TestEvent -= onTestEvent;//取消偵聽事件
}



===================================


2012年5月1日 星期二

Unity 也能做2D Game (ex2D)

一直很苦惱,學了Unity 3D但是卻想做2DGame,因為不是所有Game都適合作3D ><"
苦搜了很久找到這個外掛ex2D (http://www.ex-dev.com/ex2d/) 
不貴喔~~建議在官網買 只要25美金!

要升級至Unity3.5以上喔!!不然是無法使用的!!
待我研究一下再上來分享囉~~

2012年4月10日 星期二

使用 #pragma strict

簡單的在腳本頂部添加#pragma strict。
然後,unity將在腳本中禁用動態類型,強制使用靜態類型,如果一個類型未知。
Unity將報告編譯錯誤。那麼在這種情況下foo將在編譯時產生一個錯誤:

#pragma strict
function Start (){
     var foo = GetComponent(MyScript);
     //會出錯,必須改為 var foo:MyScript = GetComponent(MyScript);    
     foo.DoSomething();
}

公開變數、私有變數與全域變數

1.一般var的變數或public var 都是public(公開變數),是指從別的腳本也可以控制該變數
2.如果前面加上private為私有的變數,外部的腳本也讀不到
3.前面加上static為全域變數

創造了一個變數,名為someGlobal
// 'TheScriptName.js'
中的一個靜態變數
static var someGlobal = 5;

//
你可以在腳本內部像普通變數一樣讀取它
print(someGlobal);
someGlobal = 1;

也可以從另一個腳本讀取它,你需要使用這個腳本的名稱加上一個點和總體變數名。
print(TheScriptName.someGlobal);
TheScriptName.someGlobal = 10;

尋找物件的方法 各種的Find

尋找物件的方法有很多種
這邊我介紹幾種常用的

GameObject.Find("name");  //用名字尋找GameObject子物件
GameObject.FindWithTag("Tag");  //用Tag尋找物件(第一個物件)
GameObject.FindGameObjectsWithTag("Tag");  //用Tag尋找物件(全部物件)
Resources.FindObjectsOfTypeAll(typeof(colliderTest)) //尋找Objects

1.GameObject.Find
用名字尋找GameObject子物件
假如你的物件層級如下:





















腳本附加到theObject的物件裡

function Awake(){
      //取得 GameObject下的Capsule物件
      var Capsule:GameObject;
      Capsule=GameObject.Find("Capsule");
      print("Find="+playerer.name);

      //取得 GameObject下的Cylinder物件
      var Cylinder:GameObject;
      Cylinder=GameObject.Find("Cube/Cylinder");
      print("Find="+Cylinder.name);
}

2.GameObject.FindWithTag
新增Tag
















新增一個名稱叫 Tag

須先將GameObject加入Tag











於任一個GameObject裡加入腳本
可找到有Tag的物件,
function Awake(){
       var tagObject:GameObject;
       tagObject=GameObject.FindWithTag("Tag");
       print("FindWithTag="+tagObject.name);
}
如果同時有很多物件都是相同的Tag,FindWithTag只能找到第一個

3.GameObject.FindGameObjectsWithTag
如果想找到所有Tag的GameObject,必須使用FindGameObjectsWithTag
用法如下
function Awake(){
       var tagObject:GameObject[];
       //FindGameObjectsWithTag取得的是個GameObject陣列
       tagObject=GameObject.FindGameObjectsWithTag("Tag");
       //取得有幾個GameObject有"Tag"
       print("FindGameObjectsWithTag="+tagObject.Length);
       //取得所有GameObject有名稱
       for(var i:int=0;i<tagObject.Length;i++){
              print("FindGameObjectsName="+tagObject[i].name);
       }
}

4.Resources.FindObjectsOfTypeAll
使用Resources.FindObjectsOfTypeAll找到所有具有相同類或腳本名稱的物體

function Start(){
       //找尋Test這個腳本
       var TestObj:Object[]=Resources.FindObjectsOfTypeAll(typeof(Test));
       print(TestObj.Length);
       for(var i:int=0;i<TestObj.Length;i++){
              //我在Test裡加了一個Get_GameObject()的function 會回傳該腳本所屬的GameObject
              print(TestObj[i].Get_GameObject().name);
       }
}

2012年4月9日 星期一

關於OnTriggerStay

OnTriggerStay() 主要是用來知道觸發器碰到那些Collider
最常用的用途是射擊遊戲的子彈會碰到哪些敵人的Collider

首先相關的GameObject必須要有Collider這個屬性
作為觸發器的GameObject必須把 "Is Trigger"的屬性打開










於觸發器加入一個腳本 colliderTest.js

function OnTriggerStay  (other : Collider) {
        print(other.gameObject.name);
}

可判斷該觸發器碰到哪些Collider,再取得該物件的名字



如果想要碰觸到物件裡的某個腳本

function OnTriggerStay( other : Collider ) {
        // 於其他碰撞GameObject加入OtherScript
        // 取用OtherScript裡的DoSomething Function
        // 因為有可能OtherScript只加在幾個GameObject裡
        // 所以我們家上判斷碰到的GameObject必須有OtherScript
        if (other.GetComponent(OtherScript)) {
                other.GetComponent(OtherScript).DoSomething();
        }
}

theUnity3D部落格開張囉~~


theUnity3D部落格開張囉~~
這是一個分享討論Unity3D程式與功能的地方!!