在游戏设计中,一般会通过多种模式来提醒玩家突发的事件等,比如视觉效果、音效/音乐、震动等。这样不仅可以增强游戏的体验感,还可以避免玩家错过一些重要的内容。
同理,在这个游戏中,除了生命条减少,我们还可以通过灯光闪烁来提示玩家目前损耗的状态。另外,利用红色等较为醒目的颜色也会带来警示的意味,告知玩家这是“危险”的行为⚠️。
-
在编辑器上方菜单栏中选择“Game Object”—“Light”
可以看到灯光菜单栏中共有四种灯光,分别是
点灯光(Point Light) | |
聚光 (Spot Light) | |
方向光 (Directional Light) | |
区域光 (Area Light) |
(图源Unity Manual)
表格中的四幅图简单明了地解释了四种灯光的区别。它们常见的使用情况也各不相同。比如,点灯光一般适用于路灯、台灯等生活场景中常见的光源。聚光则可以用来代替手电筒、汽车灯等方向显著的光源。方向光常用作覆盖整个游戏场景的光源,因为它既有明显的方向,各个方向上的光源强度又近似,因此非常贴近日光。区域光适用的场景较广,它可以从各个维度照亮物体,又不会有像点光源那般过于明显的界限,所以常被用来创造一些较为真实的光照常场景。
你可以根据个人的喜好选择光源类型来作为飞船的灯光。点光源和聚光都是不错的选择。我选择了点光源,因为飞船可以切换前后视角,点光源可以保证各个方向都能够看到警报灯光。
-
选择“Point Light” (或者你选择的光源类型)
-
在左侧场景栏中双击选中,此时可以看到灯光的轮廓。如果看不到,可能需要滑动鼠标滚轮拉远视角。
-
左键按住场景栏中的灯光,将其拖动到飞船下方。这样灯光就可以随着飞船一起移动了。
基础灯光的样子已经完成,还可以通过右侧属性栏中调整灯光的范围(Range)、颜色(Color)、强度(intensity)等。
正常状态下的灯光可以处于白色或黄色等。接下来,我们通过代码来实现碰撞时红色灯光闪烁的场景。大致分为以下三步:
-
检测飞船与其他物体的碰撞✅
-
在发生碰撞时,切换灯光颜色为红色。
-
创造闪烁效果
第一步在之前的文章中已经详细讲过(简而言之,是利用OnCollisionEnter来探测碰撞)。第2、3步可以在之前的基础上完成。
-
在Scripts中,双击打开Spacecraft
-
新建一个boolean变量”damaged”,用来记录飞船是否收到伤害
private bool damaged;
它的默认值应该为”false”,当飞船遭到撞击时,改变为”true”。
// Start is called before the first frame update
void Start()
{
damaged = false;
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Moon Trash") || collision.gameObject.CompareTag("Space Trash"))
{
collision.gameObject.SetActive(false);
}
// change status to damaged if spaceship hits other objects
// 飞船受到碰撞,改变damage值
else { damaged = true;}
}
- 在运行后的每一帧观察damaged的值,当damaged变为false时,需要有相应的方法改变飞船的灯光。新建一个boolean变量”damaged”,用来记录飞船是否收到伤害。
// Update is called once per frame
void Update()
{
// 。。。之前其他的方法
// if the spaceship is hit by other objects, toggle light
// 当damage等于true,代表飞船收到了撞击,此时执行“ToggleLight”方法
if (damaged == true){
ToggleLight();
}
}
- 在ToggleLight中,我们需要完成前面提到的第2、3步。在完成这个方法之前,我们需要在此类中定义这些变量。
public UnityEngine.Light light; // 光源
public Color warning_color; // 警告颜色
public Color normal_color; // 正常颜色
public float maxIntensity; // 最大光源强度
public float minIntensity; // 最小光源强度
-
现在,新建ToggleLight方法。
void ToggleLight()
{
// When damaged
// 当飞船受到伤害
if(damaged)
{
// 2. change light color to red
// 将灯光的颜色改为红色
light.color = warning_color;
// 3. light blinking
// 将灯光的强度在最大和最小值间来回切换,造成闪烁的效果
if (light.intensity == minIntensity)
{
light.intensity = maxIntensity;
}
else if (light.intensity == maxIntensity)
{
light.intensity = minIntensity;
}
}
}
-
保存,回到Unity编辑器中,选择Spaceship,将光源目标拖入相应空格
-
根据你的喜好自定义大小强度、灯光颜色等变量
现在运行游戏,在碰撞不可收集的物体时,已经可以看到飞船红灯闪烁的样子了!
问题是,即使在远离物体后,灯光依然不会变回正常的模样。当然可以说飞船收到了永久伤害,但这样就无法明显的提示下一次碰撞。因此,我们需要加一个时间限制,让警示灯在闪烁X时间内,回归正常状态。
-
回到Spaceship的script中,新建两个变量
public float warningTime; // 警告持续最大时长
private float elapsedTime; // 警告已有时长
-
在update中,用elapseTime来记录灯光闪烁时间,并与我们定义的最大时长做比较。
// Update is called once per frame
void Update()
{
// 。。。之前其他的方法
// if the spaceship is hit by other objects, toggle light
// 当damage等于true,代表飞船收到了撞击,此时执行“ToggleLight”方法
if (damaged == true){
ToggleLight();
// after certain time, change it back to normal
// 记录持续时间
elapsedTime += Time.deltaTime;
// after certain time, change it back to normal
// 当持续时间大于等于最大时间时,将damage恢复正常
if (elapsedTime >= warningTime)
{
// Stop shaking and change color back to normal
damaged = false;
ToggleLight();
}
}
}
- 这里可以选择直接在update中恢复灯光的颜色和强度,也可以在ToggleLight中加一个比较条件一块解决。我选择后者,因为逻辑结构更加清晰。
void ToggleLight()
{
// When not damaged
// 当没有碰撞发生时
if(damaged==false)
{
// 恢复颜色、光源强度、以及持续时间
light.color = normal_color;
light.intensity = minIntensity;
elapsedTime = 0;
}
// When damaged
if(damaged)
{
// 2. change light color to red
light.color = warning_color;
// 3. light blinking
if (light.intensity == minIntensity)
{
light.intensity = maxIntensity;
}
else if (light.intensity == maxIntensity)
{
light.intensity = minIntensity;
}
}
}
-
保存,回到编辑器中设定warningTime为你想要的警告时长。
现在运行,就可以达到我们想要的灯光闪烁警告效果啦。
感谢阅读!如果有任何疑问或者建议,欢迎在下方留言评论哟~