using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
Transform m_transform;
Player m_player;
NavMeshAgent m_agent;
float m_movSpeed = 0.5f;
// Use this for initialization
void Start () {
m_transform = this.transform;
m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
m_agent = GetComponent<NavMeshAgent>();
m_agent.SetDestination (m_player.m_tranform.position);
}
void MoveTo ()
{
float speed = m_movSpeed * Time.deltaTime;
m_agent.Move(m_transform.TransformDirection((new Vector3 (0, 0, speed))));
}
// Update is called once per frame
void Update () {
MoveTo();
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/Spawn")]
public class Spawn : MonoBehaviour
{
public Transform m_transform;
public Transform m_enemy;
void Awake()
{
m_transform = this.transform;
}
// 图标显示
void OnDrawGizmos()
{
Gizmos.DrawIcon(transform.position, "Node.tif");
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/Player")]
public class Player : MonoBehaviour {
// 组件
public Transform m_transform;
CharacterController m_ch;
// 角色移动速度
float m_movSpeed = 3.0f;
// 重力
float m_gravity = 2.0f;
// 摄像机
Transform m_camTransform;
// 摄像机旋转角度
Vector3 m_camRot;
// 摄像机高度
float m_camHeight = 1.4f;
// 生命值
public int m_life = 5;
//枪口transform
Transform m_muzzlepoint;
// 射击时,射线能射到的碰撞层
public LayerMask m_layer;
// 射中目标后的粒子效果
public Transform m_fx;
// 射击音效
public AudioClip m_audio;
// 射击间隔时间计时器
float m_shootTimer = 0;
// Use this for initialization
void Start () {
// 获取组件
m_transform = this.transform;
m_ch = this.GetComponent<CharacterController>();
// 获取摄像机
m_camTransform = Camera.main.transform;
// 设置摄像机初始位置
Vector3 pos = m_transform.position;
pos.y += m_camHeight;
m_camTransform.position = pos;
m_camTransform.rotation = m_transform.rotation;
m_camRot = m_camTransform.eulerAngles;
Screen.lockCursor = true;
// 查找muzzlepoint
m_muzzlepoint = m_camTransform.FindChild("M16/weapon/muzzlepoint").transform;
}
// Update is called once per frame
void Update () {
// 如果生命为0,什么也不做
if (m_life <= 0)
return;
Control();
}
void Control()
{
//获取鼠标移动距离
float rh = Input.GetAxis("Mouse X");
float rv = Input.GetAxis("Mouse Y");
// 旋转摄像机
m_camRot.x -= rv;
m_camRot.y += rh;
m_camTransform.eulerAngles = m_camRot;
// 使主角的面向方向与摄像机一致
Vector3 camrot = m_camTransform.eulerAngles;
camrot.x = 0; camrot.z = 0;
m_transform.eulerAngles = camrot;
float xm = 0, ym = 0, zm = 0;
// 重力运动
ym -= m_gravity*Time.deltaTime;
// 上下左右运动
if (Input.GetKey(KeyCode.W)){
zm += m_movSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.S)){
zm -= m_movSpeed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A)){
xm -= m_movSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.D)){
xm += m_movSpeed * Time.deltaTime;
}
// 更新射击间隔时间
m_shootTimer -= Time.deltaTime;
// 鼠标左键射击
if (Input.GetMouseButton(0) && m_shootTimer<=0)
{
m_shootTimer = 0.1f;
this.audio.PlayOneShot(m_audio);
// 减少弹药,更新弹药UI
GameManager.Instance.SetAmmo(1);
// RaycastHit用来保存射线的探测结果
RaycastHit info;
// 从muzzlepoint的位置,向摄像机面向的正方向射出一根射线
// 射线只能与m_layer所指定的层碰撞
bool hit = Physics.Raycast(m_muzzlepoint.position, m_camTransform.TransformDirection(Vector3.forward), out info, 100, m_layer);
if (hit)
{
// 如果射中了tag为enemy的游戏体
if (info.transform.tag.CompareTo("enemy") == 0)
{
Enemy enemy = info.transform.GetComponent<Enemy>();
// 敌人减少生命
enemy.OnDamage(1);
}
// 在射中的地方释放一个粒子效果
Instantiate(m_fx, info.point, info.transform.rotation);
}
}
//移动
m_ch.Move( m_transform.TransformDirection(new Vector3(xm, ym, zm)) );
// 使摄像机的位置与主角一致
Vector3 pos = m_transform.position;
pos.y += m_camHeight;
m_camTransform.position = pos;
}
void OnDrawGizmos()
{
Gizmos.DrawIcon(this.transform.position, "Spawn.tif");
}
// 伤害
public void OnDamage(int damage)
{
m_life -= damage;
// 更新UI
GameManager.Instance.SetLife(m_life);
// 如果生命为0,解锁鼠标显示
if (m_life <= 0)
Screen.lockCursor = false;
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/GameManager")]
public class GameManager : MonoBehaviour {
public static GameManager Instance = null;
// 游戏得分
public int m_score = 0;
// 游戏最高得分
public static int m_hiscore = 0;
// 弹药数量
public int m_ammo = 100;
// 游戏主角
Player m_player;
// UI文字
GUIText txt_ammo;
GUIText txt_hiscore;
GUIText txt_life;
GUIText txt_score;
// Use this for initialization
void Start () {
Instance = this;
// 获得主角
m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
// 获得设置的UI文字
txt_ammo = this.transform.FindChild("txt_ammo").GetComponent<GUIText>();
txt_hiscore = this.transform.FindChild("txt_hiscore").GetComponent<GUIText>();
txt_life = this.transform.FindChild("txt_life").GetComponent<GUIText>();
txt_score = this.transform.FindChild("txt_score").GetComponent<GUIText>();
txt_hiscore.text = "High Score " + m_hiscore;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
Application.Quit();
}
void OnGUI()
{
if (m_player.m_life <= 0)
{
// 居中显示文字
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
// 改变文字大小
GUI.skin.label.fontSize = 40;
// 显示Game Over
GUI.Label(new Rect(0, 0, Screen.width, Screen.height), "Game Over");
// 显示重新游戏按钮
GUI.skin.label.fontSize = 30;
if ( GUI.Button( new Rect( Screen.width*0.5f-150,Screen.height*0.75f,300,40),"Try again"))
{
Application.LoadLevel(Application.loadedLevelName);
}
}
}
// 更新分数
public void SetScore(int score)
{
m_score+= score;
if (m_score > m_hiscore)
m_hiscore = m_score;
txt_score.text = "Score "+m_score;
txt_hiscore.text = "High Score "+ m_hiscore;
}
// 更新弹药
public void SetAmmo(int ammo)
{
m_ammo -= ammo;
// 如果弹药为负数,重新填弹
if (m_ammo <= 0)
m_ammo = 100 - m_ammo;
txt_ammo.text = m_ammo.ToString()+"/100";
}
// 更新生命
public void SetLife(int life)
{
txt_life.text = life.ToString();
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/EnemySpawn")]
public class EnemySpawn : MonoBehaviour
{
// 敌人的Prefab
public Transform m_enemy;
//生成的敌人数量
public int m_enemyCount = 0;
// 敌人的最大生成数量
public int m_maxEnemy = 3;
// 生成敌人的时间间隔
public float m_timer = 0;
protected Transform m_transform;
// Use this for initialization
void Start () {
m_transform = this.transform;
}
// Update is called once per frame
void Update () {
// 如果生成敌人的数量达到最大值,停止生成敌人
if (m_enemyCount >= m_maxEnemy)
return;
// 每间隔一定时间
m_timer -= Time.deltaTime;
if (m_timer <= 0)
{
m_timer = Random.value * 15.0f;
if (m_timer < 5)
m_timer = 5;
// 生成敌人
Transform obj=(Transform)Instantiate(m_enemy, m_transform.position, Quaternion.identity);
// 获取敌人的角本
Enemy enemy = obj.GetComponent<Enemy>();
// 初始化敌人
enemy.Init(this);
}
}
void OnDrawGizmos ()
{
Gizmos.DrawIcon (transform.position, "item.png", true);
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/Enemy")]
public class Enemy : MonoBehaviour {
// Transform组件
Transform m_transform;
//CharacterController m_ch;
// 动画组件
Animator m_ani;
// 寻路组件
NavMeshAgent m_agent;
// 主角
Player m_player;
// 角色移动速度
float m_movSpeed = 0.5f;
// 角色旋转速度
float m_rotSpeed = 120;
// 计时器
float m_timer=2;
// 生命值
int m_life = 15;
// 成生点
protected EnemySpawn m_spawn;
// Use this for initialization
void Start () {
// 获取组件
m_transform = this.transform;
m_ani = this.GetComponent<Animator>();
m_agent = GetComponent<NavMeshAgent>();
// 获得主角
m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
}
// 初始化
public void Init(EnemySpawn spawn)
{
m_spawn = spawn;
m_spawn.m_enemyCount++;
}
// 当被销毁时
public void OnDeath()
{
//更新敌人数量
m_spawn.m_enemyCount--;
// 加100分
GameManager.Instance.SetScore(100);
// 销毁
Destroy(this.gameObject);
}
// Update is called once per frame
void Update () {
// 如果主角生命为0,什么也不做
if (m_player.m_life <= 0)
return;
// 获取当前动画状态
AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);
// 如果处于待机状态
if (stateInfo.nameHash == Animator.StringToHash("Base Layer.idle") && !m_ani.IsInTransition(0))
{
m_ani.SetBool("idle", false);
// 待机一定时间
m_timer -= Time.deltaTime;
if (m_timer > 0)
return;
// 如果距离主角小于1.5米,进入攻击动画状态
if (Vector3.Distance(m_transform.position, m_player. m_transform.position) < 1.5f)
{
m_ani.SetBool("attack", true);
}
else
{
// 重置定时器
m_timer=1;
// 设置寻路目标点
m_agent.SetDestination(m_player. m_transform.position);
// 进入跑步动画状态
m_ani.SetBool("run", true);
}
}
// 如果处于跑步状态
if (stateInfo.nameHash == Animator.StringToHash("Base Layer.run") && !m_ani.IsInTransition(0))
{
m_ani.SetBool("run", false);
// 每隔1秒重新定位主角的位置
m_timer -= Time.deltaTime;
if (m_timer < 0)
{
m_agent.SetDestination(m_player. m_transform.position);
m_timer = 1;
}
// 追向主角
MoveTo();
// 如果距离主角小于1.5米,向主角攻击
if (Vector3.Distance(m_transform.position, m_player. m_transform.position) <= 1.5f)
{
//停止寻路
m_agent.ResetPath();
// 进入攻击状态
m_ani.SetBool("attack", true);
}
}
// 如果处于攻击状态
if (stateInfo.nameHash == Animator.StringToHash("Base Layer.attack") && !m_ani.IsInTransition(0))
{
// 面向主角
RotateTo();
m_ani.SetBool("attack", false);
// 如果攻击动画播完,重新进入待机状态
if (stateInfo.normalizedTime >= 1.0f)
{
m_ani.SetBool("idle", true);
// 重置计时器
m_timer = 2;
m_player.OnDamage(1);
}
}
// 死亡
if (stateInfo.nameHash == Animator.StringToHash("Base Layer.death") && !m_ani.IsInTransition(0))
{
if (stateInfo.normalizedTime >= 1.0f)
{
OnDeath();
}
}
}
// 转向目标点
void RotateTo()
{
// 当前角度
Vector3 oldangle = m_transform.eulerAngles;
// 获得面向主角的角度
m_transform.LookAt(m_player.m_transform);
float target = m_transform.eulerAngles.y;
// 转向主角
float speed = m_rotSpeed * Time.deltaTime;
float angle = Mathf.MoveTowardsAngle(oldangle.y, target, speed);
m_transform.eulerAngles = new Vector3(0, angle, 0);
}
// 寻路移动
void MoveTo()
{
float speed = m_movSpeed * Time.deltaTime;
m_agent.Move(m_transform.TransformDirection((new Vector3(0, 0, speed))));
}
// 伤害
public void OnDamage(int damage)
{
m_life -= damage;
// 如果生命为0,销毁自身
if (m_life <= 0)
{
m_ani.SetBool("death", true);
}
}
}
using UnityEngine;
using System.Collections;
[AddComponentMenu("Game/AutoDestroy")]
public class AutoDestroy : MonoBehaviour {
public float m_timer = 1.0f;
void Update () {
m_timer -= Time.deltaTime;
if (m_timer <= 0)
Destroy(this.gameObject);
}
}