–整理0404
Visual Studio2013
Unity5.6.1f1
**
一、准备工作:
**
(1)创建一个场景S003:在Hierarchy面板中写入LocalManager文件,写入ResourcesManager与CanvasManager.分别挂上LoadRes脚本与CanvasManagerEX脚本。(此步之前笔记讲过,用来管理资源与Canvas)
(2)加入所用资源:Image->Resources->图片003
(3)创建人物Player:在Canvas下创建,UI->Image。将图片资源拖入后,创建预制体Player。(将Canvas下的Player拖入PreFab的Resources中)
二、.编写控制人物移动的脚本:MoveControl.C#
通过调整Transform组件的属性实现游戏对象的移动。以下是需要了解的几个函数与结构体。
(1)Translate函数
Translate函数用于处理游戏对象移动。
this.Translate(移动方向 * 速度 * 前进/后退方向 * Time.deltaTime, 基准坐标系);
1)Time.deltaTime表示前一帧到当前帧或非的时间,
2)使用Transform组件 ,游戏对象移动的逻辑必须乘以deltaTime,使游戏对象的移动速度不受帧率的影响,而根据某个固定的速度移动。
3)乘以Time.deltaTime,游戏对象将以每秒1各单位的速度前进)
4)将向量单位乘以速度(speed),表示按照speed变量指定的速度移动。
(2)Vector3(x, y, z)是unity提供的用于保存三维坐标值和向量数据的结构体。
(3)键盘的输入:GetKey(用户长按按键有效),GetKeyDown(用户按下按键时有效),GetKeyUp(用户抬起按键时有效)三个方法分别获取用户键盘按键的输入
以下是控制移动的代码。
if (Input.GetKeyDown(KeyCode.Space))
{
frameTime = 0;
isJump = true;
}
else if (Input.GetKey(KeyCode.S))
{
print("move s");
this.transform.Translate(Vector3.back * Time.deltaTime * speed);
}
else if (Input.GetKey(KeyCode.A))
{
print("move a");
this.transform.Translate(Vector3.left * Time.deltaTime * speed);
}
else if (Input.GetKey(KeyCode.D))
{
print("move d");
this.transform.Translate(Vector3.right * Time.deltaTime * speed);
}
其中,控制角色跳跃,需要利用弹道/抛物线s=ut+1/2at²。当按下空格键时,角色跳跃呈开口向下的抛物线,至最高点后下落,返回至地面。在跳跃过程中,设生命线为frameTime。设抛物线的两个零点是0与0.6,也就是跳跃过程的生命线应小于0.6。在跳跃过程中,角色y值发生改变。由函数getY()得到y的变化值与返回布尔类型的isEnd。
float a = 18.5f;
float h = 6.66f;
bool isJump = false;
public float getY(float t, out bool isEnd)
{
if (t < 0.6)
{
isEnd = false;
}
else
{
isEnd = true;
}
if (t > 0.6)
{
return 0;
}
//带入两个零点解方程,计算出a,h的值
float y = 0.45f - 5 * (t - 0.3f) * (t - 0.3f);
return y;
}
在Start()中定义isJump 判断是否跳跃,并存贮初始y值。
isJump = false;
initposy = this.transform.position.y;
//将初始y值存储起来
在定义跳跃的代码中,初始frameTime = 0; isJump = true;
当 isJump = true;开始跳跃过程,实时时间frameTime+= Time.deltaTime;当frameTime>0.6,生命线结束,isEnd=true;
当getY()返回isEnd为true时,表示frameTime>0.6,跳跃过程结束。
if (isJump == true)
{
frameTime += Time.deltaTime;
//生命线frameTime
if (frameTime > 0.6f)
{
isEnd = true;
}
float y = getY(frameTime, out isEnd);
this.transform.position = (new Vector3(this.transform.position.x, y * 100 + initposy, this.transform.position.z));
if (isEnd == true)
{
isJump = false;
}
Debug.Log(y);
}
定义子弹发射,当按下k键时,发射子弹。其实就是按下k键,生成一个GameObject子弹对象。并定义生成后的位置。
此处,通过字典查找资源boom。
if (Input.GetKeyDown(KeyCode.K))
{
Debug.Log("按下了K");
GameObject g = GameObject.Instantiate(LoadRes.getPrefab(ResName.boom
), CanvasManagerEX.canvas1.transform);
//生成后重新定义位置
g.GetComponent().localPosition = this.GetComponent().localPosition;
}
定义预制体字典prefabDic:
1.生成字典prefabDic
//****1.生成字典prefabDic****
static Dictionary<string, GameObject> prefabDic = new Dictionary<string, GameObject>();
//****2.生成字典资源spDic****
static Dictionary<string, Sprite> spDic = new Dictionary<string, Sprite>();
2.对字典prefabDic进行封装
//在另一个脚本里面 定义资源字符串ResName,调用时用ResName.boom
//*****对字典进行封装******
// PrefaDic字典返回
public static GameObject getPrefab(string key)
{
return prefabDic[key];
}
// PrefaDic字典add
public void save2PrefaDic(string key, GameObject value)
{
if (prefabDic.ContainsKey(key) == true)
{
return;
}
prefabDic.Add(key, value);
}
3.添加键入PrefaDic字典
void Awake()
{
Debug.Log("w");
//PrefaDic字典add过程
save2PrefaDic(ResName.boom, Resources.Load<GameObject>(ResName.boom));
save2PrefaDic(ResName.Magic0, Resources.Load<GameObject>(ResName.Magic0));
save2PrefaDic(ResName.Magic1, Resources.Load<GameObject>(ResName.Magic1));
save2PrefaDic(ResName.Magic2, Resources.Load<GameObject>(ResName.Magic2));
save2PrefaDic(ResName.Magic3, Resources.Load<GameObject>(ResName.Magic3));
save2PrefaDic(ResName.Magic4, Resources.Load<GameObject>(ResName.Magic4));
instance = this;
}
三、发射子弹fps序列帧
1.找到几张子弹爆炸的动画图片,添加到PrefaDic字典。在spDic字典中加入存放爆炸图片的列表list进行调用。
// 定义资源字符串ResName,调用时用ResName.boom
//List类型的 getSp()
public static List<Sprite> getSp(List<string> key)
{
List<Sprite> list = new List<Sprite>();
foreach (string _key in key)
{
list.Add(getSp(_key));
}
return list;
}
//spDic字典(面向对象) 封装getSp,返回键值
public static Sprite getSp(string key)
{
//key不存在时不报错
if (spDic.ContainsKey(key) == true)
{
return spDic[key];
}
else
{
return null;
}
}
void Awake()
{
Debug.Log("w");
//PrefaDic字典add过程,add 爆炸图片
save2PrefaDic(ResName.Magic0, Resources.Load<GameObject>(ResName.Magic0));
save2PrefaDic(ResName.Magic1, Resources.Load<GameObject>(ResName.Magic1));
save2PrefaDic(ResName.Magic2, Resources.Load<GameObject>(ResName.Magic2));
save2PrefaDic(ResName.Magic3, Resources.Load<GameObject>(ResName.Magic3));
save2PrefaDic(ResName.Magic4, Resources.Load<GameObject>(ResName.Magic4));
instance = this;
//spDic字典add过程
spDic.Add(ResName.Magic0, Resources.Load<Sprite>(ResName.Magic0));
spDic.Add(ResName.Magic1, Resources.Load<Sprite>(ResName.Magic1));
spDic.Add(ResName.Magic2, Resources.Load<Sprite>(ResName.Magic2));
spDic.Add(ResName.Magic3, Resources.Load<Sprite>(ResName.Magic3));
spDic.Add(ResName.Magic4, Resources.Load<Sprite>(ResName.Magic4));
//存入list
ResName.list.Add(ResName.Magic0);
ResName.list.Add(ResName.Magic1);
ResName.list.Add(ResName.Magic2);
ResName.list.Add(ResName.Magic3);
ResName.list.Add(ResName.Magic4);
}
2.定义爆炸的基类BoomBase。在之后的脚本中,只需要继承这个基类,重写函数即可。
对于每一个boom动画,首先得到图片。以及播放的速度speed。
之后,定义函数changeImage(爆炸图片list列表,图片切换时间,技能结束时间)
public abstract class BoomBase : MonoBehaviour {
private Image img;
private float timeFrequency;
private List dataList = new List();
private float frameTime = 0;
private int index;
private float skillEnd;
private float bornTime;
private float speed;
public virtual void Awake()
{
//对于每一个boom动画,首先得到图片
img = this.GetComponent();
speed = 300;
}
public virtual void Start()
{
}
//0,1,2
//changeImage(爆炸图片list列表,图片切换时间,技能结束时间)
public void changeImage(List _data, float _time, float _skillEnd)
{
timeFrequency = _time;
dataList = _data;
this.skillEnd = _skillEnd;
}
public void setImage()
{
if (bornTime > skillEnd)//判断1:bornTime存货死亡的时间线 进度是否结束
{
if (index >= dataList.Count) // 下标大于链表长度,动图资源到头,结束
{
return;
}
frameTime = 0; // frameTime 每进行一帧 0.1 就设置为0,使得每一帧播放一张图片。
img.sprite = this.dataList[index];//得到每一帧的资源
index++;
}
}
public void Update()
{
//bornTime存货死亡的时间线,frameTime是每一帧时间。timeFrequency是图片切换时间
bornTime += Time.deltaTime;
frameTime += Time.deltaTime;
if (frameTime > timeFrequency)//判断1:当前时间大于图片切换时间,开始获取资源
{
setImage();
}
if (bornTime < skillEnd)//判断2:bornTime存货死亡的时间线 是否正在进行
{
this.gameObject.GetComponent().localPosition += new Vector3(1, 0, 0) * Time.deltaTime * speed;
}
if (bornTime > (timeFrequency * dataList.Count + skillEnd))//判断2:技能结束,销毁gameObject
{
Destroy(this.gameObject);
}
}
}
public class ShotScript : BoomBase {
//重载基类的Start()
public override void Start()
{
base.Start();
//需要重写调用基类的函数时,写上 base.Start();
changeImage(LoadRes.getSp(ResName.list),0.1f,1f);
}
}