Unity经典游戏教程之:雪人兄弟

版权声明:

  • 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客"(微信号:unitymaker)
  • 您可以自由转载,但必须加入完整的版权声明!

雪人兄弟游戏开发过程:

场景搭建

1.将Map地图拖入场景,

9Fqek4.png

2.创建一个ground空对象给这个对象添加一些Collider 2D 组件,把这些Collide2D覆盖到地图可以行走的地方,创建以个wall空对象给这个对象添加两个Collider 2D组件,把这两个 Collide2D 覆盖到地图的两侧。

9FOKL6.jpg

创建主角

1.创建hero对象给其一张主角的图片精灵,给hero对象添加Rigidbody2D和Collider 2D组件使其可以进行物理运动和碰撞行为;

9FO2yq.png

2. 创建动画控制器,编辑一些主角行为的的动画,再用动画控制器进行控制;

9FXxuq.jpg

3. 添加HeroMove脚本,通过编辑代码使主角可以移动和跳跃;

//Update时通过射线检测判断是否可以跳跃:RaycastHit2D hit = Physics2D.Linecast(this.transform.position, t.position, 1 << LayerMask.NameToLayer("ground"));//Debug.DrawLine(this.transform.position, t.position);// t.position//print((bool)hit);if (Input.GetButtonDown("Jump") && hit){jump = true;}···
//FixedUpdatebool speed = false; //触发动画的布尔变量float h = Input.GetAxis("Horizontal");if (h != 0){speed = true;}Vector2 force = new Vector2(h * moveForce, 0);//限制移动速度if (Mathf.Abs(rb.velocity.x) < maxSpeed){GetComponent<Animator>().SetBool("Speed", speed);rb.AddForce(force);}if (Mathf.Abs(rb.velocity.x) >= maxSpeed){rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxSpeed, rb.velocity.y);}//动画方向转变if (h < 0){var s = this.transform.localScale;s.x = Mathf.Abs(-s.x);this.transform.localScale = s;}else if (h > 0){var s = this.transform.localScale;s.x = -Mathf.Abs(-s.x);this.transform.localScale = s;}//跳跃if (jump){GetComponent<Animator>().SetTrigger("jump");rb.AddForce(Vector2.up * jumpForce);jump = false;}

4.让主角可以发射子弹:

1. 制作子弹预制体 ,

9Fb0wF.png

2.给hero添加一个子节点Gun作为生成子弹的点,并添加脚本控制子弹的发射和行为。

void Update () {if (Input.GetButtonDown("Fire1")){this.transform.parent.gameObject.GetComponent<Animator>().SetTrigger("Shoot");var rocket = Instantiate(rocketPrefab);rocket.transform.position = this.transform.position;if (this.transform.parent.localScale.x > 0){rocket.transform.rotation = Quaternion.Euler(0, 0, 0);rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0);}else{rocket.transform.rotation = Quaternion.Euler(0, 0, 180);rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(-speed, 0);}}}

创建敌人:

1.创建一个monsters空对象为了确定敌人生成的位置:

2. 创建monster对象给其一张敌人的图片精灵,给monster对象添加Rigidbody2D和Collider2D组件使其可以进行物理运动和碰撞行为,并把它做成预制体。

9FjLdK.png

3. 添加Monster脚本,通过编辑代码使敌人可以移动和跳跃;

public class Monster : MonoBehaviour
{// public float speed = 3; private float MonsterMoveForce = 0.8f;  //速度//private float MonsterMaxSpeed = 0.5f;     //限制速度public float monsterJumpForce = 600f; //= 2.8f;private bool monsterJump = false;private Transform topCheck;private Transform frontCheck;private Transform downCheck;int h;private int hp = 1;public GameObject snowball;public void Start(){topCheck = transform.Find("topCheck");frontCheck = transform.Find("frontCheck");downCheck = transform.Find("DownCheck");}public void Update(){if (hp <= 0){Vector2 s = this.transform.position;hp = 0;Destroy(this.gameObject);GameObject g = Instantiate(snowball);g.transform.position = s;return;}}public void FixedUpdate(){// 跳跃           RaycastHit2D hit1 = Physics2D.Linecast(topCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));RaycastHit2D hit2 = Physics2D.Linecast(downCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));RaycastHit2D hit = Physics2D.Linecast(frontCheck.position, this.transform.position);h = Random.Range(0, 100);Rigidbody2D rb = this.transform.gameObject.GetComponent<Rigidbody2D>();Debug.DrawLine(this.transform.position, topCheck.position);Debug.DrawLine(this.transform.position, downCheck.position);Debug.DrawLine(this.transform.position, frontCheck.position);if (hit && hit.transform.gameObject.tag == "wall" || hit.transform.gameObject.tag == "destroyer"){Vector3 s = this.transform.localScale;//s.x = -s.x;this.transform.localScale = s;}else if (hit2 && hit && hit.transform.gameObject.tag == "ground"){monsterJump = true;}else{    //随机方向         if (h == 2){Vector3 s = this.transform.localScale;s.x = -s.x;this.transform.localScale = s;}}//移动     Vector2 x = new Vector2(-this.transform.localScale.x * MonsterMoveForce, rb.velocity.y);rb.velocity = x;this.gameObject.GetComponent<Animator>().SetTrigger("move");//跳跃if (hit1 && hit2 && h == 3){monsterJump = true;}if (monsterJump){rb.AddForce(Vector2.up * monsterJumpForce);monsterJump = false;}}public void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "ground"){this.gameObject.GetComponent<Animator>().SetTrigger("ground");}if (collision.gameObject.tag == "bullet"){hp--;}}public void OnCollisionExit2D(Collision2D collision){if (collision.gameObject.tag == "ground"){this.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 0);this.gameObject.GetComponent<Animator>().SetTrigger("groundl");}}}

创建雪球:

1. 创建snowball对象给其一张默认的图片精灵,给snowball对象添加Rigidbody2D和lColider2D组件使其可以进行物理运动和碰撞行,并把它做成预制体。

9kZKde.png
9kZmqO.png
9kZuZD.png

2.给snowball对象添加脚本通过编辑代码,添加状态机使雪球状态可以切换。

public class Snowball : MonoBehaviour
{StateMachine<Snowball> stateMachine = new StateMachine<Snowball>();public Sprite snowball1;public Sprite snowball2;public Sprite snowball3;public GameObject monster;public Transform frontCheck;public GameObject[] props;public GameObject balldestory;// Use this for initialization//雪球状态public class SnowballStateB : State<Snowball>{public float explodeTime = 0;public bool gun = false;public float gunForce = 3f;float dir;public override void Enter(Snowball e){e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball1; //获的图片e.gameObject.GetComponent<Animator>().SetTrigger("snowball1");e.frontCheck = e.transform.Find("frontCheck");e.gameObject.layer = LayerMask.NameToLayer("snowball");}public override void Update(Snowball e){//雪球没滚时隔 6 个时间点恢复成版雪球if (gun == false){explodeTime += Time.deltaTime;if (explodeTime > 6){explodeTime = 0;e.stateMachine.ChangeState(new SnowballStateA());return;}}else if (gun){Rigidbody2D rb = e.gameObject.GetComponent<Rigidbody2D>();rb.freezeRotation = false;Vector2 v = new Vector2(dir * gunForce, rb.velocity.y);// rb.AddForce(v);rb.velocity = v;Collider2D[] enemies = Physics2D.OverlapCircleAll(e.transform.position, 0.05f, 1 << LayerMask.NameToLayer("monster"));foreach (Collider2D a in enemies){Vector2 s = a.gameObject.transform.position;Destroy(a.gameObject);GameObject prop = Instantiate(e.props[Random.Range(0, e.props.Length)]);prop.transform.position = s;}}}public override void OnCollisionStay2D(Snowball e, Collision2D collision){ContactPoint2D[] a = collision.contacts;if (gun == false){if (collision.gameObject.tag == "player" && collision.gameObject.transform.FindChild("Gun").GetComponent<Gun>().isFire){//  dir = -GameObject.Find("hero").transform.localScale.x;gun = true;dir = -collision.transform.localScale.x;}}}public override void OnCollisionEnter2D(Snowball e, Collision2D collision){if (gun == false){if (collision.gameObject.tag == "snowball"){gun = true;dir = -collision.transform.localScale.x;}}if (gun){if (collision.gameObject.tag == "wall" || collision.gameObject.tag == "snowball"){dir = -dir;}if (collision.gameObject.tag == "player"){//TODO//雪球带着主角走//transform.SetParent//设置父节点 //collision.transform.SetParent(e.transform);//collision.transform.position = e.transform.position;//torque //旋转}}if (collision.gameObject.tag == "destroyer"){e.gameObject.GetComponent<Animator>().SetTrigger("destrayer");}}public override void Exit(Snowball e){}}//半雪球状态public class SnowballStateA : State<Snowball>{public float explodeTime = 0;int hp = 0;public override void Enter(Snowball e){e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball2;e.gameObject.GetComponent<Animator>().SetTrigger("snowball2");e.gameObject.layer = LayerMask.NameToLayer("monster");hp = 2;}public override void Update(Snowball e){print(hp);if (hp <= 0){e.stateMachine.ChangeState(new SnowballStateB());return;}explodeTime += Time.deltaTime;if (explodeTime > 5 && hp > 0){explodeTime = 0;e.stateMachine.ChangeState(new SnowballState());return;}}public override void Exit(Snowball e){}public override void OnCollisionEnter2D(Snowball e, Collision2D collision){if (collision.gameObject.tag == "bullet"){hp--;}}}//monster被攻击状态;public class SnowballState : State<Snowball>{public float explodeTime = 0;Vector3 s;public int hp = 0;public override void Enter(Snowball e){//取得图片精灵e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball3;e.gameObject.GetComponent<Animator>().SetTrigger("snowball3");e.gameObject.layer = LayerMask.NameToLayer("monster");hp = 3;}public override void Update(Snowball e){print(hp);if (hp <= 0){e.stateMachine.ChangeState(new SnowballStateA());hp = 0;return;}explodeTime += Time.deltaTime;print(explodeTime);//经过多少时    if (explodeTime > 4 && hp > 0){explodeTime = 0;hp = 0;s = e.gameObject.transform.position;GameObject g = Instantiate(e.monster);g.transform.position = s;Destroy(e.gameObject);return;}}public override void OnCollisionEnter2D(Snowball e, Collision2D collision){if (collision.gameObject.tag == "bullet"){hp--;}}}void Start(){stateMachine.Init(this, new SnowballState());}// Update is called once per framevoid Update(){}public void FixedUpdate(){stateMachine.Update();}public void OnCollisionEnter2D(Collision2D collision){stateMachine.OnCollisionEnter2D(this, collision);}public void OnCollisionStay2D(Collision2D collision){stateMachine.OnCollisionStay2D(this, collision);}public void Destory(){Instantiate(balldestory);Destroy(this.gameObject);}}

创建道具

1.添加道具预制体.
2.雪球撞到敌人时敌人死亡,在敌人死亡的地方随机生成一种道具。
3.主角吃到道具增加属性或者加分。

过关判定

  1. 判断场景中没有敌人并且没有雪球并且没有道具就过关了。

转载于:https://www.cnblogs.com/raymondking123/p/8424673.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用webpack搭建个性化项目

安装主包 yarn add webpack webpack-cli webpack-dev-server -D根据项目实际需求安装loaders&#xff0c;webpack-loaders列表 根据项目实际需求安装插件&#xff0c; webpack-plugins列表 常用包列表 包名说明webpackwebpack主程序&#xff0c;配置列表webpack-cliwebpack…

.NET周报【11月第1期 2022-11-07】

国内文章开源安全赋能 - .NET Conf China 2022https://mp.weixin.qq.com/s/_tYpfPeQgyEGsnR4vVLzHg.NET Conf China 2022 是面向开发人员的社区峰会&#xff0c;延续 .NET Conf 2022 的活动&#xff0c;庆祝 .NET 7 的发布和回顾过去一年来 .NET 在中国的发展成果&#xff0c;它…

React - 状态提升

从入门的角度来聊一下React 的状态提升。我们先来看一下React官网是怎么介绍这一概念的&#xff1a;使用 react 经常会遇到几个组件需要共用状态数据的情况。这种情况下&#xff0c;我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理。很简单的一句介绍&#xff0…

saltstack(三) --- salt-httpapi

以下操作均在master上操作 1. 安装api netapi modules&#xff08;httpapi&#xff09;有三种&#xff0c;分别是rest_cherrypy、rest_tornado、rest_wsig&#xff0c;接下来要讲的是rest_cherrypydoc&#xff1a;https://docs.saltstack.com/en/latest/ref/netapi/all/salt.ne…

c++实现二叉搜索树

自己实现了一下二叉搜索树的数据结构。记录一下&#xff1a; #include <iostream>using namespace std;struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode(int value) { valvalue; leftNULL; rightNULL; } };class SearchTree{public:SearchTree();~Sear…

一款自用的翻译小工具,开源了

一款自用的翻译小工具&#xff0c;开源了TranslationTool作者&#xff1a;WPFDevelopersOrg - 唐宋元明清|驚鏵原文链接&#xff1a;https://github.com/Kybs0/TranslationTool此项目使用WPF MVVM开发。框架使用大于等于.NET461。Visual Studio 2019。最初是支持以下&#xff1…

JS使用按位异或方式加密字符串

按位异或加密字符串&#xff0c;字符串加解密都是该函数 缺陷是加密密钥使用的字符最好不要出现需要加密的字符串中的字符&#xff0c;一旦出现原字符与加密字符一样额情况&#xff0c;异或结果为0&#xff0c;导致不能还原字符串&#xff0c;可以考虑更改算法避免这种情况 im…

SCSS 实用知识汇总

1、变量声明 $nav-color: #F90; nav {//$width 变量的作用域仅限于{}内$width: 100px;width: $width;color: $nav-color; }.a {//报错&#xff0c;$width未定义width: $width; } 2、父选择器& scss代码&#xff1a; article a {color: blue;&:hover { color: red } } 编…

【ELK集群+MQ】通用部署方案以及快速实现MQ发布订阅服务功能

前言&#xff1a;大概一年多前写过一个部署ELK系列的博客文章&#xff0c;前不久刚好在部署一个ELK的解决方案&#xff0c;我顺便就把一些基础的部分拎出来&#xff0c;再整合成一期文章。大概内容包括&#xff1a;搭建ELK集群&#xff0c;以及写一个简单的MQ服务。如果需要看一…

python容错

#try: except: else: #为什么叫容错呢&#xff0c;先说说错误&#xff0c;这里说的错误并不是因为马虎或者什么原因在脚本中留下的bug&#xff0c;这个不能容掉&#xff0c;所谓容掉就是略过这个错误&#xff0c;要在测试时候发现并修正&#xff0c;需要容错的错误是在脚本执行…

git stash参数介绍

git stash 用于暂存工作区未提交的内容&#xff0c;便于在同时开发多个分支需要切换时保存当前分支进度。 list 语法 git stash list [<options>] &#xff0c;与git log功能类似&#xff0c;列出储藏列表&#xff0c;options 参数可以参考git log的参数 show 语法 git …

多语言报表的改动方法

在定义上传RTF模板的时候&#xff0c;会有一个是否可翻译的选项&#xff0c;选择之后。就能够上传xlf文件作为翻译内容。 对于已经存在的多语言类型报表&#xff0c;稍作改动之后再上传&#xff0c;可能会出现下面现象&#xff1a; 进程出现了“未完毕”的提示 想要改动非常eas…

自定义Cell的流程

1、.h文件 // // 文 件 名:CHBackupGateWayCell.h // // 版权所有:Copyright © 2018 lelight. All rights reserved. // 创 建 者:lelight // 创建日期:2018/12/19. // 文档说明: // 修 改 人: // 修改日期: //#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGINclass…

JS实时监听DOM元素变化 - MutationObserver

使用 MutationObserver API实时监听DOM元素变化 创建 MutationObserver 实列&#xff0c;接受一个用于监听到DOM元素变化的回调函数 const handleListenChange (mutationsList, observer) > {console.log(mutationsList, observer) } const mutationObserver new Mutati…

LightOJ - 1027 A Dangerous Maze —— 期望

题目链接&#xff1a;https://vjudge.net/problem/LightOJ-1027 1027 - A Dangerous MazePDF (English)StatisticsForumTime Limit: 2 second(s)Memory Limit: 32 MBYou are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. The p…

MASA MAUI Plugin (六)集成个推,实现本地消息推送[Android] 篇

背景MAUI的出现&#xff0c;赋予了广大.Net开发者开发多平台应用的能力&#xff0c;MAUI 是Xamarin.Forms演变而来&#xff0c;但是相比Xamarin性能更好&#xff0c;可扩展性更强&#xff0c;结构更简单。但是MAUI对于平台相关的实现并不完整。所以MASA团队开展了一个实验性项目…

第八天

配置文件 Vi /etc/fstab /dev/vg01/lv01 /dir01 ext4 defaults mount -a 扫描 使用交换空间 1.创建分区 2.mkswap /dev/sda创建交换分区 3.swapon /dev/sda启用交换分区 Linux系统启动过程 1、引导程序 BIOS自检 &#xff08;硬件自检&#xff09; 2、G…

iOS 通知中心(NSNotificationCenter)

NSNotificationCenter 在这里第一步和第二步的顺序可以互换&#xff0c;一般楼主我喜欢先在需要发送消息的页面发送消息&#xff0c;然后再在需要监听的页面注册监听。要注意的是不管是通知中心还是KVO都需要在页面销毁之前移除监听。 注册观察者/*** 观察者注册消息通知*…

vue-router和react-router嵌套路由layout配置方案的区别

最近在学习react&#xff0c;在路由这一块有点看不懂&#xff0c;第一感觉是灵活性很大&#xff0c;想怎么来就怎么来&#xff0c;但问题也来了&#xff0c;稍微复杂一点就GG了&#xff0c;不如vue的傻瓜式配置来的方便。 先说一下vue的路由配置方式&#xff0c;目录结构如下&…

微软加更.NET7中文手册,都有哪些新亮点?

11月8号发布了.NET7&#xff0c;从底层性能改进&#xff0c;到上层API升级&#xff0c;让.NET7综合性能再度提升&#xff01;同时发布了最新的C#11&#xff0c;也带来了很多小惊喜。如何快捷学习最新的.NET7和C#11&#xff1f;答案只有一个&#xff0c;微软官方中文文档&#x…