Stealth秘密行动
在这个博客里,我将讲解一个潜入类型的游戏制作方法
1. 首先我们需要导入当前的场景,这里我们需要给场景添加碰撞器,将素材里的env_stealth拖入,加上meshCollieder,添加上env_stealth_collider就可以将预先设置好的碰撞器添加上,再将模型中的汽车拖入,对照碰撞器摆好好汽车即可,
2. 我们给场景添加光源
(1).改变天空盒子为黑色
(2)创建一个叫做Light的空物体,里面存放directLight和PointLight
(3),按照自己喜好放置光源的位置即可
3. 制作警报效果
我们首先给场景添加一个直射光,命名为alarmLight,然后在它下面添加这个脚本
逻辑如下:
1. light下有个intensity的组件,我们控制这个数值来决定亮度,因此我们定义个最大值和最小值
2. 我们通过Mathf.Lerp()方法来控制数值的变动
3. 为了实现灯光的循环闪动,我们加入判断当灯光趋近于临界值时,变为0,再反复循环
4. 为了方便以后调用警报,我们判断当AlanWake是false和true时是显示光还是不显示
5. 我们将这个方法封装成单例模式
using UnityEngine;
using System.Collections;
publicclassAlarmScripts : MonoBehaviour {
publicbool AlarmWake = false;
privatefloat lowIntensity = 0;//这里控制的是警报灯光的界限,即0到0.5
privatefloat highIntensity = 0.5f;
privatefloat targetIntensity;
publicfloat AlameSpeed = 3;
publicstaticAlarmScripts _instance;
void Awake()
{
targetIntensity = highIntensity;
AlarmWake = false;
_instance = this;
}
// Update is called once per frame
void Update () {
if (AlarmWake)
{
light.intensity = Mathf.Lerp(light.intensity,targetIntensity,Time.deltaTime);//这里通过Mathf.Lerp的方法,控制光照亮度的变化,后面的数值是控制0-1的一个界限,超过1即为1,小于0就是0
if (Mathf.Abs(light.intensity - targetIntensity) < 0.05f)//Math.lerp是抛物线,永远不会接近highIntensity,当两者差值到这个界限的时候,我们需要将光照从满变成暗
{
//这里实现的是来回循环播放光照的变化
if (targetIntensity == highIntensity)
{
targetIntensity =lowIntensity;
}
else
{
targetIntensity =highIntensity;
}
}
}
else
{
light.intensity = Mathf.Lerp(light.intensity,0, Time.deltaTime *AlameSpeed);
}
}
}
4. 创建游戏控制器来管理警报和灯的协同控制
我们希望当警报响起的时候灯也同时响起,这样,我们需要一个游戏物体来控制它们
1. 首先,我们创建一个空的游戏物体将其命名为gameController,然后在它下面添加这个脚本
逻辑如下
1我们创建一个bool值来判断此时警报和灯是否应该响起
2.我们上节将所有喇叭添加了一个tag,我们通过GameObject.findwithTag这个方法来找到所有警报装置
3.我们在unpdate里同步了灯光和之前的警报脚本保持一致
4.我们创建两个方法,通过audio下的isPlaying判断是否播放,通过foreach来遍历所有的路灯
5在update里判断灯光的变化来跟随声音的变化
6..这样就实现了灯光和警报的协同变化
2. using UnityEngine;
3. using System.Collections;
4.
5. publicclassGameController : MonoBehaviour {
6. //这是一个游戏控制器,在这里我们要控制游戏的各项属性
7. //首先我们进行声音的控制
8. publicbool alarmOn=false;
9. privateGameObject[] sirens;
10. // Use this for initialization
11. void Awake () {
12. alarmOn = false;
13. sirens = GameObject.FindGameObjectsWithTag("Siren");//通过tag找到所有的警报装置
14. }
15.
16. // Update is called once per frame
17. void Update () {
18. AlarmScripts._instance.AlarmWake = this.alarmOn;//保持两边警报一致
19. if (alarmOn)
20. {
21. OpenAlarm();
22. }
23. else
24. {
25. CloseAlarm();
26. }
27. }
28. privatevoid OpenAlarm()
29. {
30.
31. foreach(GameObject go in sirens)
32. {
33. if (!go.audio.isPlaying)
34. {
35.
36. go.audio.Play();
37.
38. }
39.
40.
41. }
42.
43. }
44. privatevoid CloseAlarm()
45. {
46. foreach (GameObject go in sirens)
47. {
48. if (go.audio.isPlaying)
49. {
50.
51. go.audio.Stop();
52.
53. }
54.
55.
56. }
57.
58. }
59. }
5. 控制摄像头的来回播放
这里运用unity自带的组件animation,控制的是摄像机y轴的变动,设置一个两秒钟内0到90,90到0的变动就行,要想添加到其他摄像头上只需要添加animatior,然后将controller添加上去就行
6. 通过tags来统一管理标签
因为本项目所用标签很多,如果每个都用字符串书写,容易导致错漏,因此,创建一个统一管理标签的tags脚本,这样再通过Tags进行访问,这样出错率降低,并且修改起来简单
using UnityEngine;
using System.Collections;
publicclassTags : MonoBehaviour {
//这里用来统一存放我们需要调用的各种tags,const存放的是静态不可修改的变量
publicconststring siren= "Siren";
publicconststring player = "Player";
publicconststring enemy = "Enemy";
}
7. 给场景添加激光通道
这个不牵扯代码知识,就是将model里的激光拖出来,用空物体存储,添加boxCollider和audioSource进行控制碰撞和音乐,再将其拖放到prefab里,移动到各个接口位置即可
8. 给激光添加闪烁
我们要控制激光闪烁,只要控制render是否渲染即可,因此我们设置开始和关闭时间,通过计时器判断是否到达相应时间,再通过render,enable就可以调整激光的是否亮起了
9. using UnityEngine;
10. using System.Collections;
11.
12. publicclassLaser : MonoBehaviour
13. {
14. publicbool isFlicker = false;//判断是否闪烁
15. //控制亮的时间,关闭的时间和计时器
16. publicfloat onTime = 3;
17. publicfloat offTime = 3;
18. publicfloat timer = 0;
19.
20.
21. void OnTriggerStay(Collider other)
22. {
23. GameController._instance.seePlayer(other.transform);
24.
25.
26. }
27. //这里我们要控制激光的闪烁
28. void Update()
29. {
30. if (isFlicker)
31. {
32. if (renderer.enabled == true)
33. {
34. timer += Time.deltaTime;
35. if (timer >= onTime)
36. {
37. renderer.enabled = false;
38. timer = 0;
39.
40. }