需要了解1.四元数相关 2.协程多线程异步加载 3.射线检测与物理检测 4.可以回顾一下向量点乘叉乘内容
以下为需要复习的程序逻辑(开火点的数据刷新)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum E_firePos
{
left,
leftUp,
leftDown,
right,
rightUp,
rightDown,
Top,
Bottom,
}
public class FirePos : MonoBehaviour
{
public Camera playerCamera;
//优先获取玩家对应屏幕的z轴相对位置
public Vector3 firePos;
//散射子弹的方向向量
private Vector3 multiBullets;
//发射位置枚举
public E_firePos fireEnum;
//当前对象的发射器数据对象
public SingleFireData fireData;
//当前对象的子弹数据对象
public SingleBulletData bulletData;
//发射器对象的参数
private float fireCd;//发射子弹cd
private float delay;//子弹打完的冷却时间
private int num;//子弹数量
private int beginIndex;//随机数开头
private int endIndex;//随机数结尾
private float angle;//旋转的角度
private Vector3 frontQ;
void Start()
{
//先将发射器的坐标用屏幕坐标表示 在后面转回世界坐标
firePos.z = 261.84f;
}
//发射位置的分辨率自适应
private void ChangePos(E_firePos a)
{
switch (a)
{
case E_firePos.left:
firePos.x = 0;
firePos.y = Screen.height / 2;
multiBullets = Vector3.right;
break;
case E_firePos.leftUp:
firePos.x = 0;
firePos.y = Screen.height;
multiBullets = Vector3.right;
break;
case E_firePos.leftDown:
firePos.x = 0;
firePos.y = 0;
multiBullets = Vector3.right;
break;
case E_firePos.right:
firePos.x = Screen.width;
firePos.y = Screen.height / 2;
multiBullets = Vector3.left;
break;
case E_firePos.rightUp:
firePos.x = Screen.width;
firePos.y = Screen.height;
multiBullets = Vector3.left;
break;
case E_firePos.rightDown:
firePos.x = Screen.width;
firePos.y = 0;
multiBullets = Vector3.left;
break;
case E_firePos.Top:
firePos.x = Screen.width / 2;
firePos.y = Screen.height;
multiBullets = Vector3.right;
break;
case E_firePos.Bottom:
firePos.x = Screen.width / 2;
firePos.y = 0;
multiBullets = Vector3.right;
break;
}
//将被依附的gameobject位置改为 firePos从屏幕坐标转为世界坐标的值
this.gameObject.transform.position = playerCamera.ScreenToWorldPoint(firePos);
}
//更新数据函数
private void RefreshData()
{
if(fireCd != 0 && num != 0)
{
return;
}
if (fireData != null)
{
delay -= Time.deltaTime;
if (delay > 0)
{
return ;
}
}
List<SingleFireData> fireDataList = DataMgr.Instance.fireData.fireList;
fireData = fireDataList[Random.Range(0, fireDataList.Count)];
fireCd = fireData.fireCd;
delay = fireData.delay;
num = fireData.num;
//拆解字符串
string[] bulletInedx = fireDataList[Random.Range(0, fireDataList.Count)].bullets.Split(",");
beginIndex = int.Parse(bulletInedx[0]);
endIndex = int.Parse(bulletInedx[1]);
//随机子弹数据
int randomBulletIndex = Random.Range(beginIndex, endIndex+1);
bulletData = DataMgr.Instance.bulletData.bulletDataList[randomBulletIndex-1];
//如果是霰弹我们需要为其计算角度的数值
if(bulletData.type == 2)
{
switch (fireEnum)
{
case E_firePos.leftUp:
case E_firePos.leftDown:
case E_firePos.rightUp:
case E_firePos.rightDown:
angle = 90f / (num+1);
break;
case E_firePos.left:
case E_firePos.right:
case E_firePos.Top:
case E_firePos.Bottom:
angle = 180f / (num + 1);
break;
}
}
}
private void Fire()
{
if(num==0 && fireCd == 0)
{
return;
}
//CD更新
fireCd-=Time.deltaTime;
if (fireCd > 0)
{
return ;
}
GameObject bullet;
GameSceneBullet bulletObj;
switch (fireData.type)
{
case 1:
bullet = GameObject.Instantiate(Resources.Load<GameObject>(bulletData.bulletResourceName));
bulletObj = bullet.AddComponent<GameSceneBullet>();
bulletObj.Initial(bulletData);
//设置子弹的位置 和朝向
bullet.gameObject.transform.position = this.transform.position;
//给予旋转角度
bullet.gameObject.transform.rotation = Quaternion.LookRotation(PlayerInfo.Instance.transform.position - bullet.gameObject.transform.position);
//cd重置
--num;
//定个规则 如果num为0了 直接return
fireCd = num == 0 ? 0 : fireCd;
break;
case 2:
//如果配置文件中函数的cd是0的话
if (fireCd == 0)
{
for (int i = 0; i < num; i++)
{
bullet = GameObject.Instantiate(Resources.Load<GameObject>(bulletData.bulletResourceName));
bulletObj = bullet.AddComponent<GameSceneBullet>();
bulletObj.Initial(bulletData);
bullet.gameObject.transform.position = this.transform.position;
//先得到一个向量 再由向量进而得出旋转的角度
//四元数乘以向量将会获得一个新的向量 该向量的旋转角度为四元数所代表的度数
frontQ = Quaternion.AngleAxis(angle * i ,Vector3.up) * firePos;
//有了朝向之后 让子弹面朝向转向该向量即可
bullet.gameObject.transform.rotation = Quaternion.LookRotation(frontQ);
}
fireCd = num = 0;
}
else
{
bullet = GameObject.Instantiate(Resources.Load<GameObject>(bulletData.bulletResourceName));
bulletObj = bullet.AddComponent<GameSceneBullet>();
bulletObj.Initial(bulletData);
bullet.gameObject.transform.position = this.transform.position;
frontQ = Quaternion.AngleAxis(angle * (fireData.num - num), Vector3.up) * firePos;
//有了朝向之后 让子弹面朝向转向该向量即可
bullet.gameObject.transform.rotation = Quaternion.LookRotation(frontQ);
num--;
fireCd = num==0?0:fireData.fireCd;
}
break;
}
}
void Update()
{
ChangePos(fireEnum);
RefreshData();
Fire();
}
}