按照需求,由于要模拟丧尸被击中的效果,不能使用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(); m_rigidbody=m_transform.GetComponent (); 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 OnMouseDown(){ 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(); m_rigidbody=m_transform.GetComponent (); 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 OnMouseDown(){ 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); } }