一.前言
在 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 游戏开发之旅提供有益的参考,帮助你创造出更加精彩的游戏作品。