自学游戏笔记——第一款游戏02

一:敌人移动路线

用的是AI导航,将道路设为静态,烘焙导航路线。

脚本思路:获取目的地gameObject,设置导航目的Destination为目标地址。

二: 敌人生成

单独写一个脚本wave存放生成敌人生成的相关参数,如波数,生成什么样的敌人,生成速率。

脚本敌人生成器spawnedEnemy思路:用协程IEnumerator控制敌人间隔在Star出现。全局参数 waveRate控制延迟时间。

wave脚本不继承behavior,方便在生成器脚本用数组public wave[]。

注意事项:

wave设置序列化:system.Serializable,否则在unity无法看到public的参数。这样就可以在unity直接挂参数prefab,rate,count等参数。

设置敌人生存数,每生成一个++。

敌人消失条件:到达目的地进行销毁,被炮塔击毁(尚未实现)。

到达目的地条件判断:因为y轴的存在,不能单纯的直接equal两个位置。所以要单独判断x和z的位置关系。

注意事项:烘焙时选择的代理模型半径最好是整数!因为地图设置的路线都是整数坐标,如果代理半径有0.5等,会出现敌人的x或z坐标出现0.5等浮点数,导致判断失败。

三:炮塔生成及炮塔ui

可以从商店找到想要的炮塔素材,我是用了三种炮塔,每种炮塔有两种形态。分别为炮塔的常态和升级态生成预制体以备后用。

创建数据类TurretDate保存炮塔相关数据如:要生成的炮塔类型预制体,炮塔花费以及升级后的炮塔花费。其中用enum枚举保存炮塔的三种类型。

TurretManege监听炮塔行为,当前完成度:

1.监听到玩家选择的是哪一种炮塔,通过toggle的值改变获得点击目标。

2.监听玩家的鼠标选择的是地图上的哪一块。首先要判断地图是否和UI重合了:可以使用Even System中的current下的IsPointerOverGameObject方法(如果是做手机端游戏的话要传递参数,详见API)。将地图单独设置一个图层,这样用射线检测只要和单一图层做碰撞,获得碰撞变量hit。然后对是否碰撞做判断,如果有碰撞到就可以用hit中的Collider.GameObject获得碰撞目标。至此监听碰撞cube完成。注意:如果出现ray射线报错空指针的话首先检查一下camera的tag是否设置为main camera

3.获得碰撞地图块对象后,要判断其上是否已经建立了炮塔,可以写单独脚本MapCube单独完成部分功能:如建塔;  继续在TurretManage判断是否有建立炮塔。无:执行键塔操作,金额做对应减少(金钱更新操作可以单独用一个方法实现)同时更新UI金钱的显示,方法是获得UI Money的引用,直接用Text=“¥”+money,要注意的是:新版unity的文本是TextMeshPro,所以在定义和使用的时候要引用TextMeshProUGUI命名空间

ui:用toggle来设计ui,toggleGroup组件实现单一选择,添加text作为花费金额,额外text做为当前拥有金额。

在ui设计界面,记住按alt可以同时设置锚点,这样可以保证图像随屏幕缩放但是相对位置不变。我是选择居右。CheckMark的源图像是用于选中某炮台时,出现背景变暗功能。

 

 

 

 

c#源码:

enemy

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Enemy : MonoBehaviour
{
    private NavMeshAgent agent;
    public Transform end;
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {

        enemyMove();
    }
    void enemyMove()
    {
        agent.SetDestination(end.localPosition);
        if (transform.localPosition.x == end.localPosition.x && transform.localPosition.z == end.localPosition.z)
        {
            reachDestination();
        }
    }
    private void reachDestination()
    {
        Destroy(this.gameObject);
    }
    private void OnDestroy()
    {
        SpawnedEnemy.enemyCount--;
    }

}

SpawnedEnemy:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnedEnemy : MonoBehaviour
{
    public static int enemyCount;
    public Wave[] waves;
    public Transform star;
    //波次间隔时间
    public float waveRate=3;
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(spawnedEnemy());
    }
    IEnumerator spawnedEnemy()
    {
        foreach(Wave wave in waves)
        {
            for (int i = 0; i < wave.count; i++)
            {
                Instantiate(wave.prefab, star.localPosition, Quaternion.identity);
                enemyCount++;
                if (i<wave.count)
                {
                    yield return new WaitForSeconds(wave.rate);
                }
                
            }
            while (enemyCount > 0)
                {
                    yield return 0;
                }
            yield return new WaitForSeconds(waveRate);
        }
    }
}

Wave:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Wave
{
    public GameObject prefab;
    public int count;
    public float rate;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值