2012年12月13日 星期四

AE Expressions教學

原文來自這裡

中文教學主要是翻譯至JJ Gifford 網站, 內容較舊(AE 5.0), 所以做了些修改, 但expression及script部分沒什麼變化.

Expressions(表達式)介紹

After Effects的動畫元素大約有5種方式

  1. Brute Force(暴力):直接在圖層設定keyframe, 自由度最高,但遇到複雜動畫時也最辛苦.
  2. Pre-composing(合成):將多圖層合而為一, 轉成一個Comp屬性的圖層, 有如其他程式的群組關係.
  3. Parenting(父子關聯):圖層間建立父子連接關係, 對父物件所做的變形, 會作用到子物件.
  4. Expressions(表達式):依附在圖層的特性(property)中,是Realtime(即時的)且live(存在的), 不同時間產生不同反應, 也可以與現有的Keyframe合作.
  5. Script(腳本):不同於Expression必須依附在圖層特性中,Script可獨立存在, 以視窗等獨立介面呈現, 一次性執行完畢, 產生結果.
        
何時使用Expressions
  1. 不同圖層間的特性連接
        例如兩個圖層間以建立父子關聯,綠色方塊為父,黃色方塊為子,parenting時,黃色跟著綠色做變化;
        但有時只需要跟隨位置,所以不需建立父子關聯, 僅用expression取得綠色的position(位置)特性.
  2. 自動化
        例如底下只需讓一個特性Scale做變化,僅僅設定一個keyframe,再加上以時間做參數的expression.

  3. 特性加入一些亂數
        在原有的keyframe作用的情況下,利用expression讓原先值做變化,如底下的position加入wiggle晃動.


何時不需要使用Expression?


     有一句話"不要以為有了槌子,就把每樣東西當作釘子",這句話的意思是說不要以為expression很厲害,就一直用,應該是需要用的時候才用.


撰寫Expression

選擇要加入expression的特性後,


1.從選單中Animation>Add Expression,將特性轉成expression模式
2.Alt+左鍵點擊碼表圖示.

多出來的"=",點擊可開關expression功能, 特性數值成紅色表示啟用expression, "="旁邊的圖式稍後討論, 最右邊的 tansform.rotation 為expression程式碼.

  • 第1個圖形鈕用圖形顯示expression計算後的結果.
  • 第2個的螺旋圖按鈕,用於幫忙抓取此Composition(也稱Comp,是一個放圖層的容器; Comp中也可放入Comp屬性的圖層)中,所有可用的特性,並轉成expression程式碼,就不需要自己打字.
  • 第3個箭頭圖按鈕,提供expression中的函式庫.



什麼是Expression?


    在一個圖層特性中,最簡單的expression就是一個值(expression的分號可有可無),如
6;
    這可能沒啥作用,若是底下這樣可能還較有用.
rotation;
    當執行時,會得出圖層的rotation值,若將這rotation表達式用在opacity特性中,圖層旋轉時,不透明度opacity也會跟著變化.

    Expressions用JavaScript語法,網路上有很多資料可查詢.JavaScript功能相當齊全,例如opacity可做一些數學運算.
opacity*10;
    上式只是將圖層的opacity乘10,若opacity是100,則得出1000,若將這表達式用在rotation,則圖層旋轉1000度.


"="在哪裡呢?

    比如在position中加入expression, 直接輸入[100,100],將圖層移至座標 x=100,y=100 位置,也可以用語法
position=[100,100];
    但若只輸入100,會發生錯誤,所以只要數值格式正確,是不需要'='.


一個expression只能控制一個特性

    例如在position中加入expression,這個expression只能操作位置特性,如果想在裡面操作rotation辦不到的;若要操作rotation就在rotation特性中加入expression.

Expression可以多行程式碼

    之前都只看到一行, 然而幾百行都可以, 但是expression不是AE的Script, 行數越少越好, 總不能每移到不同時間, 幾百行的expression又執行一次, 盡量簡單.以下是rotation的expression範例.
offset=30;
ralph=rotation+offset;
ralph;
    offset是變數,程式碼中rotation是旋轉特性初始值,如果初始值為0,那加上30,所以ralph變數成為30,最後結果是30,圖層則旋轉30度,(拉黃色邊框調區塊大小)


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


螺紋選取工具

    按住螺紋按鈕, 再移到要取用的特性(屬性)文字上, 放開滑鼠左鍵即取得該特性的expression表達式



    這表示Opacity(不透明度)的將取用transform.rotation的值, 因為都是同一個圖層(物件)中的特性, 直接輸入rotation也起作用.

opacity跟隨rotation變化

    如果您抓取的是同個comp中的不同圖層的特性, 如下, 記得先選取要被取代的文字(藍底白字).


thisComp.layer("Yellow Solid 1").transform.opacity

thisComp : 表示目前所在Comp
layer("Yellow Solid 1") : 此Comp中的名為Yellow Solid 1的圖層.
transform.opacity : 表示Yellow Solid 1的 transform群組特性中的opacity特性.

    若您改成這樣也可   thisComp.layer("Yellow Solid 1").opacity

Vectors, Arrays, Dimensions 與 Indexing

    當你用螺紋從position連到rotation後, 會得到兩行程式碼(根據版本會有不同).

    因為position必須用到x,y座標值, 所以不管程式幾行, 最後一行都必須求出 2維數值,上例用
[temp,temp]表示. 這二個或多個數值資料的組合稱為vector(向量)或array(陣列) .


Vector vs Array

    Vector向量是數值的組合, 2個值是2維向量,如

[3,4] 

    3個值是3維向量,如

[3,4,5]

    Array陣列是多個資料的組合,如

ralph=[10, thisLayer, "bob"]

    ralph變數裡面就有整數值 10 , 圖層 thisLayer , 字串 "bob". 順便一提, 正常用法是不會將不同型態值放在同一陣列內.

    說白了Vector也是一個Array, 只是意義不同.


Indexing(索引)

    有如在一個陣列內取得某個資料, 如

position[0]

   從圖層的position特性取得位置0, 也就是第一個資料, Javascript的陣列從0開始, 所以0表示第一個.

    position是xyz座標值, 所以第1個也等於x座標值,

    position[1] 等於y座標值


建立陣列

    建立一個3維空間向量給變數myVector

myVector = [10,20,30]

    myVector[1] 得到20


Dimensions維度

    陣列內的數值數目等於它的維度, 如上方的myVector 是3維.  一般圖層的position是2維, 但若轉成3D圖層就是3維position. 圖層的rotation與opacity是1維,也稱純量(scalar).

修改陣列內的元件

    例如 positio特性可寫成

[position[0], position[1]];

    這是將position的第1及第2個值取出來, 再放入 position特性內, 結果等於直接寫 position , 這用意是說可以取用或修改陣列內的某個元件, 如下

top_of_layer=0;
[anchorPoint[0], top_of_layer];

    若將以上寫入圖層anchor point(錨點)特性中, x軸不會變, 因為是取用自已anchorPoint的x值, 但是y軸會往上移到0位置.

    上面範例是2維, 當轉成3維圖層, 若你沒補上第三個z值, AE會自動判斷z為0

    下面例子假設你複製comp內最上方第1個圖層的position到某個圖層位置, 並修改y值,

ralph=thisComp.layer(1); //將comp內第1個圖層指定給變數ralph, 切記 layer(1) != layer[1]
[ralph.position[0], ralph.position[1]-100];

    若2個圖層都轉成3D, 移動第1個圖層時, 發現第2個只跟隨第1個的xy值, 因為z軸不受expression制約. (加上camera後做圖層移動,camera不要放在最上方第一個位置)

了解陣列很重要

    例如

position = 6;

    AE會警告這是錯誤, 因為position必定是2維或3維, 不能給1維數值.

position=[320,240];

以上正確!

以下是一些圖層常用的特性(參數)資料表
圖層特性維度單位範圍一般範圍
anchorPoint2* [x, y, (z)]pixels±無限0–圖層寬高
position2* [x, y, (z)]pixels±無限0–comp寬高
scale2* [width, height, (depth)]percentage±無限±100
rotation1degrees±無限0–360度
opacity1percentage0–1000–100
orientation (只有3D)3 [x, y, z]degrees±無限0-360度
audioLevels2 [left, right]decibels-192–24-48–12
ambient1percentage0–1000–100
diffuse1percentage0–1000–100
specular1percentage0–1000–100
shininess1percentage0-1000-100
* 當圖層是3D時,就是3維

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




調整值的範圍

    例如第一頁教學中的用rotation來變化opacity, opacity值的範圍是0~100; 但rotation是正負無窮大.

    以轉1圈360度來說, 100度以上opacity就不作用, 若想要完整轉一圈來變化opacity全過程, 需做一些數學運算,

rotation / 360 = opacity / 100 

   上式 rotation等於0時, opacity也等於0 ; rotation為360時, opacity為100

    上面程式碼再做一些變化得到下面的程式碼, 求opacity 的運算式, 其中rotation/360的值介於0~1, 那0~1之間的值乘100, 所求得的值為0~100之間. 合乎opacity範圍

opacity =(rotation / 360) * 100  //括弧()可省略, 加上是為了清楚運算順序



同以上的理, 下方例子中

圓周長:circumference
距離:distance

    rotation是根據所走的距離(最長距離等於圓周長度), 來判斷旋轉度數.

    distance/circumference的值會落在 0~1 之間, 再用此值去乘360, 最後所得值範圍必定為 0~360

    為了使輪胎轉動, 所以 expression要放在rotation特性中, rotation 是被 position 所驅動.

    一開始 expression 可能會如下

rotation=position*?  //執行會出現錯誤, 因為還要替? 輸入正確變數, ?只是暫時代替

    要做水平方向移動才能看到輪胎旋轉, 所以取用position的x值 position[0] 來計算輪胎圖層跑多少距離, 輪胎是從comp的左邊移到右邊, 起點跑設定在comp的最左邊(comp的座標是左上到右下), 程式碼如下.

rotation=position[0]*?

    為了讓輪胎完整轉1圈, 所以要跑相當於1個圓周長距離, 轉1圈是360度. 根據所跑距離是圓周長的多少比例, 用相同比例的值來判斷輪胎轉幾度.

rotation=(position[0]/circumference)*360 //括弧()可以省略

    輪胎越大, 圓周長度越大, 圖層就必須移動越遠才能轉一圈, 現在要來定義圓周長度,

diameter是直徑, 圓周長公式 diameter*PI

    以前學校學的圓周長公式是2*π*r , r是半徑, 2*r是直徑 , π是圓週率(圓周長與直徑的比率,不變的值), javascript中以PI表示, 必須用 Math.PI 來存取, 或自己輸入3.14 , expression如下

circumference=width*Math.PI;   //width是輪胎寬度(直徑), 等於2*r(半徑)

    因為是用於rotation特性中, 所以之前的expression程式碼

rotation=(position[0]/circumference)*360

    可以刪除rotation=

    最後做全部程式碼整理, 得到

distance=position[0];
circumference=width*Math.PI;
distance/circumference*360;

    應用此expression時, 圖層scale特性必須是100%, 若有改變要另外處理, 留給讀者自己思考.

     上述效果當然也可手調, 但是若要做加速或減速時, 調不好輪胎會打滑, 還是用expression比較準確與真實.


範例檔下載 MAC Window

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Interpolation Methods(內插函式): linear(), ease()

    前面的教學, 已經知道藉由合併簡單的除法與加法來"手動"調整值的範圍. 我們也可以用同樣的方式轉換360度旋轉特性作用到opacity特性上. 但這不是唯一的方式, 因為AE提供內建的內插函式, 特別設計用來做某個特性中(如opacity)的一組數值的轉換.
linear(t, tMintMax, value1, value2)
ease(t, tMintMax, value1, value2)
ease_in(...), ease_out(...)
    這些函式看起來很複雜, 其實只是參數比較多而已, 這些參數是
t變數名, 但輸入值必須是1維的值, 例如rotation或time變數
tMint的最小值,可以省略.省略時,預設為0.
tMaxt的最大值,可以省略.省略時,預設為1.
value1此函式輸出的最小值. 當t等於或小於tMin時, 以value1值輸出. value1可以是數字或向量
value2此函式輸出的最大值. 當t等於或大於tMax時, 以value2值輸出. value2可以是數字或向量

    舉個例子
linear(time, 0, 5, 0, 360);   //time是comp中的內建變數,秒為單位

    根據字面解釋: 當time變數值(時間)從0 ~ 5, 以線性計算出0 ~ 360之間的值. 若將此expression運用在圖層的rotation特性中, 圖層會在0秒~5秒間旋轉360度.
到第5秒停止旋轉

    如果使用這行程式, 會在第五秒自動停止旋轉. 與上一個教學所講到的技術最大不同是, 本次程式在第五秒自動停止, 前次的教學是一直執行下去(若要停止,必須在加上程式碼).
一直旋轉


    除了linear()之外, 還有ease(), easeIn() 及 easeOut()等內插函式. 使用這些函式來計算出更自然的效果.
  • linear() : 中間自動產生的內插值, 以線性方式變化.
  • ease() : 起點與終點變化較緩慢.
  • easeIn() : 緩慢離開起點.(寫成ease_in 也可)
  • easeOut() : 緩慢到達終點.(寫成ease_out 也可)

範例:捲動軸動畫

    這裡將建立一個簡單的捲動軸動畫, 先建立二個圖層, 一個捲動軸(右邊小方塊)圖層(左右兩條垂直線也是圖層,可忽略), 一個文字區塊圖層. 文字圖層的anchor point(軸心)將加入expression (若加在position, position就被封住) ,這樣排版時我們還可移動文字圖層的position, 但position基本是不動, 因為要驅動的是捲動文字圖層的anchor point.

    必須記得, anchor point的值變化與圖層移動是相反的. 在這個例子, 要將文字圖層的anchor point往下移動, 所以文字會往上移動. 為了捲動完所有文字, 必須讓anchor point的y軸數值從0變化到文字區塊的高度值, 所以變數設定成

value1 = 0
value2 = height

    其他變數tMin , tMax , 可以設定為0 及 所在comp的高度. 為了外觀好看一點, 可以做些修改, 假設尺寸為 320x240. 我們設定使用範圍從 20 到 220. 所以設定捲動軸的y軸值為

tMin=20
tMax=220

    所以捲動軸的y座標值為linear函式的輸入值. 得到以下程式碼

scrollY = thisCom.layer("Scroll").position[1];
scrolledAmount = linear(scrollY, 20, 220, 0, height); //捲動多大範圍

    最後將這結果scrolledAmount放入座標陣列中, 讓anchor的x軸的值不變, 完整的expression如下.

scrollY=thisComp.layer("Scroll").position[1];
scrolledAmount=linear(scrollY, 20, 220, 0, height);
[anchorPoint[0], scrolledAmount];

    最後的動畫如下, 右邊小方塊是捲動軸 thisComp.layer("Scroll") , 它的y軸值將讓文字區塊移動.

    當然上例是需要垂直捲動. 我們也可建立水平捲軸, 用x軸值來驅動. 更可延伸到3D旋轉捲動, 加入expression到 3D圖層的rotation特性中.

水平捲動
3D旋轉捲動

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  我們之前使用螺旋紋建立簡單的Expression, 但是只能選擇畫面中存在的物件及其特性(屬性), 例如Comp的特性frameDuration就無法選擇,因為它不存在於畫面中.

什麼是物件

    物件就是一個容器,裡面可裝其他物件與特性,以及函式.

   例如Comp就是AE的一個物件, 裡面包含其他物件(圖層)或是Comp本身的特性,如duration(時間)或width(寬度)等. 在AE中有物件:Comp,layer...等,及特性:opacity,duration,width...等

全域物件(Global Object)與全域特性(Global Atttribute)

    不需定義,直接取用
全域物件與屬性物件種類
thisLayer燈光,影像,聲音 或 攝影幾等物件
thisCompComp 物件
comp("name")Comp 物件
footage("name")Footage 物件
timeNumber 屬性
valueNumber 屬性


    舉 thisComp 為例:
thisComp.layer("Solid 1") 可以取得目前Comp裏面,名為"Solid 1"的layer.

    還可接著往下取得特性, 例如layer圖層的rotation.
thisComp.layer("Solid 1").rotation

    thisComp是全域物件,layer("Solid 1")是裡面的一個layer,此expression取得該layer的rotation特性.

    可用拉螺旋紋到Solid 1的rotation, AE直接填入expression.
有transform是正規寫法,但也可忽略

    用螺旋紋時要小心,expression的欄位游標要放對, 或是被取代的字串也要選對. 底下是layer的常用特性;

圖層特性與函式值的類型維度單位
width 寬度Number1pixels
height 高度Number1pixels
startTime  圖層開始播放時間Number1seconds
inPoint  圖層啟用時間Number1seconds
outPoint 圖層失效時間Number1seconds
hasVideo 是否有影像Boolean1Boolean
hasAudio 是否有聲音Boolean1Boolean
active 是否顯示Boolean1Boolean
audioActive 聲音是否開啟Boolean1Boolean
audioLevels 聲音層數Property2 [left, right]decibels
index 圖層索引值(第幾層)Number1Number
parent 父物件Layer, Light or Camera
source 來源(指向poject面板)Comp or Footage
mask(index or name) 遮罩Mask
effect(index or name) 特效Effect

存取圖層特性的小例子


預設物件

    如 thisLayer, 你可以不需寫 thisLayer.opacity, 直接寫 opacity, AE會自動參考用這個 opacity 的 layer.

    但若要存取其他 layer 的 opacity . 必須加上其他 layer名稱及 thisComp, 也就是用螺旋紋直接連.


方法(Method,中文或稱函式)與特性(Attributes)
  • 方法(Method) : 是一組內部運算,最後得到值, 如 valueAtTime(time);
    有括弧的都是"方法"
  • 特性 : 就是一個值, 如 width, opacity...


以 opacity的valueAtTime 為例
thisComp.layer("Shape Layer 1").opacity.valueAtTime(time)
    time 是全域特性, 是時間軸的所指的時間, 以秒為單位, time作為輸入參數, 用來取得Shape Layer 1圖層的opacity 在 5秒5 的值, 如圖是52.01... , 並將此值以字串顯示在工作視窗.

2012年12月4日 星期二

2012 高雄電影節

國際瘋短片IV我在世界的中心
蒙哥馬利克里夫的愛與死 Postface - 2011 菲德瑞克莫菲
人生八十才開始 Eighty Eight - 2011 喬許班福德、聖巴斯堤恩菲翰
甜蜜十四歲 Lambs  - 2011 山姆凱利
塌塌米之味 Engawa-Sunny Veranda - 2012 古新 舜
三月六日 6th March - 2011 黃進
噪音乍洩 Noise - 2011 奇傑克、亞當斯基
浮生烽火 In The Encirclement - 2012 卡倫沙赫納札羅夫

綠色瘋短片II魔幻視界
小蘿莉冒險工廠 Ephemeral - 2012 狄亞哥蒙迪諾
尋愛馬戲熊  Ursus  - 2011 瑞尼斯比得森
二手奇蹟 Second Hand - 2011 艾薩金
越過死亡線 Angst - 2012 里昂瑞奇
小強謀殺案 A Little Suicide - 2012 安娜莉莉阿米波
生命之重 Heavy of life - 2012 郭宗福
燈泡愛情故事 Luminaris - 2011 璜薩拉米拉
里歐!好神奇的發明 Gloop - 2011 嘉比巴斯堤拉、喬奇曼


Particles Tutorial

2012年11月28日 星期三

2012年11月13日 星期二

Origami

眉毛變形



1.     準備一個要合成的背景影片(追蹤點於眉毛上方,好覆蓋),一個動眉毛的合成影片(追蹤點於臉頰)

2.     背景影片進mocha中追蹤。鋼筆圈取要替代的眉毛位子> Run過 > Track視窗 > Export Tracking Data…中 > AE CS3 Corner Pin…(*.txt) > Copy to Clipboard


3.     將收起的AE打開,Control+V在新Null。追蹤點復製上

4.     合成影片要將魯動眉毛取下貼在背景影片上。新增Comp給合成影片,Track視窗 Stabillize Motion 穩定追蹤,將影片以眉毛為中心點調整影片晃動 > Tracking臉頰上的左右追蹤點 輸出為新影片。


5.     >Mocha > 開啟調整過的合成影片 鋼筆圈起要取下的眉毛部分 > Track視窗 > Export Shape Data…> mocha shape data for AE > Copy…

6.     >AE,新增Solid > Control+V >  合成影片Alpha Solid


7.     Face Blur Alpha出的眉毛,讓邊緣柔化。合上背景影片(為了取下眉毛上方皮膚的情況)

8.     額頭跟眼睛沒跟著合成影片的眉毛變化,增Mesh Warp至背景影片上,調整眼臉的一至度。

9.     鋼筆圈下調整過的背景影片眉毛附近的皮膚(魯動眉毛素材)

1.  眉毛素材Comp和背景影片合成,素材要覆蓋原有的眉毛 眉毛Comp 右鍵 > Time > Enable Time Remapping 在保留段(合成好的Key > 語法 > loopOut(“pingpong”)  > 移動素材覆蓋原有眉毛 微調(可重複將眉毛素材Pro-Compose>Enable…的動作)

2012年11月3日 星期六

John Truby 系列


文章來自:AnimApp.tw

解剖故事

如何發想故事

 John Truby 說:
在寫作最初期,開始發想故事時,先問自己這兩個問題:
1. 這個故事的系統是什麼? ( 例如: 教父是幫派系統 / 哈利波特是魔法系統 )
2. 系統中的不同規則,用哪些角色代表?
代表系統的角色最少要四位。為什麼是四位? 因為,組成一個社會體系最少要四種觀念 (規則)。每個角色都代表一個觀念。這四位是由一個主角與三個對手所組成。但要注意,四個角色是在互相抗衡的,而不是主角在對抗整個系統。整個系統是不存在的。它只是由不同觀念的角色所組成。
我稱這為「四角抗衡」(four corner opposition)。我們先看傳統的「兩角抗衡」,其實就是大家熟悉的 - 主角 vs 反派 - 故事。這種故事只有兩人之間的衝突。但「四角抗衡」有四邊、與對角線之間的衝突。這代表什麼? 更多的劇情變化。
除了角色之間有衝突,他們所代表的觀念也可以有衝突。所以,盡可能讓每個角色個性、理念都不一樣。把他們推到正方形的四個角。不要寫一個角色都很像,擠在正方形中間的故事。


把大綱變劇本

 John Truby 說:
大綱寫完後,最艱辛的步驟是,把大綱變成 120 頁的劇本。但這其實不難,重點是要找到 - 角色變化的曲線 - 它很重要,像劇本的脊椎一樣,支撐整個故事。
接下來,開始寫劇本時,你的故事會經歷七個步驟。任何故事,不管是電影、30秒廣告、小說,都會經歷這七步。這跟我們常見的三幕劇不一樣。這七步對創作人來說很有幫助,因為它已經存在故事中,你要找到它們,讓它們幫你說你想說的。
七步的第一步: 找到角色的「渴望線」 (desire line)。這步很重要,因為整個故事將掛在這條線上。渴望線是:「你主角想要的東西」。角色從 A 到 B 追求的目標,這也是我們俗稱的「線性故事」(linear story)。不管你是哪個種族、或國籍都會很好了解,因為它本質就是個追求成功的故事。
關於「渴望線」有三個重點:
1. 「渴望線」越「具體」越好。觀眾要很清楚知道主角達成目標了沒。
2. 「渴望線」要從「頭」走到「尾」,不能在「中間」停。故事在中間結束,新的故事必須從「中間」開始。不建議一個片子有兩個故事。
3. 「渴望線」不是主角「生活」中想要的東西,而是主角在「這個故事」中想要的東西。「搶救雷恩大兵」的故事發生在二戰,那時誰不想回家。但主角的「渴望線」不是想回家,而是「搶救雷恩大兵」。
關於「渴望線」的最後一點,主角必須要「非常想要」這個目標,幾乎到「癡狂」的境界。為什麼? 主角沒有:「非常想要」,觀眾就:「不會在乎」。


如何讓觀眾在乎角色?


問: 很多電影花大錢做漂亮的畫面,但觀眾看來看去,根本不在意劇中角色的死活,連對主角一點興趣也沒有。我想問: 到底要如何讓觀眾在乎角色?
答:讓觀眾在乎角色我相信許多人都聽過,也試著做過。但他們都會犯一個錯,他們認為,給角色越多細節,越多特徵,觀眾就會在乎。但這不是個好方法,因為這些特徵都是非常「表面」的東西。
要讓觀眾在乎角色的方法有兩種:
1. 弱點 (weakness) - 找出主角內心深處,一直在傷害他,幾乎要毀掉他人生的東西。這是很「內心」的東西。( 細節、特徵都是很「表面」的東西 ) 你的故事就是在講主角解決這個問題的旅程。而解決這個問題的方法,就是去追尋他的目標。
2. 目標  (goal) - 角色一開始可能不知道,在他追求目標的過程中,會跟他的弱點面對面。如果是個好的故事,就會有這樣的安排。
劇情來自角色 (plot comes from character) 我相信許多人也都聽過。但他到底是什麼意思? 意思是主角在追求他目標的過程中,會迫使他改變自己的弱點,這樣劇情就會由這個角色的內心深處而生。

扭轉你的類型片


很多人都低估了鐵達尼號的劇本,我認為它的劇本非常棒。鐵達尼號算是個災難片。 (disaster picture) 許多災難片都不太成功。因為它一開始會一下介紹很多角色,在還不太認識他們時,災難就突然發生了。鐵達尼號不一樣,它一開始是個愛情片,這讓觀眾在故事的前半段真的認識到,也很在乎男女主角,然後故事到中後段災難才發生。這時,觀眾已經跟男女主角產生強烈的連結,會很替他們的安危擔心,很容易就被捲入故事中。
我也很喜歡史瑞克的劇本。近年來,很多很棒的劇本都來自動畫片。史瑞克除了是部有趣的動畫片,也是部偉大的愛情片。它的故事是從一個不相信愛情的人開始講起,很多很棒的愛情故事都是這樣開始的。 



劇情不好寫

許多人以為想好角色、大綱、主旨,寫劇情時就會一帆風順。其實有 90% 的人死在劇情 (plot) 上。這裡有兩點可以幫助大家寫劇情。第一點: 把注意力放在「對手」(opponent) 上。大家一定聽過這句話: 讓「主角」驅動故事。這句話說的沒錯。但這是觀眾經歷劇情的方式。創作者發想劇情的方式是從「對手」開始的。因為「對手」才是提供故事驚喜、反轉、爆點的人。記得: 「劇情來自驚喜」。(plot is based on surprises)
第二點,永遠把「對手」想成一座冰山。冰山通常只露一角,他之所以危險,是因為有很多你看不到的地方。記得這個守則: 「對手有越多你看不到的地方,你就有越多劇情可寫,越多爆點嚇觀眾和主角」


「假盟友」、「假敵人」很重要

「假盟友」(fake allies)、「假敵人」(fake foes) 我稱為「中間型角色」(in between characters),徘迴在「主角」跟「反派」立場「中間」的角色。「驚喜」是劇情中非常重要的元素。劇情除了要能嚇到觀眾,也要能嚇到主角。要如何嚇哪? 用「中間型角色」來嚇。一開始以為是敵人,最後原來是盟友! 一開始以為是盟友,最後竟然是敵人! 哈利波特作者 J.K. Rowling (羅琳) 很會玩這招。Snake 是壞人嗎? 不,它是好人。不對,它又變壞人了。這樣的劇情觀眾超愛的。

雙重反轉

雙重反轉 (double reversal) 是指主角與反派都同時有變化的故事設計。在電影「美國黑幫」( American Gangster) 中就有這樣的設計。主角與反派在結尾時像是互換角色一樣,他們互相從對方身上學到東西。這樣的設計在愛情故事中最常見,當故事走到終點時,男女主角會相互學西,兩人都會有所成長。