城市激斗
- 一、简介
- 1、所需知识点
- 2、游戏需求
- 二、开始界面
- 1、开始界面按钮功能代码
一、简介
1、所需知识点
(1)射线检测
(2)Mecanim动画系统
(3)Navigation寻路系统
(4)OGUI
(5)欧拉角与四元数、向量
(6)持久化数据
2、游戏需求
(1)开始界面(人物换装),到游戏场景角色诞生,诞生的角色穿着换装界面存储的服装。
(2)随机在3个诞生点,一共产生3波怪(每波怪2-3个即可)。
(3)怪物头顶有血条,随着波数的累加怪物越来越难打(血量多)。
(4)角色与怪之间动画互动(Mecanim动画系统),如:角色射线打到怪物,角色播放攻击动画,怪播放受到攻击的动画。
(5)敌人,角色血条效果。
(6)打敌人,随机产生掉装备,吃到掉的装备可实现例如加血的效果。
(7)打死3波怪后胜利画面,自己血条值为0时GameOver画面 。
二、开始界面
先上图,看看最终完成是什么样的!
在点击不同的按钮有不同的事件响应,按钮功能就不进行说明了。
按钮功能实现逻辑: 以上按钮可以分为四种按钮,分别是角色选择、服装选择、武器选择、动作预览。
那么我们就可以按这四种分类将功能进行实现,创建一个空物体,将一个种类的按钮作为此空物体的孩子,编写的脚本就给予空物体,那么给按钮添加事件就需要遍历所有的子物体,然后添加按钮点击事件。而点击按钮需要实现功能,我就拿角色选择按钮来举例,另外三种按钮的脚本可以仿照此逻辑进行编写;
角色选择按钮功能实现: 在点击按钮后,我需要进行角色物体的创建,那么按钮和预制件之间就需要有响应,那么如何根据我们点击的按钮来创建指定的角色呢?我们可以通过按钮名字与预制件名字来进行联系,将按钮名字设置成为预制件的名字 (按钮名字也可以不和预制件名字相同,但是必须包含预制件名字),那么功能的实现就比较简单了,可以创建字典,key值为按钮名字,value值为gameobject类型,存储角色预制件,那么我们在点击按钮的时候就可以根据按钮名字直接获取预制件进行创建角色物体了。另三种按钮功能请自行类推了~
温馨提示:代码编写当中的细节问题在代码注释中有说明
1、开始界面按钮功能代码
- 角色选择功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class GenerateRole : MonoBehaviour
{
public GameObject[] gameRole;
public Transform vec;
private Dictionary<string,GameObject> dic;
public static GameObject Role { get; set; }
public GenerateRole() { }
private void Start()
{
//初始化字典
dic = new Dictionary<string, GameObject>();
//遍历所有的孩子,给按钮添加点击事件
AddEevent();
}
//因按钮和预制件的名字不一样
//所以需要对name进行切割
private void GetButtonName()
{
var button = EventSystem.current.currentSelectedGameObject;
CreateRole(button.name.Substring(4));
}
//遍历所有孩子添加,给按钮添加点击时间
private void AddEevent()
{
string name;
for (int i=0;i<transform.childCount;i++)
{
name = transform.GetChild(i).name.Substring(4);
//将游戏物体添加至字典当中
//每次点击按钮,就将按钮的名字和游戏物体存入字典
//避免重复点击按钮时,需要重复遍历
for (int x=0;x<gameRole.Length;x++)
{
if (gameRole[x].name == name)
{
dic.Add(name,gameRole[x]);
}
}
transform.GetChild(i).GetComponent<Button>().onClick
.AddListener(new UnityAction(GetButtonName));
}
}
//创建游戏物体
private void CreateRole(string name)
{
//如果vec有孩子,则销毁后再创建,如果没有则直接创建
GameObject deleteClone;
int childCount = vec.childCount;
if (childCount==1)
{
//若是创建的游戏物体就是这个孩子,则不进行任何代码执行
//因名字包含Clone,所以还需要对名字进行改变再判断
//Debug.Log(vec.GetChild(0).name);
if (vec.GetChild(0).name==(name+"(Clone)"))
{
return;
}
deleteClone = vec.GetChild(0).gameObject;
Destroy(deleteClone);
SetParent(name);
}
else if (childCount == 0)
{
SetParent(name);
}
}
private void SetParent(string name)
{
GameObject clone = Instantiate(dic[name], vec.position, Quaternion.identity);
Role = clone;
//将创建的游戏物体设置为vic的子类
clone.transform.SetParent(vec);
}
}
- 武器选择功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class WeaponChose : MonoBehaviour
{
//创建武器位置
private Transform weaponLocal;
public GameObject[] weapons;
private Dictionary<string, GameObject> dic;
private void Start()
{
//字典进行初始化
dic = new Dictionary<string, GameObject>();
AddEvent();
DicAddWeapon();
}
//遍历所有孩子,添加按钮点击事件
/// <summary>
/// 添加点击事件
/// </summary>
private void AddEvent()
{
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetComponent<Button>().onClick
.AddListener(new UnityAction(CreateWeapon));
}
}
//将所有武器类型添加进入字典当中
private void DicAddWeapon()
{
string name;
for (int i = 0; i < transform.childCount; i++)
{
name = transform.GetChild(i).name.Substring(4);
for (int index = 0; index < transform.childCount; index++)
{
if (name == weapons[index].name)
{
dic.Add(name, weapons[index]);
}
}
}
}
//点击事件
//根据按钮的名字来创建武器
/// <summary>
/// 创建武器
/// </summary>
private GameObject clone;
private void CreateWeapon()
{
//按钮名字
string buttonName = EventSystem.current.currentSelectedGameObject.name.Substring(4);
//给武器寻找位置
weaponLocal = GameObject.Find("wphand").transform;
if (weaponLocal != null)
{
//如果wphand不存在孩子,则直接创建,否则进行二次判断
if (weaponLocal.childCount == 1)
{
//如果孩子的名字就是所点击按钮的名字,那么就直接结束程序
if (weaponLocal.GetChild(0).name == (buttonName + "(Clone)"))
{
return;
}
//否则进行武器的创建,并销毁原来的物体
Destroy(clone);
SetParent(buttonName);
}
else
//进行名字切割并创建武器
SetParent(buttonName);
}
else Debug.Log("请先创建游戏角色");
}
private void SetParent(string buttonName)
{
clone = Instantiate(dic[buttonName], weaponLocal.position, Quaternion.Euler(180, -105, 0));
clone.transform.SetParent(weaponLocal);
}
}
- 服装选择功能
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ChoseCloth : MonoBehaviour
{
//获取的名字是带有Clone的,需要进行处理
private GameObject role;
public Texture[] cloths;
private Dictionary<string, Dictionary<string, Texture>> dic;
// private Renderer rend;
//数据初始化
private void Start()
{
dic = new Dictionary<string, Dictionary<string, Texture>>();
DicAddCloth();
AddButtonEvent();
}
private void DicAddCloth()
{
int index = 0;
//存储的种类名字,四种衣服
string[] clothname=new string[4];
string[] name;
string newName = null;
//遍历cloths数组,将其添加至二维数组
foreach (Texture cloth in cloths)
{
//衣服名字格式为mon_goblinWizard_c2_df
//将名字切割,取第二个goblinWizard,再加上(Clone),再为其添加衣服
name = cloth.name.Split('_');
if (Array.IndexOf(clothname, name[1])==-1)
{
clothname[index++] = name[1];
dic.Add(name[1], new Dictionary<string, Texture>());
//Debug.Log("clothname:"+name[1]);
}
dic[name[1]].Add((dic[name[1]].Count+1)+"", cloth);
// Debug.Log(newName[1]);
}
}
private void AddButtonEvent()
{
for (int i=0;i<transform.childCount;i++)
{
transform.GetChild(i).GetComponent<Button>().onClick.AddListener
(new UnityAction(ButtonEvent));
}
}
/// <summary>
/// 触发事件,更换衣服
/// </summary>
private void ButtonEvent()
{
//获取角色
role = GenerateRole.Role;
//根据按钮名字来更换衣服
string buttonName = EventSystem.current.currentSelectedGameObject.name;
//按钮名字格式为btn_col_02
//获取最后一个数字即可
string clothName = buttonName.Substring(buttonName.Length-1);
if (role != null)
{
//将role.name的名字进行切割
string[] RoleName = role.name.Split('(');
string[] RoleName01 = RoleName[0].Split('_');
//Debug.Log("衣服名字"+clothName);
//Debug.Log("角色名字" + role.name);
//Debug.Log("种类名字:"+ RoleName01[1]);
role.GetComponentInChildren<SkinnedMeshRenderer>().material.mainTexture
= dic[RoleName01[1]][clothName];
}
else { Debug.Log("请先创建游戏角色"); }
}
}
- 动作预览功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ActionPlay : MonoBehaviour
{
//获取游戏对象
private GameObject role;
private Animation ani;
private void Start()
{
AddEvent();
}
//给每个按钮添加点击事件
private void AddEvent()
{
for (int i=0;i<transform.childCount;i++)
{
transform.GetChild(i).GetComponent<Button>().onClick.
AddListener(new UnityAction(PlayAction));
}
}
/// <summary>
/// 播放动画
/// </summary>
private void PlayAction()
{
role = GenerateRole.Role;
string buttonName = EventSystem.current.currentSelectedGameObject.name;
string[] newName = null;
if (role!=null)
{
ani = role.GetComponent<Animation>();
newName = buttonName.Split('_');
ani.Play(newName[newName.Length-1]);//字符串为按钮名字切割后的字符串
ani.CrossFadeQueued("Idle");
}
}
}
人物模型连接(含UI贴图)------MonsterBaseTeam.rar
其他功能的实现请见 Unity3D-----简易游戏项目开发02
Unity3D-----简易游戏项目开发02