Stealth游戏流程总结一

来源:互联网 发布:人工智能视觉识别 编辑:程序博客网 时间:2024/06/03 16:48

导入资源,把地图拖到hierarchy中,创建gameobject,命名为env,把地图拖到env中,该地图只是显示了出来,还需要添加碰撞属性collider,在地图属性中添加mesh collider,在资源model中有地图的collider文件,拖动到地图mesh collider属性中的mesh当中,选中地图,在视图中看到有绿色的框框,那就是碰撞器。由于里面有个车子的碰撞器没有放车子,需要把车子放到地图中,将车放到env中,创建名为Lights的gameobject,放directional light,背景为黑色,再放一个point light,背景黄色,在地图中放入多个point light,添加报警音乐,在地图中找到所有报警灯,在属性中add---->audio source,将资源的报警声拖动到audio source中,并把play on awake勾勾去掉。将警报的tag全部设置成siren。添加一个directional light命名为alermLight,改成红色背景,当警报响起时,调整他的intensity即可,添加一个alermLight脚本到灯光中,

 public bool alermOn = false;    private float minIntensity = 0;    private float maxIntensity = 0.5f;    private float targetIntensity;    public float animationSpeed = 1;    public static alermLight _instance;    void Awake()    {        targetIntensity = maxIntensity;        alermOn = false;        _instance = this;    }void Update () {        if (alermOn)        {            //通过插值函数渐变灯光的强度            GetComponent<Light>().intensity=Mathf.Lerp(GetComponent<Light>().intensity,                targetIntensity,Time.deltaTime* animationSpeed);            if (Mathf.Abs(targetIntensity- GetComponent<Light>().intensity) < 0.05f)            {                if (targetIntensity==maxIntensity)                {                    targetIntensity = minIntensity;                }                else                {                                   targetIntensity = maxIntensity;                }                                    }        }        else        {            GetComponent<Light>().intensity = Mathf.Lerp(GetComponent<Light>().intensity,        0, Time.deltaTime * animationSpeed);        }         }
创建gameobject名为GameController,给他添加一个脚本

  public bool alermOn = false;    private GameObject[] sirens;    void Awake()    {        alermOn = false;        sirens = GameObject.FindGameObjectsWithTag("siren");    }    void Update () {        alermLight._instance.alermOn = this.alermOn;        if (alermOn)        {            PlayAudio();        }        else        {            StopAudio();        }}    void PlayAudio()    {        foreach(GameObject i in sirens)        {            if (!i.GetComponent<AudioSource>().isPlaying)            {                i.GetComponent<AudioSource>().Play();            }        }    }    void StopAudio()    {        foreach (GameObject i in sirens)        {                          i.GetComponent<AudioSource>().Stop();                 }    }
测试时发现alermLight的alerm on勾勾无法点击,我们把所有音频属性的load type中compressed in memory改成decompress on load即可

在地图中添加摄像机小物体,给摄像机添加light,在light的type改成spot,背景红色,intensity最大,在资源中找到cctvcam_collision,拖动到左侧的cctvcam_body中,可以实现摄像机检测附件是否有人,给cctvcam_collision添加mesh collider,把mesh rendener移除掉,在地图中添加多个摄像机,要实现摄像机的左右晃动的动画,步骤如下:

选中摄像机,点击Window--->animation,创建动画,保存位置自定,add property,点击transform里面的rotation,先设0毫秒时rotation.y为270,     60毫秒时rotation.y为90     120毫秒时rotation.y为90,其他全部是0,点击播放,可以在scene查看动画效果,摄像机0-1秒rotation.y从270转到90度,1-2秒转了回来,让其他摄像机也拥有此动画只需添加animator,把第一个相机的animator--->controller复制过去即可
要让相机添加碰撞警报,在gamecontroller脚本中添加

public static GameController _instance;private Vector3 lastPlayerPosition = Vector3.zero;
在awake函数中添加_instance = this;这样创建一个单例并且设置一个vector3保存检测到人物的时候那个坐标

创建脚本名为cctvCollider放到摄像机collider中,代码如下

 void OnTriggerStay(Collider other)    {        if (other.tag=="Player")        {            GameController._instance.alermOn = true;   //发现人物,开启警报            GameController._instance.lastPlayerPosition = other.transform.position;//记录人物的当前坐标        }    }

接下来该添加光栅了,拖动到地图中,属性添加box collider(勾选is trigger)和light和audio source(勾选loop),添加Laser脚本

    public float ontime;    public float offtime;    private float calctime=0;       public bool isflash=false;  //光栅是否开始闪     void Update()    {        if (isflash)        {            calctime += Time.deltaTime;            if (GetComponent<Renderer>().enabled)  //光栅是亮的            {                            if (calctime>ontime)   //到了光栅灭的时间                {                    GetComponent<Renderer>().enabled = false;                    calctime = 0;                               }                          }            else     //光栅是灭的            {                             if (calctime > offtime)   //到了光栅灭的时间                {                    GetComponent<Renderer>().enabled = true;                    calctime = 0;                }            }        }    }

void OnTriggerStay(Collider other)    {        if (other.tag == "Player")        {            GameController._instance.alermOn = true;            GameController._instance.lastPlayerPosition = other.transform.position;        }    }

接下来该弄人物了,拖动人物模型到地图中,创建一个animator controller名为GameController拖动到人物的animator中,选中GameController,打开Window-->animator,拖动站立动画(Idle)到animator中,添加locomotion的blend tree,在其中添加run和walk动画,创建speed参数,blend tree的parameter选择speed,idel动画连接locomotion,条件为speed大于0.1,设置bool参数sneak(缓慢行动),拖动sneak动画到animator,从idel到sneak条件为speed>0.1和sneak=true。两个动作连接到idel动画的条件时speed<0.1。locomotion到sneak的来回连接条件就不说了

给player添加player脚本

  public float moveSpeed = 3;    public float stopSpeed = 7;    public float rotateSpeed = 7;    private Animator anim;    void Awake()    {        anim = GetComponent<Animator>();    }    void Update () {        float h = Input.GetAxis("Horizontal");        float v = Input.GetAxis("Vertical");        if (Mathf.Abs(h)>0.1|| Mathf.Abs(v) > 0.1)        {            float newSpeed = Mathf.Lerp(anim.GetFloat("Speed"), 5.6f, moveSpeed * Time.deltaTime);            anim.SetFloat("Speed", newSpeed);            Vector3 targetDir = new Vector3(h,0,v);            Vector3 nowDir = transform.forward;            float angle = Vector3.Angle(targetDir, nowDir);         if (angle > 180)            {             angle = 360 - angle;              angle = -angle;          }            transform.Rotate(Vector3.up*angle*Time.deltaTime*rotateSpeed);        }        else        {            anim.SetFloat("Speed", 0);        }        
发现人物会穿墙而过,人物添加capsule collider和rigidbody
如上代码发现angle>180的判断还是会出现向左转时,主角向右转一大圈绕回来的情况,所以采用四元数:

float newSpeed = Mathf.Lerp(anim.GetFloat("Speed"), 5.6f, moveSpeed * Time.deltaTime);            anim.SetFloat("Speed", newSpeed);            Vector3 targetDir = new Vector3(h,0,v);            Quaternion newRotation = Quaternion.LookRotation(targetDir, Vector3.up);            transform.rotation = Quaternion.Lerp(transform.rotation,newRotation,rotateSpeed*Time.deltaTime);

最后给sneak潜行添加代码

 if (Input.GetKey(KeyCode.LeftShift))        {            anim.SetBool("Sneak", true);        }        else        {            anim.SetBool("Sneak", false);        }
要让潜行速度快点,在状态机sneak动画里面speed参数指的是该动画播放速度参数,改成2即可

给角色添加player标签,给gamecontroller添加角色进场背景音乐(勾选loop和play on awake,把volume音量调到最大),和触发警报时音乐(勾选play on awake 勾选loop把volume调成0)。在gameController声明musicNormal和musicPanic两个audioSuorce,拖动两个audiosource组件到脚本中(是组件不是音频源文件)。

这里注意的是:要把musicPanic勾选play on awake,音量调到0正常状态不响,如果不勾选play on awake,触发警报它不会响起来。



0 0
原创粉丝点击