Browse Source

Fixed: Character portrait images have display artefacts #92

Changed MoveSpeed to MoveDuration (more robust)
Replaced cross fade material with simple image tweening system.
Stage Show / Hide now done by tweeting the CanvasGroup alpha.
WaitUntilFinished option now works robustly (using a Coroutine).
master
chrisgregan 10 years ago
parent
commit
f8aa36170e
  1. 6
      Assets/Fungus/Narrative/Editor/PortraitEditor.cs
  2. 93
      Assets/Fungus/Narrative/Resources/Crossfade.shader
  3. 8
      Assets/Fungus/Narrative/Resources/Crossfade.shader.meta
  4. 103
      Assets/Fungus/Narrative/Resources/Portrait.mat
  5. 4
      Assets/Fungus/Narrative/Resources/Portrait.mat.meta
  6. 65
      Assets/Fungus/Narrative/Scripts/Commands/ControlStage.cs
  7. 258
      Assets/Fungus/Narrative/Scripts/Commands/Portrait.cs
  8. 14
      Assets/Fungus/Narrative/Scripts/Dialog.cs
  9. 4
      Assets/Fungus/Narrative/Scripts/Stage.cs

6
Assets/Fungus/Narrative/Editor/PortraitEditor.cs

@ -26,7 +26,7 @@ namespace Fungus
protected SerializedProperty facingProp; protected SerializedProperty facingProp;
protected SerializedProperty useDefaultSettingsProp; protected SerializedProperty useDefaultSettingsProp;
protected SerializedProperty fadeDurationProp; protected SerializedProperty fadeDurationProp;
protected SerializedProperty moveSpeedProp; protected SerializedProperty moveDurationProp;
protected SerializedProperty shiftOffsetProp; protected SerializedProperty shiftOffsetProp;
protected SerializedProperty waitUntilFinishedProp; protected SerializedProperty waitUntilFinishedProp;
protected SerializedProperty moveProp; protected SerializedProperty moveProp;
@ -45,7 +45,7 @@ namespace Fungus
facingProp = serializedObject.FindProperty("facing"); facingProp = serializedObject.FindProperty("facing");
useDefaultSettingsProp = serializedObject.FindProperty("useDefaultSettings"); useDefaultSettingsProp = serializedObject.FindProperty("useDefaultSettings");
fadeDurationProp = serializedObject.FindProperty("fadeDuration"); fadeDurationProp = serializedObject.FindProperty("fadeDuration");
moveSpeedProp = serializedObject.FindProperty("moveSpeed"); moveDurationProp = serializedObject.FindProperty("moveDuration");
shiftOffsetProp = serializedObject.FindProperty("shiftOffset"); shiftOffsetProp = serializedObject.FindProperty("shiftOffset");
waitUntilFinishedProp = serializedObject.FindProperty("waitUntilFinished"); waitUntilFinishedProp = serializedObject.FindProperty("waitUntilFinished");
moveProp = serializedObject.FindProperty("move"); moveProp = serializedObject.FindProperty("move");
@ -217,7 +217,7 @@ namespace Fungus
if (t.move) if (t.move)
{ {
// MOVE SPEED // MOVE SPEED
EditorGUILayout.PropertyField(moveSpeedProp); EditorGUILayout.PropertyField(moveDurationProp);
} }
if (t.shiftIntoPlace) if (t.shiftIntoPlace)
{ {

93
Assets/Fungus/Narrative/Resources/Crossfade.shader

@ -1,93 +0,0 @@
Shader "Custom/Cross Fade"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_TexStart ("Start Texture ", 2D) = "white" {}
_TexEnd ("End Texture", 2D) = "white" {}
_Fade ("Fade", Range(0, 1)) = 0
_Alpha ("Alpha", Range(0, 1)) = 1
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] _FlipStart("Flip Start Texture", Float) = 0
[MaterialToggle] _FlipEnd("Flip End Texture", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector"="True"
"RenderType" = "Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
"ForceNoShadowCasting"="True"
}
Cull Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _MainTex_ST;
sampler2D _TexStart;
fixed4 _TexStart_ST;
sampler2D _TexEnd;
fixed4 _TexEnd_ST;
float _Fade;
float _Alpha;
fixed4 _Color;
float _FlipStart;
float _FlipEnd;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
fixed4 frag (v2f i) : COLOR
{
float2 start_uv = float2( i.texcoord.x, i.texcoord.y );
float2 end_uv = float2( i.texcoord.x, i.texcoord.y );
if ( _FlipStart != 0 )
start_uv = float2( 1.0 - i.texcoord.x, i.texcoord.y );
if ( _FlipEnd != 0 )
end_uv = float2( 1.0 - i.texcoord.x, i.texcoord.y );
fixed4 texStart = tex2D(_TexStart, start_uv);
fixed4 texEnd = tex2D(_TexEnd, end_uv);
fixed4 crosstex = ( texStart * texStart.a * (1.0-_Fade) ) + ( texEnd * texEnd.a * _Fade );
return (crosstex * i.color) * _Alpha;
}
ENDCG
}
}
Fallback off
}

8
Assets/Fungus/Narrative/Resources/Crossfade.shader.meta

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 0bd2a5da5a3c2e94b95241a053a21199
ShaderImporter:
defaultTextures:
- _MainTex: {instanceID: 0}
- _Tex1: {instanceID: 0}
- _Tex2: {instanceID: 0}
userData:

103
Assets/Fungus/Narrative/Resources/Portrait.mat

@ -1,103 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 3
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Portrait
m_Shader: {fileID: 4800000, guid: 0bd2a5da5a3c2e94b95241a053a21199, type: 3}
m_ShaderKeywords: []
m_CustomRenderQueue: -1
m_SavedProperties:
serializedVersion: 2
m_TexEnvs:
data:
first:
name: _MainTex
second:
m_Texture: {fileID: 2800000, guid: c27113fd8a09c7c45a856e5d3c843c11, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _BumpMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _TexStart
second:
m_Texture: {fileID: 2800000, guid: bcd5b5f11de95ec4ba92005e4a404502, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _TexEnd
second:
m_Texture: {fileID: 2800000, guid: f20cadd42b0548a4d8d2cd5b36223312, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _Tex1
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _Tex2
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
data:
first:
name: PixelSnap
second: 0
data:
first:
name: _Fade
second: 1
data:
first:
name: _FlipStart
second: 0
data:
first:
name: _FlipEnd
second: 0
data:
first:
name: _Alpha
second: 1
data:
first:
name: _flipStart
second: 0
data:
first:
name: _flipEnd
second: 0
data:
first:
name: _Opacity
second: 1
m_Colors:
data:
first:
name: _Color
second: {r: 1, g: 1, b: 1, a: 1}
data:
first:
name: _StartColor
second: {r: 1, g: 1, b: 1, a: 1}
data:
first:
name: _EndColor
second: {r: 1, g: 1, b: 1, a: 1}

4
Assets/Fungus/Narrative/Resources/Portrait.mat.meta

@ -1,4 +0,0 @@
fileFormatVersion: 2
guid: 84ea47f59517f4ac1815f552cc8d60bc
NativeFormatImporter:
userData:

65
Assets/Fungus/Narrative/Scripts/Commands/ControlStage.cs

@ -85,14 +85,14 @@ namespace Fungus
switch(display) switch(display)
{ {
case (StageDisplayType.Show): case (StageDisplayType.Show):
Show(stage); Show(stage, true);
break; break;
case (StageDisplayType.Hide): case (StageDisplayType.Hide):
Hide(stage); Show(stage, false);
break; break;
case (StageDisplayType.Swap): case (StageDisplayType.Swap):
Show(stage); Show(stage, true);
Hide(replacedStage); Show(replacedStage, false);
break; break;
case (StageDisplayType.MoveToFront): case (StageDisplayType.MoveToFront):
MoveToFront(stage); MoveToFront(stage);
@ -111,54 +111,23 @@ namespace Fungus
} }
} }
protected void Show(Stage stage) protected void Show(Stage stage, bool visible)
{ {
if (fadeDuration == 0) float duration = (fadeDuration == 0) ? float.Epsilon : fadeDuration;
{ float targetAlpha = visible ? 1f : 0f;
fadeDuration = float.Epsilon;
}
LeanTween.value(gameObject,0,1,fadeDuration).setOnUpdate(
(float fadeAmount)=>{
foreach ( Character c in stage.charactersOnStage)
{
c.state.portraitImage.material.SetFloat("_Alpha",fadeAmount);
}
}
).setOnComplete(
()=>{
foreach ( Character c in stage.charactersOnStage)
{
c.state.portraitImage.material.SetFloat("_Alpha",1);
}
OnComplete();
}
);
}
protected void Hide(Stage stage) CanvasGroup canvasGroup = stage.GetComponentInChildren<CanvasGroup>();
{ if (canvasGroup == null)
if (fadeDuration == 0)
{ {
fadeDuration = float.Epsilon; Continue();
} return;
LeanTween.value(gameObject,1,0,fadeDuration).setOnUpdate(
(float fadeAmount)=>{
foreach ( Character c in stage.charactersOnStage)
{
c.state.portraitImage.material.SetFloat("_Alpha",fadeAmount);
}
} }
).setOnComplete(
()=>{ LeanTween.value(canvasGroup.gameObject, canvasGroup.alpha, targetAlpha, duration).setOnUpdate( (float alpha) => {
foreach ( Character c in stage.charactersOnStage) canvasGroup.alpha = alpha;
{ }).setOnComplete( () => {
c.state.portraitImage.material.SetFloat("_Alpha",0);
}
OnComplete(); OnComplete();
} });
);
} }
protected void MoveToFront(Stage stage) protected void MoveToFront(Stage stage)
@ -181,7 +150,7 @@ namespace Fungus
stage.dimPortraits = false; stage.dimPortraits = false;
foreach (Character character in stage.charactersOnStage) foreach (Character character in stage.charactersOnStage)
{ {
Portrait.Undim(character, stage); Portrait.SetDimmed(character, stage, false);
} }
} }

258
Assets/Fungus/Narrative/Scripts/Commands/Portrait.cs

@ -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;
} }

14
Assets/Fungus/Narrative/Scripts/Dialog.cs

@ -239,11 +239,11 @@ namespace Fungus
{ {
if (c != speakingCharacter) if (c != speakingCharacter)
{ {
Portrait.Dim(c,s); Portrait.SetDimmed(c, s, true);
} }
else else
{ {
Portrait.Undim(c,s); Portrait.SetDimmed(c, s, false);
} }
} }
} }
@ -621,18 +621,18 @@ namespace Fungus
{ {
if (c.state.portraitImage != null) if (c.state.portraitImage != null)
{ {
if (LeanTween.isTweening(c.state.portraitObj)) if (LeanTween.isTweening(c.state.portraitImage.gameObject))
{ {
LeanTween.cancel(c.state.portraitObj, true); LeanTween.cancel(c.state.portraitImage.gameObject, true);
c.state.portraitImage.material.SetFloat( "_Fade", 1 );
Portrait.SetRectTransform(c.state.portraitImage.rectTransform, c.state.position); Portrait.SetRectTransform(c.state.portraitImage.rectTransform, c.state.position);
if (c.state.dimmed == true) if (c.state.dimmed == true)
{ {
c.state.portraitImage.material.SetColor("_Color", new Color(0.5f,0.5f,0.5f,1f)); c.state.portraitImage.color = new Color(0.5f,0.5f,0.5f,1f);
} }
else else
{ {
c.state.portraitImage.material.SetColor("_Color", new Color(1f,1f,1f,1f)); c.state.portraitImage.color = Color.white;
} }
} }
} }

4
Assets/Fungus/Narrative/Scripts/Stage.cs

@ -13,8 +13,8 @@ namespace Fungus
{ {
public Canvas portraitCanvas; public Canvas portraitCanvas;
public bool dimPortraits; public bool dimPortraits;
public float fadeDuration; public float fadeDuration = 0.5f;
public float moveSpeed; public float moveDuration = 1f;
public LeanTweenType fadeEaseType; public LeanTweenType fadeEaseType;
public LeanTweenType moveEaseType; public LeanTweenType moveEaseType;
public Vector2 shiftOffset; public Vector2 shiftOffset;

Loading…
Cancel
Save