首页 > 代码库 > 总结一下今天做的unity面试题(一):刚体的点击事件

总结一下今天做的unity面试题(一):刚体的点击事件

技术分享

按照需求,由于要模拟丧尸被击中的效果,不能使用CharactorControll组件,只能使用rigidbody组件。

首先在场景上摆好僵尸和相机的位置,这里就不给相机加脚本了,直接固定住。

技术分享

然后给丧尸加上了胶囊型的碰撞盒,用来检测鼠标的点击,当然刚体组件是不可少的。

技术分享

随后就是控制丧尸的脚本,由于题目需求,将注释全部用英文写了,不过应该不难看懂。

首先设定不同的数值并初始化:

    public float move_speed=10f;
    public float force_x=0f,force_y=200f,force_z=200f;
    Transform m_transform,m_camera,blood;
    Animation m_animation;
    Rigidbody m_rigidbody;
    string[] clipName={"idle","crawl","shamble","run","fallBack","hit1","hit2"};
    bool is_hit=false,is_die=false;
    public int hp=1;//Zombie‘s hp,when 0 zombie die
    // Use this for initialization
    void Start () {
        m_camera = GameObject.FindGameObjectWithTag ("MainCamera").transform;
        m_transform = this.transform;
        m_animation = m_transform.GetComponent<Animation> ();
        m_rigidbody=m_transform.GetComponent<Rigidbody> ();
        blood=Resources.Load("partice/blood_out",typeof(Transform)) as Transform;
    }

 

然后要根据丧尸的移动速度给予丧尸不同的动画,理论上这里用动画状态机来做会更好,这里就是简单的切换播放:

       if (move_speed < 0.001f)
                m_animation.Play (clipName [0]);
            else if (move_speed < 1f)
                m_animation.Play (clipName [1]);
            else if (move_speed < 3f)
                m_animation.Play (clipName [2]);
            else
                m_animation.Play (clipName [3]);

然后让丧尸面向相机并向前移动:

        m_transform.LookAt (m_camera);
        m_rigidbody.transform.position+=(m_camera.position-m_transform.position).normalized*Time.deltaTime*move_speed;//zombie lookat camera and move to it

最后是点击丧尸时给予丧尸伤害,并且模拟一个击飞:

    void onm ouseDown(){
        if (!is_die) {
            m_rigidbody.AddForce (new Vector3 (force_x, force_y, force_z));//add a force if zombie not dead
            StartCoroutine (blood_out ());//play the blood animator
            hp--;
            if (0 == hp)
                StartCoroutine (die ());
            else
                StartCoroutine (hit ());
        }
    }

上面的blood_out是我用粒子系统做的一个很简陋的动画,就不放出来了。

还有一些控制动画用的协程:

    IEnumerator die(){
        is_die = true;
        yield return StartCoroutine(playanimation(clipName[4],1f));
        yield return new WaitForSeconds(3f);//after 3 seconds,destory the dead zombie
        Destroy(m_transform.gameObject);
    }
    IEnumerator hit(){
        is_hit = true;
        yield return StartCoroutine(playanimation(clipName[6],0.2f));
        is_hit = false;
    }
    IEnumerator playanimation(string name,float time){
        m_animation.Play (name);
        yield return new WaitForSeconds(time);
    }

整个完整的脚本:

using UnityEngine;
using System.Collections;

public class ZombieControll : MonoBehaviour {
    public float move_speed=10f;
    public float force_x=0f,force_y=200f,force_z=200f;
    Transform m_transform,m_camera,blood;
    Animation m_animation;
    Rigidbody m_rigidbody;
    string[] clipName={"idle","crawl","shamble","run","fallBack","hit1","hit2"};
    bool is_hit=false,is_die=false;
    public int hp=1;//Zombie‘s hp,when 0 zombie die
    // Use this for initialization
    void Start () {
        m_camera = GameObject.FindGameObjectWithTag ("MainCamera").transform;
        m_transform = this.transform;
        m_animation = m_transform.GetComponent<Animation> ();
        m_rigidbody=m_transform.GetComponent<Rigidbody> ();
        blood=Resources.Load("partice/blood_out",typeof(Transform)) as Transform;
    }
    
    // Update is called once per frame
    void Update () {
        if (hp > 0 && !is_hit) {
            if (move_speed < 0.001f)
                m_animation.Play (clipName [0]);
            else if (move_speed < 1f)
                m_animation.Play (clipName [1]);
            else if (move_speed < 3f)
                m_animation.Play (clipName [2]);
            else
                m_animation.Play (clipName [3]);//the animator depend on the move_speed
        m_transform.LookAt (m_camera);
        m_rigidbody.transform.position+=(m_camera.position-m_transform.position).normalized*Time.deltaTime*move_speed;//zombie lookat camera and move to it
        }
    }
    void onm ouseDown(){
        if (!is_die) {
            m_rigidbody.AddForce (new Vector3 (force_x, force_y, force_z));//add a force if zombie not dead
            StartCoroutine (blood_out ());//play the blood animator
            hp--;
            if (0 == hp)
                StartCoroutine (die ());
            else
                StartCoroutine (hit ());
        }
    }
    IEnumerator blood_out(){
        Transform t=Instantiate (blood).transform;
        t.position = m_transform.position;
        Debug.Log (t.name);
        yield return new WaitForSeconds(1f);//the animator last for 1 seconds
            Destroy(t.gameObject);
    }
    IEnumerator die(){
        is_die = true;
        yield return StartCoroutine(playanimation(clipName[4],1f));
        yield return new WaitForSeconds(3f);//after 3 seconds,destory the dead zombie
        Destroy(m_transform.gameObject);
    }
    IEnumerator hit(){
        is_hit = true;
        yield return StartCoroutine(playanimation(clipName[6],0.2f));
        is_hit = false;
    }
    IEnumerator playanimation(string name,float time){
        m_animation.Play (name);
        yield return new WaitForSeconds(time);
    }
}

 

总结一下今天做的unity面试题(一):刚体的点击事件