12.开始场景-选角界面-逻辑处理
12.1 知识点
创建选角界面ChoosePanel脚本继承面板基类挂载到选角面板控件,添加各个按钮和模型父对象变量,下方属性相关对象,并关联。在选角界面ChoosePanel脚本中,初始化各个按钮的监听事件。点击左右按钮时,更改游戏数据管理器中的当前选角索引,并切换当前飞机角色的模型和数据。创建一个GameObject对象来存储当前的飞机预制体对象。封装一个方法来切换当前选择的飞机和删除上一个飞机模型。在切换当前选择的飞机的方法中,调用游戏数据管理器中获取当前选择角色数据的方法。删除上一个飞机模型后,根据得到的角色数据重新实例化飞机模型,并设置位置、角度、缩放等属性,修改显示层级。最后设置血量,速度,体积的属性。在删除上一个飞机模型的方法中,对当前飞机预制体对象进行判空操作,如果不为空则删除对象并置空。重写显示面板和隐藏面板方法,在显示面板时调用切换当前选择的飞机的方法,在隐藏面板时调用删除上一个飞机模型的方法。完成所有方法后,完善各个按钮的监听事件。左右按钮事件监听中要判断当前选择飞机所索引有没有索引越界。开始按钮和关闭按钮分别添加切换场景和关闭选角面板的监听。
public class ChoosePanel : BasePanel<ChoosePanel>
{
//各个按钮
public UIButton btnClose; // 关闭按钮
public UIButton btnLeft; // 左按钮
public UIButton btnRight; // 右按钮
public UIButton btnStart; // 开始按钮
//模型父对象
public Transform heroPos; // 模型父对象
//下方属性相关对象
public List<GameObject> hpObjs; // 血量对象列表
public List<GameObject> speedObjs; // 速度对象列表
public List<GameObject> volumeObjs; // 音量对象列表
//当前显示的飞机模型对象
private GameObject airPlaneObj; // 当前显示的飞机模型对象
public Camera uiCamera; // UI相机
public override void Init()
{
//选择角色后 点击开始 切场景
btnStart.onClick.Add(new EventDelegate(() =>
{
SceneManager.LoadScene("GameScene"); // 加载游戏场景
}));
btnLeft.onClick.Add(new EventDelegate(() =>
{
//左按钮 减我们的索引
--GameDataMgr.Instance.nowSelHeroIndex;
//如果 小于最小的索引了 直接等于 最后一个索引
if (GameDataMgr.Instance.nowSelHeroIndex < 0)
GameDataMgr.Instance.nowSelHeroIndex = GameDataMgr.Instance.roleData.roleList.Count - 1;
ChangeNowHero(); // 切换当前选择的英雄
}));
btnRight.onClick.Add(new EventDelegate(() =>
{
//右按钮 加我们的索引
++GameDataMgr.Instance.nowSelHeroIndex;
//如果 大于最大的索引了 直接等于 0
if (GameDataMgr.Instance.nowSelHeroIndex >= GameDataMgr.Instance.roleData.roleList.Count)
GameDataMgr.Instance.nowSelHeroIndex = 0;
ChangeNowHero(); // 切换当前选择的英雄
}));
btnClose.onClick.Add(new EventDelegate(() =>
{
//隐藏自己
HideMe();
//显示开始界面
BeginPanel.Instance.ShowMe();
}));
HideMe();
}
public override void ShowMe()
{
base.ShowMe();
//每次显示的时候 都从第一个开始选择
GameDataMgr.Instance.nowSelHeroIndex = 0;
ChangeNowHero(); // 切换当前选择的英雄
}
public override void HideMe()
{
base.HideMe();
//删除当前的模型
DestroyObj();
}
//切换当前的选择
private void ChangeNowHero()
{
//得到当前选择的 玩家英雄数据
RoleInfo info = GameDataMgr.Instance.GetNowSelHeroInfo();
//更新模型
//先删除上一次的飞机模型
DestroyObj();
//再创建当前的飞机模型
airPlaneObj = Instantiate(Resources.Load<GameObject>(info.resName));
//设置父对象
airPlaneObj.transform.SetParent(heroPos, false);
//设置角度和位置 缩放
airPlaneObj.transform.localPosition = Vector3.zero;
airPlaneObj.transform.localRotation = Quaternion.identity;
airPlaneObj.transform.localScale = Vector3.one * info.scale;
//修改层级
airPlaneObj.layer = LayerMask.NameToLayer("UI");
//更新属性
for (int i = 0; i < 10; i++)
{
hpObjs[i].SetActive(i < info.hp);
speedObjs[i].SetActive(i < info.speed);
volumeObjs[i].SetActive(i < info.volume);
}
}
/// <summary>
/// 用于删除上一次显示的模型对象
/// </summary>
private void DestroyObj()
{
if (airPlaneObj != null)
{
Destroy(airPlaneObj);
airPlaneObj = null;
}
}
}
开始面板的点击开始按钮监听中添加显示选角面板的实际代码
//监听按钮事件
btnBegin.onClick.Add(new EventDelegate(()=> {
//显示 选角面板
ChoosePanel.Instance.ShowMe();
//隐藏自己
HideMe();
}));
在ChoosePanel脚本的Update中给飞机增加上下浮动的效果。可以用到三角函数API。增加让飞机可以点击选中飞机旋转的效果。添加射线检测的逻辑,当按下鼠标左键且射线检测到碰撞体时,说明已经选中,可以用四元数旋转飞机模型。松开鼠标取消选择。注意,发出射线的摄像机要是NGUI摄像机,不然有可能被东西挡住。可以设置变量拖拽获取。
public Camera uiCamera; // UI相机
private float time;
//是否鼠标选中 模型
private bool isSel;
void Update()
{
//让飞机 上下浮动
time += Time.deltaTime;
//注意设置位置的时候要用世界坐标,因为当前角色模型父对象HeroPos是有角度偏移的
heroPos.Translate(Vector3.up * Mathf.Sin(time) * 0.0001f, Space.World);
//射线检测 让飞机 可以左右转动
if (Input.GetMouseButtonDown(0))
{
//如果点击到了 UI层碰撞器 认为需要开始 拖动 飞机了
if (Physics.Raycast(uiCamera.ScreenPointToRay(Input.mousePosition),
1000,
1 << LayerMask.NameToLayer("UI")))
{
isSel = true;
}
}
//抬起 取消选中
if (Input.GetMouseButtonUp(0))
isSel = false;
//旋转对象
if (Input.GetMouseButton(0) && isSel)
{
heroPos.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 20, Vector3.up);
}
}
12.2 知识点代码
ChoosePanel
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ChoosePanel : BasePanel<ChoosePanel>
{
//各个按钮
public UIButton btnClose; // 关闭按钮
public UIButton btnLeft; // 左按钮
public UIButton btnRight; // 右按钮
public UIButton btnStart; // 开始按钮
//模型父对象
public Transform heroPos; // 模型父对象
//下方属性相关对象
public List<GameObject> hpObjs; // 血量对象列表
public List<GameObject> speedObjs; // 速度对象列表
public List<GameObject> volumeObjs; // 音量对象列表
//当前显示的飞机模型对象
private GameObject airPlaneObj; // 当前显示的飞机模型对象
public override void Init()
{
//选择角色后 点击开始 切场景
btnStart.onClick.Add(new EventDelegate(() =>
{
SceneManager.LoadScene("GameScene"); // 加载游戏场景
}));
btnLeft.onClick.Add(new EventDelegate(() =>
{
//左按钮 减我们的索引
--GameDataMgr.Instance.nowSelHeroIndex;
//如果 小于最小的索引了 直接等于 最后一个索引
if (GameDataMgr.Instance.nowSelHeroIndex < 0)
GameDataMgr.Instance.nowSelHeroIndex = GameDataMgr.Instance.roleData.roleList.Count - 1;
ChangeNowHero(); // 切换当前选择的英雄
}));
btnRight.onClick.Add(new EventDelegate(() =>
{
//右按钮 加我们的索引
++GameDataMgr.Instance.nowSelHeroIndex;
//如果 大于最大的索引了 直接等于 0
if (GameDataMgr.Instance.nowSelHeroIndex >= GameDataMgr.Instance.roleData.roleList.Count)
GameDataMgr.Instance.nowSelHeroIndex = 0;
ChangeNowHero(); // 切换当前选择的英雄
}));
btnClose.onClick.Add(new EventDelegate(() =>
{
//隐藏自己
HideMe();
//显示开始界面
BeginPanel.Instance.ShowMe();
}));
HideMe();
}
public override void ShowMe()
{
base.ShowMe();
//每次显示的时候 都从第一个开始选择
GameDataMgr.Instance.nowSelHeroIndex = 0;
ChangeNowHero(); // 切换当前选择的英雄
}
public override void HideMe()
{
base.HideMe();
//删除当前的模型
DestroyObj();
}
//切换当前的选择
private void ChangeNowHero()
{
//得到当前选择的 玩家英雄数据
RoleInfo info = GameDataMgr.Instance.GetNowSelHeroInfo();
//更新模型
//先删除上一次的飞机模型
DestroyObj();
//再创建当前的飞机模型
airPlaneObj = Instantiate(Resources.Load<GameObject>(info.resName));
//设置父对象
airPlaneObj.transform.SetParent(heroPos, false);
//设置角度和位置 缩放
airPlaneObj.transform.localPosition = Vector3.zero;
airPlaneObj.transform.localRotation = Quaternion.identity;
airPlaneObj.transform.localScale = Vector3.one * info.scale;
//修改层级
airPlaneObj.layer = LayerMask.NameToLayer("UI");
//更新属性
for (int i = 0; i < 10; i++)
{
hpObjs[i].SetActive(i < info.hp);
speedObjs[i].SetActive(i < info.speed);
volumeObjs[i].SetActive(i < info.volume);
}
}
/// <summary>
/// 用于删除上一次显示的模型对象
/// </summary>
private void DestroyObj()
{
if (airPlaneObj != null)
{
Destroy(airPlaneObj);
airPlaneObj = null;
}
}
public Camera uiCamera; // UI相机
private float time;
//是否鼠标选中 模型
private bool isSel;
void Update()
{
//让飞机 上下浮动
time += Time.deltaTime;
//注意设置位置的时候要用世界坐标,因为当前角色模型父对象HeroPos是有角度偏移的
heroPos.Translate(Vector3.up * Mathf.Sin(time) * 0.0001f, Space.World);
//射线检测 让飞机 可以左右转动
if (Input.GetMouseButtonDown(0))
{
//如果点击到了 UI层碰撞器 认为需要开始 拖动 飞机了
if (Physics.Raycast(uiCamera.ScreenPointToRay(Input.mousePosition),
1000,
1 << LayerMask.NameToLayer("UI")))
{
isSel = true;
}
}
//抬起 取消选中
if (Input.GetMouseButtonUp(0))
isSel = false;
//旋转对象
if (Input.GetMouseButton(0) && isSel)
{
heroPos.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 20, Vector3.up);
}
}
}
BeginPanel
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 开始界面
/// </summary>
public class BeginPanel : BasePanel<BeginPanel>
{
public UIButton btnBegin;
public UIButton btnRank;
public UIButton btnSetting;
public UIButton btnQuit;
public override void Init()
{
//监听按钮事件
btnBegin.onClick.Add(new EventDelegate(() => {
//显示 选角面板
ChoosePanel.Instance.ShowMe();
//隐藏自己
HideMe();
}));
btnRank.onClick.Add(new EventDelegate(() => {
//显示 排行榜
RankPanel.Instance.ShowMe();
}));
btnSetting.onClick.Add(new EventDelegate(() => {
//显示 设置面板
SettingPanel.Instance.ShowMe();
}));
btnQuit.onClick.Add(new EventDelegate(() => {
//退出游戏
Application.Quit();
}));
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com