Unity百游修炼(19)——粒子系统之魔法battle(详细全流程)

一.前言

        在 Unity 游戏开发的世界里,构建丰富且交互性强的游戏玩法是吸引玩家的关键。本次项目旨在打造一个充满奇幻色彩的场景,玩家通过点击操作发射魔法球攻击随机生成的敌人。这一过程涉及资源整合、脚本编程以及碰撞检测等多个重要环节,对于理解和掌握 Unity 开发技术具有重要意义。通过详细的步骤解析,无论是新手开发者还是有一定经验的创作者,都能从中获取宝贵的实践经验,提升游戏开发技能。


二.最终效果

        玩家置身于导入的 POLYDesert 场景中,控制名为 Player 的角色。当玩家点击鼠标,角色会向点击位置发射魔法球,左键和右键分别对应不同的魔法球,增加操作的多样性。发射出的魔法球

unity6.6


三.素材

 场景资源:POLYDesert | 3D 风景 | Unity Asset Store

        从 Unity Asset Store 获取的 “POLYDesert | 3D 风景” 资源,为游戏构建了一个逼真且富有特色的沙漠场景,为游戏世界奠定了基础。其包含丰富的地形、建筑和自然元素,能够极大地提升游戏的视觉吸引力。


特效资源:Cartoon FX Remaster Free | VFX 粒子 | Unity Asset Store

        “Cartoon FX Remaster Free | VFX 粒子” 资源提供了炫酷的粒子特效,如用于魔法球的火焰特效,使游戏中的技能表现更加生动和华丽,增强了游戏的视觉冲击力。


人物资源:Easy Primitive People | 3D 角色 | Unity Asset Store

         “Easy Primitive People | 3D 角色” 资源中的角色模型被用于游戏中的玩家角色和敌人角色,简单而独特的风格与整体游戏风格相契合,为游戏增添了趣味性。


四.实现路径

1.下载资源并导入场景和角色

        从 Unity Asset Store 下载所需资源包后,在 Unity 项目中通过特定的导入流程,将场景资源和角色资源整合到项目中,为后续的开发工作搭建基础环境。

2.在场景中点击,角色向单击位置发射出一个魔法球,同时鼠标左键和右键分别用于控制两种不同的魔法球

        通过编写脚本,利用射线检测获取鼠标点击位置,当玩家点击鼠标时,角色根据点击位置调整朝向并发射魔法球,同时区分鼠标左键和右键发射不同类型的魔法球。

3.让火焰朝前方移动,接触敌人时产生爆炸效果

        为火焰预制体添加物理组件和脚本,使其能够向前移动,并通过碰撞检测,当火焰与敌人碰撞时,触发爆炸特效并销毁火焰和敌人。

4.在场景中随机生成敌人

        创建一个空物体作为敌人生成点,编写脚本实现以该点为中心,在设定的随机范围内定期生成敌人,增加游戏的挑战性和趣味性。

5.敌人受到魔法攻击,完成销毁

        为敌人预制体添加脚本和碰撞检测,当敌人与魔法球碰撞时,执行销毁操作,实现游戏的战斗逻辑。


五.详细操作步骤

1.导入场景资源,进入资源DesertScence中,如下图:

        下载 “POLYDesert” 资源包后,在 Unity 项目中,通过菜单栏的 “Assets” -> “Import Package” -> “Custom Package” 选择下载的资源包进行导入。导入完成后,进入资源文件夹中的 “DesertScence”,该场景包含了各种地形、建筑等元素,可直接拖入到游戏场景中,构建游戏的基础环境。

 2.  拖入场景角色,命名为Player

        从 “Easy Primitive People” 资源中找到合适的角色模型,将其拖入到游戏场景中,并命名为 “Player”。选中 “Player” 物体,在 Inspector 面板中可对其位置、旋转和缩放等参数进行调整,使其位于场景中的合适位置,并且大小比例协调。同时,可根据游戏需求对角色模型的材质、颜色等外观属性进行进一步定制。

 

3.创建一个脚本PlayerControl,并挂载到Player物体上

        在 Project 面板中右键点击,选择 “Create” -> “C# Script”,命名为 “PlayerControl”。双击打开脚本。

代码如下:

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

public class PlayerControl : MonoBehaviour
{
    public GameObject FirePre1;
    public GameObject FirePre2;
    private float fire1CD = 0.4f;
    private float fire2CD = 1f;

    private float time;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        time += Time.deltaTime;
        Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if(Physics.Raycast(ray, out hit))
        {
            transform.LookAt(new Vector3(hit.point.x, transform.position.y, hit.point.z));
            if(Input.GetMouseButtonDown(0))
            {
                Fire(FirePre1, fire1CD);
            }
            else if(Input.GetMouseButtonDown(1))
            {
                Fire(FirePre2, fire2CD);
            }
        }
    }


    void Fire(GameObject firePre,float fireCD)
    {
        if(time>fireCD)
        {
            time = 0;
            Instantiate(firePre,transform.position,transform.rotation);
        }
    }
}

        在脚本中,FirePre1和FirePre2分别代表两种不同的魔法球预制体,fire1CD和fire2CD表示两种魔法球的冷却时间。在Update函数中,通过射线检测获取鼠标点击位置,若检测到点击,根据点击的鼠标按键调用Fire函数发射相应的魔法球。注意,在使用前需在 Inspector 面板中为FirePre1和FirePre2赋值对应的魔法球预制体。

4.选中火焰预制体CFX3 FIRE Shield和CFX4 Fire,添加Sphere collider组件,rigidbody组件,取消 use gravity ,勾选 “是触发器”

        选中火焰预制体 “CFX3 FIRE Shield” 和 “CFX4 Fire”,在 Inspector 面板中点击 “Add Component”,分别添加 “Sphere collider” 组件和 “Rigidbody” 组件。对于 “Rigidbody” 组件,取消 “use gravity” 勾选,因为我们不希望火焰受重力影响下落,同时勾选 “Is Trigger”,使其作为触发器使用。调整 “Sphere collider” 的半径等参数,使其范围与火焰特效的实际范围相匹配,确保碰撞检测的准确性。

 

5.为火焰预制体创建一个脚本FireControl,并且挂载到两个火焰预制体身上

        在 Project 面板中创建一个新的 C# 脚本,命名为 “FireControl”,并挂载到两个火焰预制体上。

代码如下:

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

public class FireControl : MonoBehaviour
{
    public GameObject Explosionpre;
    private float speed = 10f;
    // Start is called before the first frame update
    void Start()
    {
        Destroy(gameObject,5f);
        GetComponent<Rigidbody>().velocity = transform.forward*speed;

    }

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

    private void OnTriggerEnter(Collider other)
    {
        if(other.tag=="Enemy")
        {
            Instantiate(Explosionpre,transform.position, Quaternion.identity);
            Destroy(gameObject);
        }
    }
}

         在Start函数中,设置火焰在 5 秒后自动销毁,同时通过Rigidbody组件使其以设定的速度向前移动。在OnTriggerEnter函数中,当火焰与带有 “Enemy” 标签的物体碰撞时,会在碰撞位置实例化爆炸预制体 “Explosionpre”,并销毁火焰自身。同样,在使用前需在 Inspector 面板中为 “Explosionpre” 赋值对应的爆炸预制体。  

6.创建一个空物体,命名为EnemyPoint。同时创建一个脚本EnemyPointControl,并把脚本挂载到物体上,最后把EnemyPoint做成预制体

        在 Hierarchy 面板中右键点击,选择 “Create Empty”,创建一个空物体,命名为 “EnemyPoint”。在 Project 面板中创建一个新的 C# 脚本,命名为 “EnemyPointControl”

EnemyPoint代码如下:

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

public class EnemyPoint : MonoBehaviour
{
    public GameObject EnemyPre;
    private float timer;
    private float CD;
    // 定义随机生成范围的半径
    public float spawnRadius = 5f;

    // Start is called before the first frame update
    void Start()
    {
        CD = Random.Range(1, 3);
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;
        if (timer > CD)
        {
            // 生成随机位置
            Vector3 randomOffset = Random.insideUnitCircle * spawnRadius;
            Vector3 spawnPosition = new Vector3(transform.position.x + randomOffset.x, 1, transform.position.z + randomOffset.y);

            Transform enemy = Instantiate(EnemyPre, spawnPosition, Quaternion.identity).transform;
            enemy.SetParent(transform);

            enemy.LookAt(new Vector3(Camera.main.transform.position.x, enemy.transform.position.y, Camera.main.transform.position.z));
            CD = Random.Range(1, 3);
            timer = 0;
        }
    }
}

        以 “EnemyPoint” 为中心,在随机半径范围内定期生成敌人的功能。在Start函数中,初始化敌人生成的冷却时间 “CD”。在Update函数中,当计时器 “timer” 超过 “CD” 时,计算一个随机位置并实例化敌人预制体 “EnemyPre”,同时让敌人看向摄像机位置,然后重新设置冷却时间和计时器。完成脚本编写后,将其挂载到 “EnemyPoint” 物体上,并在 Inspector 面板中为 “EnemyPre” 赋值对应的敌人预制体。最后,将 “EnemyPoint” 物体制作成预制体,方便在场景中多次使用或进行进一步的设置。

7.创建一个脚本EnemyControl,将其添加到Robber预制体上,并为预制体设置一个标签Enemy,最后再添加一个Capsule Collider组件

        在 Project 面板中创建一个新的 C# 脚本,命名为 “EnemyControl”,并添加到 “Robber” 预制体上。

EnemyControl代码如下:

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

public class EnemyControl : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);
    }
}

        当敌人与其他碰撞体发生碰撞(这里主要是与魔法球碰撞)时,OnTriggerEnter函数被触发,执行销毁敌人自身的操作。为了确保碰撞检测的准确性,需要为 “Robber” 预制体添加 “Capsule Collider” 组件,并设置合适的参数,同时为其设置一个标签 “Enemy”,以便在其他脚本中进行识别和交互。


六.结语

        在实际开发中,开发者可以根据项目需求进一步优化和扩展这些功能,如增加更多类型的魔法球、敌人的 AI 行为、更丰富的特效等。希望本文能为你的 Unity 游戏开发之旅提供有益的参考,帮助你创造出更加精彩的游戏作品。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值