2023.12.18
一、地图的创建
用了15*15的Cube做地图,然后删除相应的点形成一条路径。画面缩放和移动: Input.GetAxis("") 是 Unity 引擎中的一个方法,用于获取游戏玩家在键盘或游戏手柄上输入的某个轴(Axis)的值。这里的 "" 是一个字符串参数,表示要获取的轴的名称。
void Update () {
//水平轴 该轴默认是由A、D以及方向键左右箭头来触发!
float h = Input.GetAxis("Horizontal");
//垂直轴 该轴默认是由W、S以及方向键上下箭头来触发!
float v = Input.GetAxis("Vertical");
//鼠标滚轮
float mouse = Input.GetAxis("Mouse ScrollWheel");
//每一帧都在运行 要 * Time.deltaTime 因为这里摄像机翻转了 需要用世界坐标而不是local
transform.Translate(new Vector3(v*speed, mouse*MouseSpeed, h*speed ) * Time.deltaTime ,Space.World);
}
二、敌人的移动
创建了拐角对象 调用Translate方法 单位化让敌人移动
ps:如果要在一个类里面实例化另一个类的多个对象 需要在另一个类上面添加可序列化代码 [System.Serializable]
三、创建敌人孵化器及优化
Instantiate方法
IEnumerator SpawnEnemy()
{
foreach (Wave wave in waveList)
{
for (int i = 0; i < wave.count; i++)
{
GameObject.Instantiate(wave.EnemyPrefab, START.position,Quaternion.identity);
ActiveCount++;
if (i!=wave.count-1)
yield return new WaitForSeconds(wave.rate);
}
while(ActiveCount>0)
{
yield return 0;
}
yield return new WaitForSeconds(WaitGroupTime);
}
}
void ReachEnd()
{
GameObject.Destroy(this.gameObject);
}
//销毁后传递消息给销毁方法 让存活敌人减一
void OnDestroy()
{
EnemySpawn.ActiveCount--;
}
通过监听Destory 传递消息给Destory方法 使敌人数量减一
四、创建数据类
创建数据类(属性类)不需要继承自 MonoBehaviour类,不然Inspector面板上不能显示列表属性
五、创建炮台
这里用到了射线 用摄像机发出的射线到Cube上得到对象。ps:注意添加Mask标记 不然射线不生效
六、金钱不够的闪烁动画
Animation用法 添加关键帧
七、利用粒子特效来实现坦克建造时的特效
effect-Partic System
八、坦克与敌人碰撞检测
1.Collider的消息函数,不要改函数名
OnTriggerEnter | GameObject 与另一个 GameObject 碰撞时,Unity 会调用 OnTriggerEnter。 |
OnTriggerExit | 当 Collider other 已停止接触该触发器时调用 OnTriggerExit。 |
2.性能优化 Edit-Progecting-Physics 设置坦克和敌人的碰撞层 只相互碰撞
九、子弹攻击敌人
public class Bullet : MonoBehaviour {
public float Damage=50;
public float Speed=40;
private Transform target;
public void Move(Transform _target)
{
this.target = _target;
}
void Update()
{
//子弹朝向
transform.LookAt(this.target);
//Translate移动 *时间和速度
transform.Translate(Vector3.forward * Time.deltaTime * Speed);
}
}
void Attack()
{
//得到子弹
GameObject bullet= GameObject.Instantiate(BulletPrefab, BulltPos.position,BulltPos.rotation);
//得到挂在子弹上的Bullet代码组件调用Move方法 指向敌队列的第一个敌人
bullet.GetComponent<Bullet>().Move(Enemy[0].transform);
}
十、敌人队列销毁的更新处理
创建了两个数组,更新时要减去之前更新的元素个数保证按下标删除
//更新Enmey数组
void UpdateEnemy()
{
List<int> EmptyList= new List<int>();
for (int i = 0; i <Enemy.Count; i++)
{
if (Enemy[i]==null)
{
EmptyList.Add(i);
}
}
for (int j = 0; j < EmptyList.Count; j++)
{
//每移动一个元素 队列其他元素往前移 -j才能删除
Enemy.RemoveAt(EmptyList[j]-j);
}
}
十一、实现坦克头朝敌人效果
//让坦克头朝向敌人
if (Enemy.Count > 0 && Enemy[0]!=null)
{
Vector3 targetPosition = Enemy[0].transform.position;
//控制敌人和坦克在垂直方向上一致
targetPosition.y = TurretHead.position.y;
TurretHead.LookAt(targetPosition);
}
这里旋转要注意坦克的头部和坦克本身的中心点是否一致,不一致就导致不能实现预期效果,需要在坦克上建一个空物体 再把坦克头部放到空物体里面(这里还要注意保持这个空物体的Z轴即坦克头部子弹方向和坦克头部一致 先要把空物体的Z轴设置好了再把头部放进去 步骤不能倒置!)保持中心点一致。
十二、鼠标在MapCube上时显示红色
坦克的圆形碰撞器和鼠标有反应导致在一个坦克周围不显示红色,此时需要把Edit-Progecting-Physics里的Queries Hit Triggers取消勾选
//鼠标在MapCube上时显示红色
void OnMouseEnter()
{
if(Turret==null&&EventSystem.current.IsPointerOverGameObject()==false)
{
renderer.material.color = Color.red;
}
}
void OnMouseExit()
{
renderer.material.color = Color.white;
}
十三、升级和拆除UI
创建动画
十四、坦克射线攻击的实现
Line Renderer组件
if(Enemy.Count > 0)
{
lineRenderer.SetPositions(new Vector3[] { BulltPos.transform.position, Enemy[0].transform.position });
}
十五、如何判定成功
IEnumerator SpawnEnemy()
{
foreach (Wave wave in waveList)
{
for (int i = 0; i < wave.count; i++)
{
GameObject.Instantiate(wave.EnemyPrefab, START.position,Quaternion.identity);
ActiveCount++;
if (i!=wave.count-1)
yield return new WaitForSeconds(wave.rate);
}
while(ActiveCount>0)
{
yield return 0;
}
yield return new WaitForSeconds(WaitGroupTime);
}
while(ActiveCount>0)
{
yield return 0;
}
GameManager.instance.Success();
}
在这里while循环AcctiveCount存活敌人数量 yeild return 0 循环返回 最后AcctiveCount等于0即游戏成功
十六、一些方法
1.设计开始结束页面UI时,如果做的3D用到的Canvas画布通常要设置成世界空间
文章来源:https://www.toymoban.com/news/detail-781558.html
2....太晚了有时间更文章来源地址https://www.toymoban.com/news/detail-781558.html
到了这里,关于Unity 塔防笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!