Stealth游戏流程总结一

导入资源,把地图拖到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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值