Unity 塔防笔记

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的消息函数,不要改函数名

OnTriggerEnterGameObject 与另一个 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画布通常要设置成世界空间 

2....太晚了有时间更

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值