新手第一次Unity实战总结

这篇博客总结了作者初次使用Unity制作塔防游戏的体验,重点讨论了敌人和防御塔的设计,包括它们的属性和行为机制。尽管游戏尚处于未完成状态,但作者从中学到了很多,并期待未来能创作出更优秀的作品。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本次总结针对我的第一个Unity实战项目(TOWER DEFENSE),在创作过程中的一些分析和感悟以及对部分机制的探讨。

序曲

一个塔防游戏,重要的对象应该是防御塔和敌人,而机制无一例外都是基于消灭敌人防止其进入key point。

敌人

敌人因有的属性如下:
1.属于自己的基础血量,伤害值(不一定),移动速度,特殊能力(不一定)等。
2.一定的行动轨迹。
3.对key point造成影响

防御塔

防御塔有以下属性:
1.建造所需的价格,场地。
2.攻击范围,攻击方式,攻击伤害。
3.特殊能力

经过以上分析,我们便拥有了游戏设计的思路。

创作

场景的构建

1.场地
场地
在平面中以相同size的白方块作为放置防御塔的场地格,棕色连贯道路即为敌人行动轨迹。
2.出生点&key point
红色块为出生点,蓝色块为key point

防御塔素材

借助SIKI学院官方公众号获得了所需要的素材(不叫白嫖),详情可去siki学院官网 获取。

敌人基础属性

1.敌人用不同颜色,体型的小球代表,并创建一个管理机制在这里插入图片描述
在游戏开始自动生成敌人,代码如下

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

public class EnemySpawner : MonoBehaviour
{
    public static int CountEnemyAlive = 0;
    public Wave[] waves;
    public Transform START;
    public float waveRate = 3;

    void Start()
    {
        StartCoroutine(SpawnEnemy());
    }
    
    IEnumerator SpawnEnemy()
    {
        foreach(Wave wave in waves)
        {
            for(int i=0;i<wave.count;i++)
            {
                GameObject.Instantiate(wave.enemyPrefab, START.position, Quaternion.identity);
                if(i!=wave.count-1)
                yield return new WaitForSeconds(wave.rate);
            }
            while (CountEnemyAlive >0)
            {
                yield return 0;
            }
            yield return new WaitForSeconds(waveRate);
        }
    }
}

2.敌人移动通过路径点达成
在这里插入图片描述
在添加脚本控制

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

public class WayPoints : MonoBehaviour
{
    
    public static Transform[] positions;
    void Awake()
    {
        positions = new Transform[transform.childCount];
        for (int i=0;i<positions.Length;i++)
        {
            positions[i] = transform.GetChild(i);
        }
    }
}

以及给敌人命令脚本

 void Move()
    {
        if (index > positions.Length - 1)
        {
            index = 0;
            transform.position = new Vector3(5f, 2f, 5f);
        }
        transform.Translate((positions[index].position - transform.position).normalized * Time.deltaTime * speed);
        if(Vector3.Distance(positions[index].position,transform.position)<0.2f)
        {
            index++;
        }
        if(index>positions.Length-1)
        {
            ReachDestination();
        }
    }

3.血量及被消灭机制
暂未实现
4.对目标点伤害
暂未实现

防御塔属性

1.建造页面UI
在这里插入图片描述
游戏内画面
在这里插入图片描述建造代码如下:

using System.Collections;                                                                                                                                                                                                                                                                                                                                                                                                         
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class BuildManager : MonoBehaviour
{
    public TurretData LaserTurretData;
    public TurretData MissileTurretData; 
    public TurretData StandardTurretData;

    
    private TurretData selectedTurretData;

    public Text moneyText;

    public Animator moneyAnimator;

    public int money = 1000;
    void ChangeMoney(int change=0)
    {
        money += change;   
        moneyText.text = "¥" + money;
     }


   void Update()
    {
        if(selectedTurretData!=null&&Input.GetMouseButtonDown(0))
        {
            if(EventSystem.current.IsPointerOverGameObject()==false)
            {
                
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                bool isCollider = Physics.Raycast(ray,out hit, 1000, LayerMask.GetMask("MapCube"));
                if(isCollider )
                {
                    MapCube  mapCube = hit.collider.GetComponent<MapCube>();
                    if(mapCube.turretGO ==null)
                    {
                        
                        if(money>selectedTurretData.cost)
                        {     
                            ChangeMoney(-selectedTurretData.cost);                    
                            mapCube.BuildTurret(selectedTurretData.turretPrefab);
                            
                        }
                        else
                        {
                            
                            moneyAnimator.SetTrigger("Flicker");
                        }
                    }
                    else
                    {
                        

                    }
                }
                
            }
        }
    }

    public void OnLaserSelected(bool isOn)
    {
        selectedTurretData = LaserTurretData;
    }
    public void OnMissileSelected(bool isOn)
    {
        selectedTurretData = MissileTurretData;
    }
    public void OnstandardSelected(bool isOn)
    {
        selectedTurretData = StandardTurretData; 
    }
}

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

public class MapCube : MonoBehaviour
{
    [HideInInspector ]
    public GameObject turretGO;

    public GameObject buildEffect;

    public void BuildTurret(GameObject turretPrefab)
    {
        turretGO = GameObject.Instantiate(turretPrefab, transform.position, Quaternion.identity);
        GameObject effect = GameObject.Instantiate(buildEffect, transform.position, Quaternion.identity);
        Destroy(effect, 1);
    }
}//与地面做交互

2.防御塔属性

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

[System.Serializable]

public class TurretData 
{
    public GameObject turretPrefab;
    public int cost;
    public GameObject turretUpgradePrefab;
    public int costUpgraded;
    public TurretType type;
}
public enum TurretType
{
    LaserTurret,
    MissileTurret,
    StandardTurret
}

在这里插入图片描述
3.防御塔攻击
通过BoxCollider实现,检测敌人的tag并攻击
在这里插入图片描述
攻击代码

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

public class Bullet : MonoBehaviour
{
    public int damage = 50;

    public float speed = 20;

    public GameObject explosionEffectPrefab;
    private Transform target;
    public void SetTarget(Transform _target)
    {
        this.target = _target;
    }

    void Update()
    {
        transform.LookAt(target.position);
        transform.Translate(Vector3.forward * speed * Time.deltaTime);

        Vector3 dir = target.position - transform.position;
        if(dir.magnitude <1)
        {  
            target .GetComponent<Enemy>().TakeDamage(damage);
            GameObject.Instantiate(explosionEffectPrefab, transform.position, transform.rotation);
            Destroy(this.gameObject);
        }
    }
}

总结

这是个未完成品,但是确实让我理解了很多,我相信以后可以做出更好的作品

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值