unity3d-游戏实战突出重围,整合游戏

时间:2022-04-22 18:56:11

结构图:

unity3d-游戏实战突出重围,整合游戏  unity3d-游戏实战突出重围,整合游戏

两个场景,一个是开始界面。一个是游戏界面:

脚本说明:依次是:敌人脚本,主角游戏,主菜单,工具

Enemy

 using UnityEngine;
using System.Collections; public class Enemy : MonoBehaviour
{ /*===============================
* 敌人脚本
*==============================*/ //敌人状态 //敌人站立状态
public const int STATE_STAND = ;
//敌人行走状态
public const int STATE_WALK = ;
//敌人奔跑状态
public const int STATE_RUN = ;
//敌人暂停状态
public const int STATE_PAUSE = ; //记录敌人当前状态
private int enemState;
//主角对象
private GameObject hero; //备份上一次敌人的思考时间
private float backUptime;
//敌人思考下一次行为时间
private const int AI_ATTACK_TIME = ;
//敌人的巡逻范围
public const int AI_ATTACK_DISTANCE = ; //是否绘制血条 当鼠标指向敌人则绘制。离开则不绘制
bool showBlood = false; //血条资源贴图
public Texture2D tex_red;
public Texture2D tex_black; //生命值贴图
public Texture2D tex_hp; //生命值
private int HP = ; //敌人仇恨
private bool ishatred = false; //图片数字资源
Object[] texmube; // Use this for initialization
void Start()
{
//获取主角对象,这里前端赋值比较好
hero = GameObject.Find("Hero"); //读取图片资源
texmube = Resources.LoadAll("number"); //设置敌人默认状态为站立
enemState = STATE_STAND;
} // Update is called once per frame
void Update()
{
//判断敌人与主角之间的距离
if (Vector3.Distance(transform.position, hero.transform.position) < AI_ATTACK_DISTANCE || ishatred)
{
//敌人进入奔跑状态
gameObject.animation.Play("run");
enemState = STATE_RUN; //设置敌人面朝主角方向
transform.LookAt(hero.transform); //随机攻击主角
int rand = Random.Range(, );
if (rand == )
{
//模拟攻击,
//向主角发送攻击消息,然后在主角对象脚本中实现HeroHrut方法,进行主角减血
hero.SendMessage("HeroHurt");
}
}
//敌人进入巡逻状态
else
{
//计算敌人的思考时间
if (Time.time - backUptime >= AI_ATTACK_TIME)
{
//敌人开始思考
//备份思考的时间
backUptime = Time.time; //取得0~2之间的随机数
int rand = Random.Range(, );
if (rand == )
{
//敌人进入站立状态
transform.animation.Play("idle");
//设置状态
enemState = STATE_STAND;
}
else if (rand == )
{
//敌人进入行走状态
//敌人随机旋转角度
Quaternion rotate = Quaternion.Euler(, Random.Range(, ) * , );
//1秒内完成旋转
transform.rotation = Quaternion.Lerp(transform.rotation, rotate, Time.deltaTime * );
//播放行走动画
transform.animation.Play("walk");
enemState = STATE_WALK;
} }
}
switch (enemState)
{
case STATE_STAND: break;
case STATE_WALK:
//敌人行走
transform.Translate(Vector3.forward * Time.deltaTime);
//gameObject.animation.Play("walk");
break;
case STATE_RUN:
//敌人朝向主角奔跑,当相距2时,就不向前跑了
if (Vector3.Distance(transform.position, hero.transform.position) > )
{
transform.Translate(Vector3.forward * Time.deltaTime * );
}
break;
}
}
void OnGUI()
{
if (showBlood)//如果绘制血条
{
//绘制生命值贴图
GUI.DrawTexture(new Rect(, , tex_hp.width, tex_hp.height), tex_hp);
//绘制主角生命值
Tools.DrawImageNumber(, , HP, texmube); //绘制敌人血条
int blood_width = tex_red.width * HP / ;
//绘制黑色血条 即底色
GUI.DrawTexture(new Rect(, , tex_black.width, tex_black.height), tex_black);
//绘制红色血条
GUI.DrawTexture(new Rect(, , blood_width, tex_red.height), tex_red);
}
} /// <summary>
/// 当在敌人上单击鼠标左键
/// </summary>
void OnMouseDown()
{
//击中敌人目标
if (HP > )
{
//减掉5点血
HP -= ;
//被击打时,后退
transform.Translate(Vector3.back * );
//击中敌人后立即进入战斗状态
ishatred = true;
}
else//敌人死亡
{
//敌人死亡
Destroy(gameObject);
//发送死亡消息
hero.SendMessage("EnemyHurt");
}
}
void OnMouseUp()
{
//击打后退还原
transform.Translate(Vector3.forward * Time.deltaTime * );
}
void OnMouseOver()
{
//开始绘制血条
showBlood = true;
}
void OnMouseExit()
{
//结束绘制血条
showBlood = false;
}
}

Game

 using UnityEngine;
using System.Collections; public class Game : MonoBehaviour
{
/*===============================
* 主角脚本
*==============================*/ //游戏状态机 //游戏中状态
public const int STATE_GAME = ;
//游戏胜利状态
public const int STATE_WIN = ;
//游戏失败状态
public const int STATE_LOSE = ; //枚举角色鼠标位置
public enum RotationAxes { MouseXAndY = , MouseX = , MouseY = }
public RotationAxes axes = RotationAxes.MouseXAndY;
float rotationY = 0f; //鼠标准心
public Texture2D tex_fire; //血条资源贴图
public Texture2D tex_red;
public Texture2D tex_black; //生命值贴图
public Texture2D tex_hp; //战斗胜利资源贴图
public Texture2D tex_win;
//战斗失败资源贴图
public Texture2D tex_lose;
//游戏音乐资源
public AudioSource music; //主角生命值
public int HP = ; //图片数字资源
Object[] texmuber; //当前游戏状态
int gameState; // Use this for initialization
void Start()
{
//取消默认鼠标图标
Screen.showCursor = false;
//读取图片资源
texmuber = Resources.LoadAll("number");
//设置默认状态为游戏中
gameState = STATE_GAME; if (rigidbody) //如果是刚体
/*
如果freezeRotation被启用,旋转不会被物体模拟修改。
* 这对于创建第一人称射击游戏时是很有用的,因为玩家需要使用鼠标完全控制旋转。
*/
rigidbody.freezeRotation = true;////冻结旋转
} // Update is called once per frame
void Update()
{
switch (gameState)
{
case STATE_GAME: UpdateGame(); break;
case STATE_WIN:
case STATE_LOSE:
if (Input.GetKey(KeyCode.Escape))
{
Application.LoadLevel("Menu");
}
break;
default:
break;
}
} void OnGUI()
{
switch (gameState)
{
case STATE_GAME:
RenderGame();
break;
case STATE_WIN:
GUI.DrawTexture(new Rect(, , tex_win.width, tex_win.height), tex_win);
break;
case STATE_LOSE:
GUI.DrawTexture(new Rect(, , tex_lose.width, tex_lose.height), tex_lose);
break;
default:
break;
}
} private void RenderGame()
{
if (tex_fire)
{
//绘制鼠标准心
float x = Input.mousePosition.x - tex_fire.width / ;
float y = Screen.height - Input.mousePosition.y - tex_fire.width / ; GUI.DrawTexture(new Rect(x, y, tex_fire.width, tex_fire.height), tex_fire);
} //绘制主角血条
int blood_width = tex_red.width * HP / ;
GUI.DrawTexture(new Rect(, Screen.height - , tex_black.width, tex_black.height), tex_black);
GUI.DrawTexture(new Rect(, Screen.height - , blood_width, tex_red.height), tex_red); //绘制生命值贴图
GUI.DrawTexture(new Rect(, Screen.height - , tex_hp.width, tex_hp.height), tex_hp); //绘制主角生命值
Tools.DrawImageNumber(, Screen.height - , HP, texmuber);
} /// <summary>
/// 主角被攻击
/// </summary>
void HeroHurt()
{
HP--;
if (HP <= )
{
HP = ;
gameState = STATE_LOSE; //游戏失败
}
} /// <summary>
/// 碰到道具血条加血
/// </summary>
void HeroAddBlood()
{
HP += ;
if (HP >= )
{
HP = ;
}
}
/// <summary>
/// 敌人被攻击
/// </summary>
void EnemyHurt()
{
//找到所有的NPC
GameObject[] enemy = GameObject.FindGameObjectsWithTag("enemy");
//Debug.Log(enemy.Length); //敌人对象数字长度为1表示敌人全部死亡
if (enemy.Length == )
{ gameState = STATE_WIN;
}
}
private void UpdateGame()
{
if (Input.GetKey(KeyCode.Escape))
{
Application.LoadLevel("Menu");
}
//计算摄像机旋转
if (axes == RotationAxes.MouseX)
{
//旋转角色
transform.Rotate(, Input.GetAxis("Mouse X"), );
}
else
{
//设置角色欧拉角
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, );
}
} /// <summary>
/// 在移动的时,当controller碰撞到collider时OnControllerColliderHit被调用。
/// </summary>
/// <param name="hit"></param>
void OnControllerColliderHit(ControllerColliderHit hit)
{
//获取角色控制器碰撞到的游戏对象
GameObject collObj = hit.gameObject; //是否为加血的箱子对象
if (collObj.name == "Cube")
{
//主角加血
HeroAddBlood();
//销毁箱子
Destroy(collObj);
}
} }

Menu

 using UnityEngine;
using System.Collections; public class Menu : MonoBehaviour { /*===============================
* 主菜单脚本
*==============================*/ //游戏界面状态机 //主菜单界面
public const int STATE_MAINMENU = ;
//游戏设置界面
public const int STATE_OPTION = ;
//游戏帮助界面
public const int STATE_HELP = ;
//游戏退出界面
public const int STATE_EXIT = ;
//GUI皮肤
public GUISkin mySkin; //游戏背景贴图
public Texture textureBG;
//开始菜单贴图
public Texture tex_startInfo;
//帮助菜单贴图
public Texture tex_helpInfo; //游戏音乐资源
public AudioSource music;
//当前游戏状态
private int gameState; // Use this for initialization
void Start()
{
//初始化游戏状态为主菜单界面
gameState = STATE_MAINMENU;
} // Update is called once per frame
void Update()
{ }
void OnGUI()
{
switch (gameState)
{
case STATE_MAINMENU:
//绘制主菜单界面
RenderMainMenu();
break;
case STATE_OPTION:
//绘制游戏设置界面
RenderOption();
break;
case STATE_HELP:
//绘制游戏帮助界面
RenderHelp();
break;
case STATE_EXIT:
//绘制游戏退出界面
//目前直接关闭并退出游戏
break;
default:
break;
}
}
/// <summary>
/// 绘制游戏帮助界面
/// </summary>
private void RenderHelp()
{
GUI.skin = mySkin;
GUI.DrawTexture(new Rect(, , Screen.width, Screen.height), tex_helpInfo);
//返回按钮
if (GUI.Button(new Rect(, , , ), "", "back"))
{
gameState = STATE_MAINMENU;
}
}
/// <summary>
/// 绘制游戏设置界面
/// </summary>
private void RenderOption()
{
GUI.skin = mySkin;
GUI.DrawTexture(new Rect(, , Screen.width, Screen.height), textureBG); //开启音乐按钮
if (GUI.Button(new Rect(, , , ), "", "music_on"))
{
if (!music.isPlaying)
{
//播放音乐
music.Play();
}
}
//关闭音乐按钮
if (GUI.Button(new Rect(, , , ), "", "music_off"))
{
//关闭音乐
music.Stop();
}
//返回按钮
if (GUI.Button(new Rect(, , , ), "", "back"))
{
gameState = STATE_MAINMENU;
}
}
/// <summary>
/// 绘制主菜单界面
/// </summary>
private void RenderMainMenu()
{
//设置界面皮肤
GUI.skin = mySkin;
//绘制游戏背景图
GUI.DrawTexture(new Rect(, , Screen.width, Screen.height), textureBG); //开始游戏按钮
if (GUI.Button(new Rect(, , , ), "", "start"))
{
//进入开始游戏状态
Application.LoadLevel("Game");
}
//游戏选项按钮
if (GUI.Button(new Rect(, , , ), "", "option"))
{
//处于开始游戏状态
gameState = STATE_OPTION;
}
//游戏帮助按钮
if (GUI.Button(new Rect(, , , ), "", "help"))
{
//进入游戏帮助状态
gameState = STATE_HELP;
}
//游戏退出按钮
if (GUI.Button(new Rect(, , , ), "", "exit"))
{
//退出游戏
Application.Quit();
}
}
}

Tools

 

 using UnityEngine;
using System.Collections; public class Tools : MonoBehaviour
{ /*===============================
* 工具脚本
*==============================*/ /// <summary>
///
/// </summary>
/// <param name="x">绘制数字 x坐标</param>
/// <param name="y">绘制数字 y坐标</param>
/// <param name="number">需要绘制的数字</param>
/// <param name="texnumber">绘制图片数组资源</param>
public static void DrawImageNumber(int x, int y, int number, Object[] texnumber)
{
//将整数数据转换为字符数组
char[] chars = number.ToString().ToCharArray();
//计算图片的宽度与高度,因为每张图片都是一样大。所以这里获取第一张即可
Texture2D tex = (Texture2D)texnumber[];
int width = tex.width;
int height = tex.height; //遍历字符数组
foreach (char item in chars)
{
//得到每一位整型数组
int i = int.Parse(item.ToString());
//绘制图片数字
GUI.DrawTexture(new Rect(x, y, width, height), texnumber[i] as Texture2D);
x += width;
}
} }

注意事项:NPC需要添加标签:enemy

游戏源码:

http://pan.baidu.com/s/1ntmOQnf