@ -15,7 +15,6 @@ namespace Fungus
public Sprite portrait ;
public Sprite portrait ;
public RectTransform position ;
public RectTransform position ;
public FacingDirection facing ;
public FacingDirection facing ;
public GameObject portraitObj ;
public Image portraitImage ;
public Image portraitImage ;
}
}
@ -27,6 +26,7 @@ namespace Fungus
Replace ,
Replace ,
MoveToFront
MoveToFront
}
}
public enum FacingDirection
public enum FacingDirection
{
{
None ,
None ,
@ -79,10 +79,10 @@ namespace Fungus
public bool useDefaultSettings = true ;
public bool useDefaultSettings = true ;
[Tooltip("Fade Duration")]
[Tooltip("Fade Duration")]
public float fadeDuration ;
public float fadeDuration = 0.5f ;
[Tooltip("Movement Speed ")]
[Tooltip("Movement Duration ")]
public float moveSpeed ;
public float moveDuration = 1f ;
[Tooltip("Shift Offset")]
[Tooltip("Shift Offset")]
public Vector2 shiftOffset ;
public Vector2 shiftOffset ;
@ -95,7 +95,10 @@ namespace Fungus
[Tooltip("Wait until the tween has finished before executing the next command")]
[Tooltip("Wait until the tween has finished before executing the next command")]
public bool waitUntilFinished = false ;
public bool waitUntilFinished = false ;
// Timer for waitUntilFinished functionality
protected float waitTimer ;
public override void OnEnter ( )
public override void OnEnter ( )
{
{
// If no display specified, do nothing
// If no display specified, do nothing
@ -104,18 +107,21 @@ namespace Fungus
Continue ( ) ;
Continue ( ) ;
return ;
return ;
}
}
// If no character specified, do nothing
// If no character specified, do nothing
if ( character = = null )
if ( character = = null )
{
{
Continue ( ) ;
Continue ( ) ;
return ;
return ;
}
}
// If Replace and no replaced character specified, do nothing
// If Replace and no replaced character specified, do nothing
if ( display = = DisplayType . Replace & & replacedCharacter = = null )
if ( display = = DisplayType . Replace & & replacedCharacter = = null )
{
{
Continue ( ) ;
Continue ( ) ;
return ;
return ;
}
}
// Selected "use default Portrait Stage"
// Selected "use default Portrait Stage"
if ( stage = = null ) // Default portrait stage selected
if ( stage = = null ) // Default portrait stage selected
{
{
@ -124,37 +130,51 @@ namespace Fungus
stage = GameObject . FindObjectOfType < Stage > ( ) ;
stage = GameObject . FindObjectOfType < Stage > ( ) ;
}
}
}
}
// If portrait stage does not exist, do nothing
// If portrait stage does not exist, do nothing
if ( stage = = null )
if ( stage = = null )
{
{
Continue ( ) ;
Continue ( ) ;
return ;
return ;
}
}
// Use default settings
if ( useDefaultSettings )
{
fadeDuration = stage . fadeDuration ;
moveDuration = stage . moveDuration ;
shiftOffset = stage . shiftOffset ;
}
if ( character . state . portraitImage = = null )
if ( character . state . portraitImage = = null )
{
{
CreatePortraitObject ( character , stage ) ;
CreatePortraitObject ( character , stage ) ;
}
}
// if no previous portrait, use default portrait
// if no previous portrait, use default portrait
if ( character . state . portrait = = null )
if ( character . state . portrait = = null )
{
{
character . state . portrait = character . profileSprite ;
character . state . portrait = character . profileSprite ;
}
}
// Selected "use previous portrait"
// Selected "use previous portrait"
if ( portrait = = null )
if ( portrait = = null )
{
{
portrait = character . state . portrait ;
portrait = character . state . portrait ;
}
}
// if no previous position, use default position
// if no previous position, use default position
if ( character . state . position = = null )
if ( character . state . position = = null )
{
{
character . state . position = stage . defaultPosition . rectTransform ;
character . state . position = stage . defaultPosition . rectTransform ;
}
}
// Selected "use previous position"
// Selected "use previous position"
if ( toPosition = = null )
if ( toPosition = = null )
{
{
toPosition = character . state . position ;
toPosition = character . state . position ;
}
}
if ( replacedCharacter ! = null )
if ( replacedCharacter ! = null )
{
{
// if no previous position, use default position
// if no previous position, use default position
@ -163,65 +183,68 @@ namespace Fungus
replacedCharacter . state . position = stage . defaultPosition . rectTransform ;
replacedCharacter . state . position = stage . defaultPosition . rectTransform ;
}
}
}
}
// If swapping, use replaced character's position
// If swapping, use replaced character's position
if ( display = = DisplayType . Replace )
if ( display = = DisplayType . Replace )
{
{
toPosition = replacedCharacter . state . position ;
toPosition = replacedCharacter . state . position ;
}
}
// Selected "use previous position"
// Selected "use previous position"
if ( fromPosition = = null )
if ( fromPosition = = null )
{
{
fromPosition = character . state . position ;
fromPosition = character . state . position ;
}
}
// if portrait not moving, use from position is same as to position
// if portrait not moving, use from position is same as to position
if ( ! move )
if ( ! move )
{
{
fromPosition = toPosition ;
fromPosition = toPosition ;
}
}
if ( display = = DisplayType . Hide )
if ( display = = DisplayType . Hide )
{
{
fromPosition = character . state . position ;
fromPosition = character . state . position ;
}
}
// if no previous facing direction, use default facing direction
// if no previous facing direction, use default facing direction
if ( character . state . facing = = FacingDirection . None )
if ( character . state . facing = = FacingDirection . None )
{
{
character . state . facing = character . portraitsFace ;
character . state . facing = character . portraitsFace ;
}
}
// Selected "use previous facing direction"
// Selected "use previous facing direction"
if ( facing = = FacingDirection . None )
if ( facing = = FacingDirection . None )
{
{
facing = character . state . facing ;
facing = character . state . facing ;
}
}
// Use default settings
if ( useDefaultSettings )
{
fadeDuration = stage . fadeDuration ;
moveSpeed = stage . moveSpeed ;
shiftOffset = stage . shiftOffset ;
}
switch ( display )
switch ( display )
{
{
case ( DisplayType . Show ) :
case ( DisplayType . Show ) :
Show ( character , fromPosition , toPosition ) ;
Show ( character , fromPosition , toPosition ) ;
character . state . onScreen = true ;
character . state . onScreen = true ;
if ( ! stage . charactersOnStage . Contains ( character ) )
if ( ! stage . charactersOnStage . Contains ( character ) )
{
{
stage . charactersOnStage . Add ( character ) ;
stage . charactersOnStage . Add ( character ) ;
}
}
break ;
break ;
case ( DisplayType . Hide ) :
case ( DisplayType . Hide ) :
Hide ( character , fromPosition , toPosition ) ;
Hide ( character , fromPosition , toPosition ) ;
character . state . onScreen = false ;
character . state . onScreen = false ;
stage . charactersOnStage . Remove ( character ) ;
stage . charactersOnStage . Remove ( character ) ;
break ;
break ;
case ( DisplayType . Replace ) :
case ( DisplayType . Replace ) :
Show ( character , fromPosition , toPosition ) ;
Show ( character , fromPosition , toPosition ) ;
Hide ( replacedCharacter , replacedCharacter . state . position , replacedCharacter . state . position ) ;
Hide ( replacedCharacter , replacedCharacter . state . position , replacedCharacter . state . position ) ;
character . state . onScreen = true ;
character . state . onScreen = true ;
replacedCharacter . state . onScreen = false ;
replacedCharacter . state . onScreen = false ;
stage . charactersOnStage . Add ( character ) ;
stage . charactersOnStage . Add ( character ) ;
stage . charactersOnStage . Remove ( replacedCharacter ) ;
stage . charactersOnStage . Remove ( replacedCharacter ) ;
break ;
break ;
case ( DisplayType . MoveToFront ) :
case ( DisplayType . MoveToFront ) :
MoveToFront ( character ) ;
MoveToFront ( character ) ;
break ;
break ;
@ -236,57 +259,87 @@ namespace Fungus
{
{
character . state . display = display ;
character . state . display = display ;
}
}
character . state . portrait = portrait ;
character . state . portrait = portrait ;
character . state . facing = facing ;
character . state . facing = facing ;
character . state . position = toPosition ;
character . state . position = toPosition ;
waitTimer = 0f ;
if ( ! waitUntilFinished )
if ( ! waitUntilFinished )
{
{
Continue ( ) ;
Continue ( ) ;
}
}
else
{
StartCoroutine ( WaitUntilFinished ( fadeDuration ) ) ;
}
}
}
public static void CreatePortraitObject ( Character character , Stage stage )
protected virtual IEnumerator WaitUntilFinished ( float duration )
{
{
GameObject portraitObj = new GameObject ( character . name , typeof ( RectTransform ) , typeof ( CanvasRenderer ) , typeof ( Image ) ) ;
// Wait until the timer has expired
// Any method can modify this timer variable to delay continuing.
waitTimer = duration ;
while ( waitTimer > 0f )
{
waitTimer - = Time . deltaTime ;
yield return null ;
}
Continue ( ) ;
}
protected virtual void CreatePortraitObject ( Character character , Stage stage )
{
// Create a new portrait object
GameObject portraitObj = new GameObject ( character . name ,
typeof ( RectTransform ) ,
typeof ( CanvasRenderer ) ,
typeof ( Image ) ) ;
// Set it to be a child of the stage
portraitObj . transform . SetParent ( stage . portraitCanvas . transform , true ) ;
portraitObj . transform . SetParent ( stage . portraitCanvas . transform , true ) ;
// Configure the portrait image
Image portraitImage = portraitObj . GetComponent < Image > ( ) ;
Image portraitImage = portraitObj . GetComponent < Image > ( ) ;
portraitImage . preserveAspect = true ;
portraitImage . preserveAspect = true ;
portraitImage . sprite = character . profileSprite ;
portraitImage . sprite = character . profileSprite ;
// Workaround for bug #92. Tiled switches off an internal quad cropping optimisation.
portraitImage . color = new Color ( 1f , 1f , 1f , 0f ) ;
portraitImage . type = Image . Type . Tiled ;
Material portraitMaterial = Instantiate ( Resources . Load ( "Portrait" ) ) as Material ;
// LeanTween doesn't handle 0 duration properly
portraitImage . material = portraitMaterial ;
float duration = ( fadeDuration > 0f ) ? fadeDuration : float . Epsilon ;
character . state . portraitObj = portraitObj ;
// Fade in character image (first time)
LeanTween . alpha ( portraitImage . transform as RectTransform , 1f , duration ) . setEase ( stage . fadeEaseType ) ;
// Tell character about portrait image
character . state . portraitImage = portraitImage ;
character . state . portraitImage = portraitImage ;
character . state . portraitImage . material . SetFloat ( "_Alpha" , 0 ) ;
}
}
protected void SetupPortrait ( Character character , RectTransform fromPosition )
protected void SetupPortrait ( Character character , RectTransform fromPosition )
{
{
SetRectTransform ( character . state . portraitImage . rectTransform , fromPosition ) ;
SetRectTransform ( character . state . portraitImage . rectTransform , fromPosition ) ;
character . state . portraitImage . material . SetFloat ( "_Fade" , 0 ) ;
character . state . portraitImage . material . SetTexture ( "_MainTex" , character . profileSprite . texture ) ;
Texture2D blankTexture = new Texture2D ( 1 , 1 , TextureFormat . ARGB32 , false ) ;
blankTexture . SetPixel ( 0 , 0 , new Color ( 0f , 0f , 0f , 0f ) ) ;
blankTexture . Apply ( ) ;
character . state . portraitImage . material . SetTexture ( "_TexStart" , blankTexture as Texture ) ;
character . state . portraitImage . material . SetTexture ( "_TexEnd" , blankTexture as Texture ) ;
if ( character . state . facing ! = character . portraitsFace )
if ( character . state . facing ! = character . portraitsFace )
{
{
character . state . portraitImage . material . SetFloat ( "_FlipStart" , 1 ) ;
character . state . portraitImage . rectTransform . localScale = new Vector3 ( - 1f , 1f , 1f ) ;
}
}
else
else
{
{
character . state . portraitImage . material . SetFloat ( "_FlipStart" , 0 ) ;
character . state . portraitImage . rectTransform . localScale = new Vector3 ( 1f , 1f , 1f ) ;
}
}
if ( facing ! = character . portraitsFace )
if ( facing ! = character . portraitsFace )
{
{
character . state . portraitImage . material . SetFloat ( "_FlipEnd" , 1 ) ;
character . state . portraitImage . rectTransform . localScale = new Vector3 ( - 1f , 1f , 1f ) ;
}
}
else
else
{
{
character . state . portraitImage . material . SetFloat ( "_FlipEnd" , 0 ) ;
character . state . portraitImage . rectTransform . localScale = new Vector3 ( 1f , 1f , 1f ) ;
}
}
character . state . portraitImage . material . SetFloat ( "_Alpha" , 1 ) ;
}
}
public static void SetRectTransform ( RectTransform oldRectTransform , RectTransform newRectTransform )
public static void SetRectTransform ( RectTransform oldRectTransform , RectTransform newRectTransform )
{
{
oldRectTransform . eulerAngles = newRectTransform . eulerAngles ;
oldRectTransform . eulerAngles = newRectTransform . eulerAngles ;
@ -299,6 +352,7 @@ namespace Fungus
oldRectTransform . pivot = newRectTransform . pivot ;
oldRectTransform . pivot = newRectTransform . pivot ;
oldRectTransform . localScale = newRectTransform . localScale ;
oldRectTransform . localScale = newRectTransform . localScale ;
}
}
protected void Show ( Character character , RectTransform fromPosition , RectTransform toPosition )
protected void Show ( Character character , RectTransform fromPosition , RectTransform toPosition )
{
{
if ( shiftIntoPlace )
if ( shiftIntoPlace )
@ -317,84 +371,86 @@ namespace Fungus
fromPosition . anchoredPosition = new Vector2 ( fromPosition . anchoredPosition . x , fromPosition . anchoredPosition . y ) ;
fromPosition . anchoredPosition = new Vector2 ( fromPosition . anchoredPosition . x , fromPosition . anchoredPosition . y ) ;
}
}
}
}
SetupPortrait ( character , fromPosition ) ;
SetupPortrait ( character , fromPosition ) ;
if ( character . state . display ! = DisplayType . None & & character . state . display ! = DisplayType . Hide )
{
// LeanTween doesn't handle 0 duration properly
character . state . portraitImage . material . SetTexture ( "_TexStart" , character . state . portrait . texture ) ;
float duration = ( fadeDuration > 0f ) ? fadeDuration : float . Epsilon ;
// Fade out a duplicate of the existing portrait image
if ( character . state . portraitImage ! = null )
{
GameObject tempGO = GameObject . Instantiate ( character . state . portraitImage . gameObject ) ;
tempGO . transform . SetParent ( character . state . portraitImage . transform . parent , false ) ;
Image tempImage = tempGO . GetComponent < Image > ( ) ;
tempImage . sprite = character . state . portraitImage . sprite ;
tempImage . preserveAspect = true ;
tempImage . color = character . state . portraitImage . color ;
LeanTween . alpha ( tempImage . rectTransform , 0f , duration ) . setEase ( stage . fadeEaseType ) . setOnComplete ( ( ) = > {
Destroy ( tempGO ) ;
} ) ;
}
}
character . state . portraitImage . material . SetTexture ( "_TexEnd" , portrait . texture ) ;
UpdateTweens ( character , fromPosition , toPosition ) ;
// Fade in the new sprite image
character . state . portraitImage . sprite = portrait ;
character . state . portraitImage . color = new Color ( 1f , 1f , 1f , 0f ) ;
LeanTween . alpha ( character . state . portraitImage . rectTransform , 1f , duration ) . setEase ( stage . fadeEaseType ) ;
DoMoveTween ( character , fromPosition , toPosition ) ;
}
}
protected void Hide ( Character character , RectTransform fromPosition , RectTransform toPosition )
protected void Hide ( Character character , RectTransform fromPosition , RectTransform toPosition )
{
{
if ( character . state . display = = DisplayType . None )
if ( character . state . display = = DisplayType . None )
{
{
return ;
return ;
}
}
SetupPortrait ( character , fromPosition ) ;
SetupPortrait ( character , fromPosition ) ;
character . state . portraitImage . material . SetTexture ( "_TexStart" , character . state . portrait . texture ) ;
UpdateTweens ( character , fromPosition , toPosition ) ;
// LeanTween doesn't handle 0 duration properly
float duration = ( fadeDuration > 0f ) ? fadeDuration : float . Epsilon ;
LeanTween . alpha ( character . state . portraitImage . rectTransform , 0f , duration ) . setEase ( stage . fadeEaseType ) ;
DoMoveTween ( character , fromPosition , toPosition ) ;
}
}
protected void MoveToFront ( Character character )
protected void MoveToFront ( Character character )
{
{
character . state . portraitImage . transform . SetSiblingIndex ( character . state . portraitImage . transform . parent . childCount ) ;
character . state . portraitImage . transform . SetSiblingIndex ( character . state . portraitImage . transform . parent . childCount ) ;
}
}
protected void UpdateTweens ( Character character , RectTransform fromPosition , RectTransform toPosition )
{
protected void DoMoveTween ( Character character , RectTransform fromPosition , RectTransform toPosition )
if ( fadeDuration = = 0 ) fadeDuration = float . Epsilon ;
LeanTween . value ( character . state . portraitObj , 0 , 1 , fadeDuration ) . setEase ( stage . fadeEaseType ) . setOnComplete ( OnComplete ) . setOnUpdate (
( float fadeAmount ) = > {
character . state . portraitImage . material . SetFloat ( "_Fade" , fadeAmount ) ;
}
) ;
float moveDuration = ( Vector3 . Distance ( fromPosition . anchoredPosition , toPosition . anchoredPosition ) / moveSpeed ) ;
if ( moveSpeed = = 0 ) moveDuration = float . Epsilon ;
LeanTween . value ( character . state . portraitObj , fromPosition . anchoredPosition , toPosition . anchoredPosition , moveDuration ) . setEase ( stage . moveEaseType ) . setOnComplete ( OnComplete ) . setOnUpdate (
( Vector3 updatePosition ) = > {
character . state . portraitImage . rectTransform . anchoredPosition = updatePosition ;
}
) ;
}
public static void Dim ( Character character , Stage stage )
{
if ( character . state . dimmed = = false )
{
character . state . dimmed = true ;
float fadeDuration = stage . fadeDuration ;
if ( fadeDuration = = 0 ) fadeDuration = float . Epsilon ;
LeanTween . value ( character . state . portraitObj , 1f , 0.5f , fadeDuration ) . setEase ( stage . fadeEaseType ) . setOnUpdate (
( float tintAmount ) = > {
Color tint = new Color ( tintAmount , tintAmount , tintAmount , 1 ) ;
character . state . portraitImage . material . SetColor ( "_Color" , tint ) ;
}
) ;
}
}
public static void Undim ( Character character , Stage stage )
{
{
if ( character . state . dimmed = = true )
// LeanTween doesn't handle 0 duration properly
{
float duration = ( moveDuration > 0f ) ? moveDuration : float . Epsilon ;
character . state . dimmed = false ;
float fadeDuration = stage . fadeDuration ;
LeanTween . move ( character . state . portraitImage . rectTransform , toPosition . anchoredPosition3D , duration ) . setEase ( stage . fadeEaseType ) ;
if ( fadeDuration = = 0 ) fadeDuration = float . Epsilon ;
if ( waitUntilFinished )
LeanTween . value ( character . state . portraitObj , 0.5f , 1f , fadeDuration ) . setEase ( stage . fadeEaseType ) . setOnUpdate (
{
( float tintAmount ) = > {
waitTimer = duration ;
Color tint = new Color ( tintAmount , tintAmount , tintAmount , 1 ) ;
character . state . portraitImage . material . SetColor ( "_Color" , tint ) ;
}
) ;
}
}
}
}
protected void OnComplete ( )
public static void SetDimmed ( Character character , Stage stage , bool dimmedState )
{
{
if ( waitUntilFinished )
if ( character . state . dimmed = = dimmedState )
{
{
if ( ! LeanTween . isTweening ( character . state . portraitObj ) )
return ;
{
Continue ( ) ;
}
}
}
character . state . dimmed = dimmedState ;
Color targetColor = dimmedState ? new Color ( 0.5f , 0.5f , 0.5f , 1f ) : Color . white ;
// LeanTween doesn't handle 0 duration properly
float duration = ( stage . fadeDuration > 0f ) ? stage . fadeDuration : float . Epsilon ;
LeanTween . color ( character . state . portraitImage . rectTransform , targetColor , duration ) . setEase ( stage . fadeEaseType ) ;
}
}
public override string GetSummary ( )
public override string GetSummary ( )
{
{
if ( display = = DisplayType . None & & character = = null )
if ( display = = DisplayType . None & & character = = null )
@ -409,6 +465,7 @@ namespace Fungus
{
{
return "Error: No character selected" ;
return "Error: No character selected" ;
}
}
string displaySummary = "" ;
string displaySummary = "" ;
string characterSummary = "" ;
string characterSummary = "" ;
string fromPositionSummary = "" ;
string fromPositionSummary = "" ;
@ -426,6 +483,7 @@ namespace Fungus
displaySummary + = " \"" + replacedCharacter . name + "\" with" ;
displaySummary + = " \"" + replacedCharacter . name + "\" with" ;
}
}
}
}
characterSummary = character . name ;
characterSummary = character . name ;
if ( stage ! = null )
if ( stage ! = null )
{
{
@ -436,6 +494,7 @@ namespace Fungus
{
{
portraitSummary = " " + portrait . name ;
portraitSummary = " " + portrait . name ;
}
}
if ( shiftIntoPlace )
if ( shiftIntoPlace )
{
{
if ( offset ! = 0 )
if ( offset ! = 0 )
@ -448,27 +507,36 @@ namespace Fungus
{
{
fromPositionSummary = " from " + "\"" + fromPosition . name + "\"" ;
fromPositionSummary = " from " + "\"" + fromPosition . name + "\"" ;
}
}
if ( toPosition ! = null )
if ( toPosition ! = null )
{
{
string toPositionPrefixSummary = "" ;
string toPositionPrefixSummary = "" ;
if ( move )
if ( move )
{
toPositionPrefixSummary = " to " ;
toPositionPrefixSummary = " to " ;
}
else
else
{
toPositionPrefixSummary = " at " ;
toPositionPrefixSummary = " at " ;
}
toPositionSummary = toPositionPrefixSummary + "\"" + toPosition . name + "\"" ;
toPositionSummary = toPositionPrefixSummary + "\"" + toPosition . name + "\"" ;
}
}
if ( facing ! = FacingDirection . None )
if ( facing ! = FacingDirection . None )
{
{
if ( facing = = FacingDirection . Left )
if ( facing = = FacingDirection . Left )
{
{
facingSummary = "<--" ;
facingSummary = "<--" ;
}
}
if ( facing = = FacingDirection . Right )
if ( facing = = FacingDirection . Right )
{
{
facingSummary = "-->" ;
facingSummary = "-->" ;
}
}
facingSummary = " facing \"" + facingSummary + "\"" ;
facingSummary = " facing \"" + facingSummary + "\"" ;
}
}
return displaySummary + " \"" + characterSummary + portraitSummary + "\"" + stageSummary + facingSummary + fromPositionSummary + toPositionSummary ;
return displaySummary + " \"" + characterSummary + portraitSummary + "\"" + stageSummary + facingSummary + fromPositionSummary + toPositionSummary ;
}
}