1、目标
当角色移动到草/树的后面时,因为草/树层级优先级大于等于角色,导致角色无法全部展示。
如下图所示,草遮挡了一半的角色,而树则遮挡了全部的角色。
我们希望当角色走到草/树的后面时,草/树能够改变透明度(不再是1),从而在Game界面可以看到角色。
2、创建Fader脚本
该程序执行物体淡出 / 淡入的操作。
淡出时:会在指定时间内减少alpha值到某个值
淡入时:会在指定时间内增加alpha值到1。
当玩家与物体碰撞(Trigger)后会执行淡出操作,当玩家离开物体后会执行淡入操作。
(1)Settings中配置参数值
在Assets -> Scripts -> Misc -> Settings.cs中新增代码如下:
// Obscuring Item Fader
public const float fadeInSeconds = 0.25f;
public const float fadeOutSeconds = 0.35f;
public const float targetAlpha = 0.45f;
目前Settings.cs的完整代码如下:
using UnityEngine;
public static class Settings
{
// Obscuring Item Fader
public const float fadeInSeconds = 0.25f;
public const float fadeOutSeconds = 0.35f;
public const float targetAlpha = 0.45f;
// Player Movement
public const float runningSpeed = 5.333f;
public const float walkingSpeed = 2.666f;
// Player Animation Parameters
public static int xInput;
public static int yInput;
public static int isWalking;
public static int isRunning;
public static int toolEffect;
public static int isUsingToolRight;
public static int isUsingToolLeft;
public static int isUsingToolUp;
public static int isUsingToolDown;
public static int isLiftingToolRight;
public static int isLiftingToolLeft;
public static int isLiftingToolUp;
public static int isLiftingToolDown;
public static int isSwingingToolRight;
public static int isSwingingToolLeft;
public static int isSwingingToolUp;
public static int isSwingingToolDown;
public static int isPickingRight;
public static int isPickingLeft;
public static int isPickingUp;
public static int isPickingDown;
// Shared Animation Parameters
public static int idleUp;
public static int idleDown;
public static int idleLeft;
public static int idleRight;
// static constructor
static Settings()
{
xInput = Animator.StringToHash("xInput");
yInput = Animator.StringToHash("yInput");
isWalking = Animator.StringToHash("isWalking");
isRunning = Animator.StringToHash("isRunning");
toolEffect = Animator.StringToHash("toolEffect");
isUsingToolRight = Animator.StringToHash("isUsingToolRight");
isUsingToolLeft = Animator.StringToHash("isUsingToolLeft");
isUsingToolUp = Animator.StringToHash("isUsingToolUp");
isUsingToolDown = Animator.StringToHash("isUsingToolDown");
isLiftingToolRight = Animator.StringToHash("isLiftingToolRight");
isLiftingToolLeft = Animator.StringToHash("isLiftingToolLeft");
isLiftingToolUp = Animator.StringToHash("isLiftingToolUp");
isLiftingToolDown = Animator.StringToHash("isLiftingToolDown");
isSwingingToolRight = Animator.StringToHash("isSwingingToolRight");
isSwingingToolLeft = Animator.StringToHash("isSwingingToolLeft");
isSwingingToolUp = Animator.StringToHash("isSwingingToolUp");
isSwingingToolDown = Animator.StringToHash("isSwingingToolDown");
isPickingRight = Animator.StringToHash("isPickingRight");
isPickingLeft = Animator.StringToHash("isPickingLeft");
isPickingUp = Animator.StringToHash("isPickingUp");
isPickingDown = Animator.StringToHash("isPickingDown");
idleUp = Animator.StringToHash("idleUp");
idleDown = Animator.StringToHash("idleDown");
idleLeft = Animator.StringToHash("idleLeft");
idleRight = Animator.StringToHash("idleRight");
}
}
(2)淡入淡出效果的脚本
在Scripts下新建Item的目录。
并在其下创建ObscuringItemFader.cs脚本。
using System.Collections;
using UnityEngine;
[RequireComponent(typeof(SpriteRenderer))]
public class ObscuringItemFader : MonoBehaviour
{
private SpriteRenderer spriteRenderer;
// Start is called before the first frame update
private void Awake()
{
spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
}
public void FadeOut()
{
StartCoroutine(FadeOutRoutine());
}
public void FadeIn()
{
StartCoroutine(FadeInRoutine());
}
private IEnumerator FadeInRoutine()
{
float currentAlpha = spriteRenderer.color.a;
float distance = 1f - Settings.targetAlpha;
while (1f - currentAlpha > 0.01f)
{
currentAlpha = currentAlpha + distance / Settings.fadeInSeconds * Time.deltaTime;
spriteRenderer.color = new Color(1f, 1f, 1f, currentAlpha);
yield return null;
}
spriteRenderer.color = new Color(1f, 1f, 1f, 1f);
}
private IEnumerator FadeOutRoutine()
{
float currentAlpha = spriteRenderer.color.a;
float distance = currentAlpha - Settings.targetAlpha;
while(currentAlpha - Settings.targetAlpha > 0.01f)
{
currentAlpha = currentAlpha - distance / Settings.fadeOutSeconds * Time.deltaTime;
spriteRenderer.color = new Color(1f, 1f, 1f, currentAlpha);
yield return null;
}
spriteRenderer.color = new Color(1f, 1f, 1f, Settings.targetAlpha);
}
}
该脚本需要附加到 与角色发生碰撞后 需要模糊处理的物体上。
- [RequireComponent(typeof(SpriteRenderer))]:该脚本使用的前提是当前对象有SpriteRenderer组件
- distance / Settings.fadeOutSeconds * Time.deltaTime:每一帧的变动值。
- SpriteRenderer的Color:默认的Color为(1f,1f,1f,1f)
- yield return null:当使用yield return null时,协程会在下一帧继续执行。这意味着协程将暂停一帧,然后在下一帧继续执行。使用yield return null可以在每一帧之间进行操作,比如更新游戏对象的位置、旋转或者其他计算。
(3)触发淡入淡出的脚本
在Scripts -> Item目录下创建TriggerObscuringItemFader脚本。
using UnityEngine;
public class TriggerObscuringItemFader : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collision)
{
// Get the gameobject we have collided with, and then get all the Obscuring Item Fader components on it and its children - and then trigger the fade out
ObscuringItemFader[] obscuringItemFaders = collision.gameObject.GetComponentsInChildren<ObscuringItemFader>();
if(obscuringItemFaders.Length > 0)
{
for(int i = 0; i < obscuringItemFaders.Length; i++)
{
obscuringItemFaders[i].FadeOut();
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
// Get the gameobject we have collided with, and then get all the Obscuring Item Fader components on it and its children - and then trigger the fade in
ObscuringItemFader[] obscuringItemFaders = collision.gameObject.GetComponentsInChildren<ObscuringItemFader>();
if (obscuringItemFaders.Length > 0)
{
for (int i = 0; i < obscuringItemFaders.Length; i++)
{
obscuringItemFaders[i].FadeIn();
}
}
}
}
collision.gameObject 是碰撞中的另一个游戏对象。
GetComponentsInChildren<Type>() 是一个用于获取游戏对象及其所有子对象的组件的函数。
3、给Bush和Tree添加Fader脚本
给Prefabs -> Scenary中的CanyonOaScenary和WildOakScenary分别添加Box Collider 2D组件和ObscuringItemFader组件。
其中需要勾选Box Collider 2D组件的Is Trigger属性。
CanyonOaScenary还包括Trunk部分,所以也需要添加Box Collider 2D组件和ObscuringItemFader组件。
TumbleweedThistle预设体比较特殊,因为我们已经给它添加了Box Collider 2D组件,放置角色穿透它。
那我们的做法是:给它添加另外一个Box Collider 2D组件作为Trigger,但是Trigger只是位于上半部分,和Collider不重叠。
Trigger部分的区域如下(为了避免两个Collider不好操作,可以暂时先反选第一个Collider)。
然后再添加ObscuringItemFader组件。
4、给Player添加TriggerObscuringItemFader组件
效果如下: