unity制作愤怒的小鸟
文章目录
- 一、 介绍
- SpringJoint2D 、line renderer制作发射绳
- 基类bird脚本的基础功能
- 给bird添加飞行拖尾效果
- pig类
- 游戏胜利的小星星烟花界面
- 摄像机跟随移动
- 游戏失败的界面
- 多种小鸟的制作:黄鸟、绿鸟、黑鸟
- 地图选择
- 关卡选择
- 数据保存
- 制作多个关卡
- 场景异步加载
- 游戏全局管理器
- 源文件下载
一、 介绍
SpringJoint2D
line renderer
动画制作
协程
异步资源加载
resource文件夹存储关卡数据
playerprefs存储关卡信息
trail拖尾效果
SpringJoint2D 、line renderer制作发射绳
基类bird脚本的基础功能
bird脚本是红鸟的专属脚本,yellow鸟、green鸟、black鸟可以在此基础上进行拓展。
以下是函数的简要作用:
OnMouseDown(): 处理鼠标按下事件,设置isClick为true,并禁用刚体组件。
OnMouseUp(): 处理鼠标抬起事件,设置isClick为false,延迟0.1秒后开始飞行,禁用划线组件,设置canMove为false。
Update(): 处理小鸟移动和相机跟随的逻辑,以及炫技操作。
Fly(): 在飞行状态下播放飞行音效,开启拖尾效果,禁用弹簧关节,5秒后自动切换到下一只小鸟。
Line(): 实现划线逻辑。
AudioPlay(): 实现音效播放。
Next(): 切换到下一只小鸟。
Hurt(): 处理小鸟受伤逻辑。
ShowSkill(): 处理小鸟炫技效果。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bird : MonoBehaviour {private bool isClick = false; //是否点击了小鸟public float maxDis = 3; //弹弓的最大拉伸距离[HideInInspector]public SpringJoint2D sp; //SpringJoint2D组件protected Rigidbody2D rg; //Rigidbody2D组件public LineRenderer right; //右边的划线组件public Transform rightPos; //右边的点public LineRenderer left; //左边的划线组件public Transform leftPos; //左边的点public GameObject boom; //小鸟死亡的爆炸效果protected TestMyTrail myTrail; //拖尾效果private bool canMove = true; //是否可以移动public float smooth = 3; //相机跟随的平滑度public AudioClip select; //选择小鸟的音效public AudioClip fly; //小鸟飞行的音效private bool isFly = false; //是否在飞行中public Sprite hurt; //受伤后的图片protected SpriteRenderer render; //SpriteRenderer组件private void Awake(){sp = GetComponent<SpringJoint2D>();rg = GetComponent<Rigidbody2D>();myTrail = GetComponent<TestMyTrail>();render = GetComponent<SpriteRenderer>();}private void OnMouseDown() //鼠标按下{if (canMove){AudioPlay(select); //播放选择小鸟的音效isClick = true; //设置为点击状态rg.isKinematic = true; //关闭物理效果}}private void OnMouseUp() //鼠标抬起{if (canMove){isClick = false; //设置为非点击状态rg.isKinematic = false; //开启物理效果Invoke("Fly", 0.1f); //延迟0.1秒后开始飞行//禁用划线组件right.enabled = false;left.enabled = false;canMove = false; //不可移动}}private void Update(){if (isClick) //鼠标一直按下,进行位置的跟随{transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);//transform.position += new Vector3(0, 0, 10);transform.position += new Vector3(0,0,-Camera.main.transform.position.z);if (Vector3.Distance(transform.position, rightPos.position) > maxDis) //进行位置限定{Vector3 pos = (transform.position - rightPos.position).normalized; //单位化向量pos *= maxDis; //最大长度的向量transform.position = pos + rightPos.position;}Line(); //绘制划线}//相机跟随float posX = transform.position.x;Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position, new Vector3(Mathf.Clamp(posX,0,15),Camera.main.transform.position.y, Camera.main.transform.position.z),smooth*Time.deltaTime);if (isFly){if (Input.GetMouseButtonDown(0)){ShowSkill(); //炫技操作}}}void Fly(){isFly = true; //设置为飞行状态AudioPlay(fly); //播放飞行的音效myTrail.StartTrails(); //开启拖尾效果sp.enabled = false; //禁用弹簧关节Invoke("Next", 5); //飞行5秒后自动切换到下一只小鸟}/// <summary>/// 划线/// </summary>void Line(){right.enabled = true;left.enabled = true;right.SetPosition(0, rightPos.position);right.SetPosition(1, transform.position);left.SetPosition(0, leftPos.position);left.SetPosition(1, transform.position);}/// <summary>/// 下一只小鸟的飞出/// </summary>/// protected virtual void Next(){GameManager._instance.birds.Remove(this); //从GameManager中移除当前小鸟Destroy(gameObject); //销毁当前小鸟Instantiate(boom, transform.position, Quaternion.identity); //生成爆炸效果GameManager._instance.NextBird(); //切换到下一只小鸟}private void OnCollisionEnter2D(Collision2D collision){isFly = false; //设置为非飞行状态myTrail.ClearTrails(); //清除拖尾效果}public void AudioPlay(AudioClip clip){AudioSource.PlayClipAtPoint(clip, transform.position); //在指定位置播放音效}/// <summary>/// 炫技操作/// </summary>public virtual void ShowSkill(){isFly = false; //设置为非飞行状态}public void Hurt(){render.sprite = hurt; //切换为受伤后的图片}
}
给bird添加飞行拖尾效果
给bird添加一个子对象,命名为 Trail,为其添加 WeaponTrail.cs脚本、 Mesh Renderer组件,材质为Pocket RPG Trails提供的材质,设置好如下图所示:
修改 TestMyTrail.cs代码为如下:
using UnityEngine;
using System.Collections;public class TestMyTrail : MonoBehaviour {public WeaponTrail myTrail;private Animator animator;private float t = 0.033f;private float tempT = 0;private float animationIncrement = 0.003f;void Start () {animator = GetComponent<Animator>();}void LateUpdate(){t = Mathf.Clamp(Time.deltaTime, 0, 0.066f);if (t > 0){while (tempT < t){tempT += animationIncrement;if (myTrail.time > 0){myTrail.Itterate(Time.time - t + tempT);}else{myTrail.ClearTrail();}}tempT -= t;if (myTrail.time > 0){myTrail.UpdateTrail(Time.time, t);}}}void OnGUI(){if (GUI.Button( new Rect( 0, 0, 50, 50), "攻击")){animator.SetTrigger( "Attack");}}
}
将 Trail对象赋给 My Trail属性,如下图所示:
修改 TestMyTrail.cs 代码为如下:
void Start () {animator = GetComponent<Animator>();// 默认没有拖尾效果myTrail.SetTime( 0.0f, 0.0f, 1.0f);}public void heroAttack(){//设置拖尾时长myTrail.SetTime( 2.0f, 0.0f, 1.0f);//开始进行拖尾myTrail.StartTrail( 0.5f, 0.4f);}public void heroIdle(){//清除拖尾myTrail.ClearTrail();}
参考链接:https://blog.csdn.net/akof1314/article/details/37603559
资源链接:https://download.csdn.net/download/akof1314/7610241
pig类
这个脚本可以挂载到pig上,也可以挂在砖头上,受伤后速度值过大直接销毁,速度适中展示“损坏”的效果。
//导入命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//定义一个猪的类
public class Pig : MonoBehaviour {//定义最大速度和最小速度public float maxSpeed = 0.01f;public float minSpeed = 0.005f;//定义一个SpriteRendererprivate SpriteRenderer render;//定义一个hurt的Spritepublic Sprite hurt;//定义一个炸弹和得分的游戏对象public GameObject boom;public GameObject score;//定义三种音效public AudioClip hurtClip;public AudioClip dead;public AudioClip birdCollision;//判断是否为猪public bool isPig = false;//定义一个Awake方法,在脚本被启用前执行一次private void Awake(){//获取SpriteRenderer组件render = GetComponent<SpriteRenderer>();}//定义一个OnCollisionEnter2D方法,在碰撞发生时执行private void OnCollisionEnter2D(Collision2D collision){//判断碰撞对象是否为Playerif (collision.gameObject.tag == "Player") {//播放birdCollision音效AudioPlay(birdCollision);//让Bird受伤collision.transform.GetComponent<Bird>().Hurt();}//如果相对速度大于最大速度,直接死亡if (collision.relativeVelocity.magnitude > maxSpeed){Dead();} //如果相对速度在最大速度和最小速度之间,播放hurt音效else if (collision.relativeVelocity.magnitude > minSpeed && collision.relativeVelocity.magnitude < maxSpeed) {render.sprite = hurt;AudioPlay(hurtClip); } }//定义一个Dead方法,处理猪死亡的逻辑public void Dead() {//如果是猪,从GameManager中移除猪if (isPig){GameManager._instance.pig.Remove(this);}//销毁猪的游戏对象Destroy(gameObject);//在猪的位置生成一个炸弹Instantiate(boom, transform.position, Quaternion.identity);//在猪的位置生成得分的游戏对象,并延迟1.5秒后销毁GameObject go = Instantiate(score, transform.position + new Vector3(0,0.5f,0), Quaternion.identity);Destroy(go, 1.5f);//播放死亡音效AudioPlay(dead);}//定义一个AudioPlay方法,用于播放音效public void AudioPlay(AudioClip clip){//在猪的位置播放指定的音效AudioSource.PlayClipAtPoint(clip, transform.position);}
}
游戏胜利的小星星烟花界面
一颗一颗显示星星:
public void ShowStars() {StartCoroutine("show");}IEnumerator show() {for (; starsNum < birds.Count + 1; starsNum++){if (starsNum >= stars.Length) {break;}yield return new WaitForSeconds(0.2f);stars[starsNum].SetActive(true);}print(starsNum);}
摄像机跟随移动
//相机跟随float posX = transform.position.x;Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position,new Vector3(Mathf.Clamp(posX,0,15),Camera.main.transform.position.y, Camera.main.transform.position.z),smooth*Time.deltaTime);
游戏失败的界面
图片嵌套,设置动画,透明度渐变。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PausePanel : MonoBehaviour
{private Animator anim;public GameObject button;private void Awake(){anim = GetComponent<Animator>();}public void Retry() {Time.timeScale = 1;UnityEngine.SceneManagement.SceneManager.LoadScene(2);}/// <summary>/// 点击了pause按钮/// </summary>public void Pause(){//1、播放pause动画 anim.SetBool("isPause", true);button.SetActive(false);}/// <summary>/// 点击了继续按钮/// </summary>public void Resume() {//1、播放resume动画Time.timeScale = 1;anim.SetBool("isPause", false);}public void Home(){Time.timeScale = 1;UnityEngine.SceneManagement.SceneManager.LoadScene(1);}/// <summary>/// pause动画播放完调用/// </summary>public void PauseAnimEnd() {Time.timeScale = 0;}/// <summary>/// resume动画播放完调用/// </summary>public void ResumeAnimEnd() {button.SetActive(true);}}
多种小鸟的制作:黄鸟、绿鸟、黑鸟
各种鸟,都继承红鸟bird的基础功能,进而拓展自己的功能。
黄鸟点击屏幕可以加速:
public class YellowBird : Bird {/// <summary>/// 重写方法/// </summary>public override void ShowSkill(){base.ShowSkill();rg.velocity *= 2;}}
绿鸟点击屏幕可以回旋:
public class GreenBird : Bird {public override void ShowSkill(){base.ShowSkill();Vector3 speed = rg.velocity;speed.x *= -1;rg.velocity = speed;}}
黑鸟点击屏幕发生爆炸,把一定范围的pig通过处罚监测存到list中,全部销毁
using System.Collections; //导入命名空间System.Collections
using System.Collections.Generic; //导入命名空间System.Collections.Generic
using UnityEngine; //导入命名空间UnityEnginepublic class BlackBird : Bird { //定义名为BlackBird的类,继承自Bird类public List<Pig> blocks = new List<Pig>(); //定义名为blocks的Pig类型的列表/// <summary>/// 进入触发区域/// </summary>/// <param name="collision"></param>private void OnTriggerEnter2D(Collider2D collision) //当进入触发区域时{if (collision.gameObject.tag == "Enemy") { //如果触碰到的物体标签为“Enemy”blocks.Add(collision.gameObject.GetComponent<Pig>()); //将触碰到的物体的Pig组件添加到blocks列表中}}/// <summary>/// 离开触发区域/// </summary>/// <param name="collision"></param>private void OnTriggerExit2D(Collider2D collision) //当离开触发区域时{if (collision.gameObject.tag == "Enemy") //如果触碰到的物体标签为“Enemy”{blocks.Remove(collision.gameObject.GetComponent<Pig>()); //将触碰到的物体的Pig组件从blocks列表中移除}}public override void ShowSkill() //重写父类的ShowSkill方法{base.ShowSkill(); //调用父类的ShowSkill方法if (blocks.Count > 0 && blocks != null) { //如果blocks列表中有元素for (int i = 0; i < blocks.Count; i++) { //循环遍历blocks列表中的元素blocks[i].Dead(); //调用Pig类的Dead方法}}OnClear(); //调用自定义的OnClear方法}void OnClear() { //自定义名为OnClear的方法rg.velocity = Vector3.zero; //将刚体的速度设置为零向量Instantiate(boom,transform.position,Quaternion.identity); //在对象的位置生成一个boom预制体render.enabled = false; //关闭SpriteRenderer组件GetComponent<CircleCollider2D>().enabled = false; //关闭CircleCollider2D组件myTrail.ClearTrails(); //调用自定义的ClearTrails方法清空拖尾效果}protected override void Next() //重写父类的Next方法{GameManager._instance.birds.Remove(this); //将当前对象从GameManager类的birds列表中移除Destroy(gameObject); //销毁对象GameManager._instance.NextBird(); //调用GameManager类的NextBird方法}
}
地图选择
关卡选择
数据保存
public void SaveData() {if (starsNum > PlayerPrefs.GetInt(PlayerPrefs.GetString("nowLevel"))){PlayerPrefs.SetInt(PlayerPrefs.GetString("nowLevel"), starsNum);}//存储所有的星星个数int sum = 0; for (int i = 1; i <= totalNum; i++) {sum += PlayerPrefs.GetInt("level" + i.ToString());}PlayerPrefs.SetInt("totalNum",sum);//print(PlayerPrefs.GetInt("totalNum"));}
PlayerPrefs类:用于存储游戏数据,包括玩家的设置和游戏状态。
GetInt()方法:从PlayerPrefs中获取一个整数值。
GetString()方法:从PlayerPrefs中获取一个字符串值。
SetInt()方法:将一个整数值存储到PlayerPrefs中。
制作多个关卡
新建文件夹RESOURCE,自己制作不同的关卡,用于方便后续加载
场景异步加载
设置分辨率,加载到选择地图界面。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class LoadLevelAsync : MonoBehaviour {// Use this for initializationvoid Start() {Screen.SetResolution(960,600,false);Invoke("Load",2);}void Load() {SceneManager.LoadSceneAsync(1);}}
游戏全局管理器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class GameManager : MonoBehaviour {public List<Bird> birds; // 小鸟列表public List<Pig> pig; // 猪列表public static GameManager _instance; // 游戏管理器实例private Vector3 originPos; //初始化的位置public GameObject win; // 胜利界面public GameObject lose; // 失败界面public GameObject[] stars; // 星星private int starsNum = 0; // 星星数量private int totalNum = 9; // 总星星数量private void Awake(){_instance = this;if(birds.Count > 0) {originPos = birds[0].transform.position;}}private void Start(){Initialized();}/// <summary>/// 初始化小鸟/// </summary>private void Initialized(){for(int i = 0; i < birds.Count; i++){if (i == 0) //第一只小鸟{birds[i].transform.position = originPos;birds[i].enabled = true;birds[i].sp.enabled = true;}else{birds[i].enabled = false;birds[i].sp.enabled = false;}}}/// <summary>/// 判定游戏逻辑/// </summary>public void NextBird(){if(pig.Count > 0){if(birds.Count > 0){//下一只飞吧Initialized();}else{//输了lose.SetActive(true);}}else{//赢了win.SetActive(true);}}public void ShowStars() {StartCoroutine("show");}IEnumerator show() {for (; starsNum < birds.Count + 1; starsNum++){if (starsNum >= stars.Length) {break;}yield return new WaitForSeconds(0.2f);stars[starsNum].SetActive(true);}print(starsNum);}public void Replay() {SaveData();SceneManager.LoadScene(2);}public void Home() {SaveData();SceneManager.LoadScene(1);}public void SaveData() {if (starsNum > PlayerPrefs.GetInt(PlayerPrefs.GetString("nowLevel"))){PlayerPrefs.SetInt(PlayerPrefs.GetString("nowLevel"), starsNum);}//存储所有的星星个数int sum = 0; for (int i = 1; i <= totalNum; i++) {sum += PlayerPrefs.GetInt("level" + i.ToString());}PlayerPrefs.SetInt("totalNum",sum);//print(PlayerPrefs.GetInt("totalNum"));}
}
维护小鸟列表(birds)和猪列表(pig)。
实现了单例模式,通过静态变量 _instance 获取 GameManager 的实例。
存储初始位置(originPos)。
引用胜利界面(win)和失败界面(lose)的游戏对象。
存储星星的数组(stars)。
跟踪星星数量(starsNum)和总星星数量(totalNum)。
在 Awake 方法中设置 GameManager 的实例和初始位置。
在 Start 方法中调用 Initialized 方法进行初始化。
Initialized 方法用于初始化小鸟列表中的小鸟,将第一只小鸟设置在初始位置,其他小鸟禁用。
NextBird 方法根据游戏逻辑判断游戏输赢,并在相应情况下显示胜利或失败界面。
ShowStars 方法使用协程逐个显示星星。
Show 方法用于协程,控制星星的显示过程。
Replay 方法用于重新加载场景。
Home 方法用于返回主菜单。
SaveData 方法用于保存游戏数据,包括更新关卡的星星数量和总星星数量。
源文件下载
https://wwez.lanzoul.com/iBdeT0whs3gh
unity制作愤怒的小鸟相关推荐
- Unity 制作愤怒的小鸟
Unity 制作愤怒的小鸟 一.项目准备 二.切片 三.实现小鸟的拖拽与飞出 1. 添加并设置Spring Joint 2D 2. 实现小鸟跟随鼠标移动 3. 限定小鸟最大拖拽距离 4. 实现小鸟飞出 ...
- unity制作愤怒的小鸟笔记
1.穿透效果 层级(小鸟和弹弓都属于BirdHood层) 前弹弓属于BirdHood层的第3层 后弹弓属于BirdHood层的第1层 小鸟属于BirdHood层的第2层 层级关系小鸟可以在实现穿透效果 ...
- Unity制作2D动作平台游戏视频教程
Metroidvania工具包:打造统一的2D行动平台 流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确 ...
- Unity制作游戏中的场景
Unity制作游戏中的场景 1.2.3 场景 在Unity中,场景(Scene)就是游戏开发者制作游戏时,所使用的游戏场景.它是一个三维空间,对应的三维坐标轴分别是X轴.Y轴和Z轴本文选自Unity ...
- arkit unity_凯蒂猫! 如何使用ARKit和Unity制作增强现实应用程序。
arkit unity by Francesco Pallotta 由Francesco Pallotta 凯蒂猫! 如何使用ARKit和Unity制作增强现实应用程序. (Hello, Kitty! ...
- unity 制作书本 翻页效果
unity 制作书籍翻页效果 unity C# 翻书效果 2D 真实翻页 不使用插件 自制 实现思路: 将书本分为两边,一边一个翻页实现: 下图为书本的右面,以OA为分界线,△OAB是下一面的如上图的 ...
- Unity 制作简单的任务动画
Unity 制作简单的任务动画 1.添加人物模型到unity 我使用的是unity store中的免费模型: https://assetstore.unity.com/packages/3d/char ...
- Unity 制作萌系live2d桌宠:屏幕自适应+交互
目录 准备工作 使用unity显示live2d人物 全屏+背景透明+点击穿透+置顶 屏幕自适应 交互 本文在之前的博客如何使用unity制作萌萌的live2d桌宠的基础上对项目继续改进,解决了屏幕自适 ...
- Unity制作格斗游戏核心思路总结
http://anchorart9.com/2016/05/22/unity%E5%88%B6%E4%BD%9C%E6%A0%BC%E6%96%97%E6%B8%B8%E6%88%8F%E6%A0%B ...
最新文章
- HD 1525 Euclid's Game
- Hi3516A开发--/etc/passwd
- 云顶之弈机器人法爆_云顶之弈:六法机器人强势来袭,输出爆炸,网友:吃鸡必备...
- ConvLab介绍及使用
- 还在看那些老掉牙的性能优化文章么?这些最新性能指标了解下
- 自动化测试辅助工具——FirePath
- 健身管理系统一站式智能化健身管理体验
- 手机如何无线投屏到电视/电脑
- 拷贝相关器 matlab,基于MELP的水下实时语音通信机的研究与实现
- LeetCode 简单算法题
- 前端局部刷新的几种方式
- 【kafka】二、kafka安装
- 在Windows 下的 Qt 应用程序获得 Administrator 权限
- Android Banner
- 关闭 Hadoop 集群
- 欧氏空间位姿与变换矩阵的转换
- C++语言单链表实现荷兰旗问题
- Linux chromium弹出your preferences can not be read
- 九段刀客:express连接MySQL并实现增、删、改、查
- 7.4 初等矩阵和可逆性
热门文章
- 毕业设计-基于微信小程序的订水系统
- java-net-php-python-ssm购房贷款交易平台计算机毕业设计程序
- 梯度下降求解一元二次函数
- Android 测试知识点总结
- 李阳疯狂英语900句
- creator 构建ios 项目 接入 google admob 横幅广告
- minGW 2022/7/27 安装教程 简单可用
- WARN - Got result of null when trying to get Boolean.
- O-flocking: 一种自动生成的群体自组织区域移动模型
- 计算机一级百度英语,这款翻译机火到了中非合作论坛上 百度大脑让它更“聪明”...