Unity教程(十二)视差背景

news2024/9/28 21:25:14

Unity开发2D类银河恶魔城游戏学习笔记

Unity教程(零)Unity和VS的使用相关内容
Unity教程(一)开始学习状态机
Unity教程(二)角色移动的实现
Unity教程(三)角色跳跃的实现
Unity教程(四)碰撞检测
Unity教程(五)角色冲刺的实现
Unity教程(六)角色滑墙的实现
Unity教程(七)角色蹬墙跳的实现
Unity教程(八)角色攻击的基本实现
Unity教程(九)角色攻击的改进

Unity教程(十)Tile Palette搭建平台关卡
Unity教程(十一)相机
Unity教程(十二)视差背景

Unity教程(十三)敌人状态机


如果你更习惯用知乎
Unity开发2D类银河恶魔城游戏学习笔记目录


文章目录

  • Unity开发2D类银河恶魔城游戏学习笔记
  • 前言
  • 一、概述
  • 二、视差背景
    • (1)添加背景
    • (2)调整层次
    • (3)视差背景实现
  • 三、无尽滚动背景


前言

本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记,如有错误,欢迎指正。

本节添加视差背景。
对应b站视频:
【Unity教程】从0编程制作类银河恶魔城游戏P45
【Unity教程】从0编程制作类银河恶魔城游戏P46


一、概述

本节给游戏添加背景,我们做一个视差背景来增强视觉效果。
视差背景是通过多层次的背景来模拟透视视差效果。就是当发生移动时,离照相机越近的背景移动越快;反之越慢。这样,我们的背景就会形成类似于透视视差的效果。
我参照了这篇文章 聊聊2D游戏视差背景的实现
除此之外教程中还讲解了无限滚动的背景怎么实现。

二、视差背景

(1)添加背景

背景图的路径:
Assets->Graphics->Surroundings->Medieval_Castle->Background
将layer_1、layer_2拖入场景中
在这里插入图片描述
注意:(1)如果Tile Palette画笔工具还开着会向Tilemap的背景上绘制。所以记得拖入背景图前关掉。
(2)查看右上角2D选项有没有被关掉,关掉会显示不出背景。
在这里插入图片描述

(2)调整层次

调整Sprite Renderer中的Sorting Layer参数,调整被渲染的顺序
我们先添加四个层Background、Ground、Enemy、Player
在这里插入图片描述
在这里插入图片描述
给天空背景层重命名为BG_Sky_Layer,城堡背景层重命名为BG_City_Layer。
Sorting Layer都设置为Background,并分别修改Order inLayer为-10和-9。
在这里插入图片描述
在这里插入图片描述
重置他们的位置,挂靠在空物体下面,并把空物体重命名为Background
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Animator层次设定为Player
在这里插入图片描述
将Tilemap里Ground层次设置为Ground,Background层次设置为Background
在这里插入图片描述
在这里插入图片描述

(3)视差背景实现

天空层复制两次成为天空层的子层。改变两个子层的位置,x的值一个改为-40,一个改为40。
在这里插入图片描述
城市层进行相同的处理
在这里插入图片描述
创建脚本ParallaxBackground
创建变量xPosition,在进入状态时记录背景的初始位置。
创建变量parallaxEffect来表示视差效应,控制背景跟随相机的速度。
在Update()中每次用背景初始位置xPosition加上计算出的要移动的距离distanceToMove,来更新背景位置

//ParallaxBackground:视差背景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParallaxBackground : MonoBehaviour
{

    private GameObject cam;
    [SerializeField] private float parallaxEffect;

    private float xPosition;

    // Start is called before the first frame update
    void Start()
    {
        cam = GameObject.Find("Main Camera");

        xPosition = transform.position.x;
    }

    // Update is called once per frame
    void Update()
    {
        float distanceToMove = cam.transform.position.x * parallaxEffect;

        transform.position=new Vector3(xPosition + distanceToMove,transform.position.y);
    }
}

将脚本分别挂载到BG_Sky_Layer和BG_City_Layer,根据想要的效果调节ParallaxEffect的值
在这里插入图片描述
在这里插入图片描述
效果对比如下:
ParallaxEffect都为0
在这里插入图片描述

BG_Sky_Layer:ParallaxEffect为1,BG_City_Layer:ParallaxEffect为0.8
在这里插入图片描述

可以看出增添视差效果后两层背景的移动速度明显不一样了,更具有空间效果。

按照教程做完我发现,假如相机初始位置为负可能造成背景反向移动,以比较极端的情况为例:
我将场景向x负方向拖,Main Camera的x坐标为-109.4
在这里插入图片描述
这时运行,背景会瞬间向后移动很长的距离。
在这里插入图片描述
虽然我们的初始位置一般定在中心,基本不会出现这种情况,但我还是想进行改进。
我们只要在进入状态时记录相机的初始位置,并且在计算要移动的距离时,将使用相机的x坐标改为使用相机x方向的位移即可。

//ParallaxBackground:视差背景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParallaxBackground : MonoBehaviour
{

    private GameObject cam;
    [SerializeField] private float parallaxEffect;

    private float xPosition;
    private float xCamPosition;

    // Start is called before the first frame update
    void Start()
    {
        cam = GameObject.Find("Main Camera");

        xPosition = transform.position.x;

        xCamPosition= cam.transform.position.x;
    }

    // Update is called once per frame
    void Update()
    {
        float distanceToMove = (cam.transform.position.x - xCamPosition) * parallaxEffect;

        transform.position=new Vector3(xPosition + distanceToMove,transform.position.y);
    }
}

这时即使初始位置比较极端程序也可以正常运行
在这里插入图片描述

三、无尽滚动背景

制作无尽滚动的背景我们使用可拼接重复的图片。如下所示,如果一瞬间移动背景使得移动过来的部分与原背景完全一致,在相机中我们是看不出来的。
如果没有视差背景和摄像机应该同步移动,现在背景落后于摄像机,所以每当背景落后于相机一个图片长度的时候我们移动一次背景,背景就可以不断随着角色前移,实现背景的无尽滚动。
在这里插入图片描述
图片的长度length通过SpriteRenderer获得。
判断背景与相机的距离差值与图片长度的关系。差值大于length,则前移length;小于-legth,则后移length
和教程中实现方式对应的示意图如下:
在这里插入图片描述

由图示可知距离插值等于 d i s t a n c e D i f f e r e n c e = c a m P o s i t i o n ∗ ( 1 − E f f e c t ) − x P s i o t i o n distanceDifference=camPosition * (1 - Effect) - xPsiotion distanceDifference=camPosition(1Effect)xPsiotion
对应代码

//ParallaxBackground:视差背景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParallaxBackground : MonoBehaviour
{

    private GameObject cam;
    [SerializeField] private float parallaxEffect;

    private float xPosition;

    private float length;


    // Start is called before the first frame update
    void Start()
    {
        cam = GameObject.Find("Main Camera");

        length=GetComponent<SpriteRenderer>().bounds.size.x;

        xPosition = transform.position.x;
    }

    // Update is called once per frame
    void Update()
    {
        float distanceToMove = cam.transform.position.x * parallaxEffect;
        float distanceMoved = cam.transform.position.x * (1 - parallaxEffect);

        transform.position=new Vector3(xPosition + distanceToMove,transform.position.y);


        if (distanceMoved > xPosition + length)
            xPosition = xPosition + length;
        else if (distanceMoved < xPosition - length)
            xPosition = xPosition - length;
    }
}

和改进后实现方式对应的示意图如下:
在这里插入图片描述

由图示可知距离插值等于 d i s t a n c e D i f f e r e n c e = ( c a m P o s i t i o n − x P o s i t i o n ) ∗ ( 1 − E f f e c t ) − ( x P o s i t i o n − x C a m P o s i t i o n ) distanceDifference=(camPosition-xPosition) * (1 - Effect) - (xPosition-xCamPosition) distanceDifference=(camPositionxPosition)(1Effect)(xPositionxCamPosition)

//ParallaxBackground:视差背景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParallaxBackground : MonoBehaviour
{

    private GameObject cam;
    [SerializeField] private float parallaxEffect;

    private float xPosition;
    private float xCamPosition;

    private float length;


    // Start is called before the first frame update
    void Start()
    {
        cam = GameObject.Find("Main Camera");

        length=GetComponent<SpriteRenderer>().bounds.size.x;

        xPosition = transform.position.x;

        xCamPosition= cam.transform.position.x;
    }

    // Update is called once per frame
    void Update()
    {
        float distanceToMove = (cam.transform.position.x - xCamPosition) * parallaxEffect;
        float distanceDifference = (cam.transform.position.x - xCamPosition) *(1- parallaxEffect)-(xPosition-xCamPosition);

        transform.position=new Vector3(xPosition + distanceToMove,transform.position.y);


        if (distanceDifference > length)
            xPosition = xPosition + length;
        else if (distanceDifference < -length)
            xPosition = xPosition + - length;
    }
}

在这里插入图片描述

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

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

相关文章

生命科学与医学类专业数据库有哪些

一、Cell Press Cell Press的期刊是生物工程科学方面权威的学术期刊&#xff0c;影响因子一直名列前茅&#xff0c;在生物、医学研究领域享有很高声誉&#xff0c;是公认的了解生物医学最新学术成果的必读文献。可通过Elsevier的ScienceDirect平台访问全文。 二、中华医学期刊…

黑神话:悟空,第一回合boss位置详解大全!

《黑神话&#xff1a;悟空》是一款以中国经典神话为背景的动作角色扮演游戏&#xff0c;玩家将在游戏中扮演齐天大圣孙悟空&#xff0c;经历一系列惊心动魄的冒险和战斗。在游戏的第一章节中&#xff0c;玩家将会遇到各种强大的BOSS&#xff0c;击败它们不仅可以顺利通关&#…

一场机器人盛宴:如何兼顾“月亮”与“六便士”? |直击2024 WRC

一年一度的世界机器人大会是整个机器人行业发展的缩影&#xff0c;从中能看到的是整个行业以及企业内心所怀揣的对未来的理想。 而就2024年来说&#xff0c;这是一场属于机器人的盛宴&#xff0c;也是具身智能公司的集体狂欢。 作者|思杭 编辑|皮爷 出品|产业家 “我们…

Python高阶函数 - reduce

reduce函数作用就是把一个函数作用在一个序列上&#xff0c;这个函数必须接收两个参数&#xff0c;reduce函数把结果继续和序列的下一个元素做累积计算&#xff0c;跟递归有点相似。 reduce函数参数主要包括两个&#xff0c;一个是以上说的作用函数&#xff0c;另外一个是seque…

Shell 脚本开发学习

Shell 教程 1. Shell 脚本 Shell 脚本&#xff08;shell script&#xff09;&#xff0c;是一种为shell编写的脚本程序。注&#xff1a;shell和shell script是两个不同的概念。 2. Shell 环境 Linux 的 Shell 种类众多&#xff0c;常见的有&#xff1a; 。Bourne Shell (/u…

gpt_academic,一个读/写论文的利器

推荐gpt_academic&#xff0c;一个读/写论文的利器 最近看到github上标星60K的读论文和写论文的AI开源工具。 我自己试了一下&#xff0c;配置了五个公司&#xff08;openai、kimi、讯飞、阿里和百度&#xff09;AI的key&#xff0c;能正常使用。 然后我让它读论文&#xff0c…

15 字符数组与二维数组(定义、初始化、访问、遍历、内存调试分析),数组编程练习

目录 1 字符数组&#xff08;字符串&#xff09; 1.1 介绍 1.2 字符数组的定义与初始化 1.2.1 使用字符列表进行初始化 1.2.1.1 VS Code 调试内存 1.2.2 使用字符串字面量进行初始化 1.3 字符数组的访问和遍历 2 多维数组 2.1 介绍 2.2 二维数组的定义 2.2.1 先定义…

探索ACPL-302J光耦合器的多功能性

ACPL-302J是一款高度集成的2.5A栅极驱动光耦合器&#xff0c;经过精心设计&#xff0c;可用于驱动大功率工业应用中的IGBT&#xff08;绝缘栅双极晶体管&#xff09;和功率MOSFET。其精巧的设计和强大的功能使其成为效率、安全性和可靠性至关重要的系统中不可或缺的组件。本文详…

Nature | 应变不敏感的柔性可拉伸射频组件(柔性传感/柔性健康监测/可穿戴电子/界面调控/电子皮肤/柔性电子/集成电路)

韩国首尔汉阳大学Yei Hwan Jung和Hyoungsuk Yoo团队&#xff0c;在《Nature 》上发布了一篇题为“Strain-invariant stretchable radio-frequency electronics”的论文。论文内容如下&#xff1a; 一、 摘要 可实现无线通信和无线能量传输功能的射频&#xff08;radio-frequen…

《黑神话:悟空》专题 收集相关的攻略、壁纸、视频、辅助器等

本专题专注于收集游戏《黑神话&#xff1a;悟空》的相关资料&#xff0c;如游戏攻略、壁纸、音乐、视频等。《黑神话&#xff1a;悟空》是一款以中国神话为背景的动作角色扮演游戏。故事取材于中国古典小说“四大名著”之一的《西游记》。你将扮演一位“天命人”&#xff0c;为…

大佬都在用的抓包工具:Wireshark、BurpSuite分享,零基础入门到精通 (1)

各位师傅们&#xff0c;你们平常用什么抓包工具&#xff1f; 抓包工具多种多样&#xff0c;比如Charles、Microsoft Network Monitor、Tcpdump。今天这些我们都不介绍&#xff0c;而是来介绍两款非常优秀的大牛都在用的抓包工具&#xff1a;Wireshark、BurpSuite。 1 Wiresh…

【SQL】连续出现的数字

目录 题目 分析 代码 题目 表&#xff1a;Logs ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ---------------------- 在 SQL 中&#xff0c;id 是该表的主键。 id 是一个自增列。找出…

python爬虫——入门

一、概念 万维网之所以叫做网&#xff0c;是因为通过点击超链接或者进入URL&#xff0c;我们可以访问任何网络资源&#xff0c;从一个网页跳转到另一个网页&#xff0c;所有的相关资源连接在一起&#xff0c;就形成了一个网。 而爬虫呢&#xff0c;听名字就让人想起来一个黏糊…

2024最全性能测试学习指南【建议收藏】

浅谈软件测试中的性能测试 很多时候&#xff0c;我们都知道软件有黑白盒测试&#xff0c;但往往还遗漏掉了一个性能测试。 在下面的这篇文章中&#xff0c;就带领大家来了解性能测试。一起来学习吧~ 学习目录 一、 性能测试概念 二、 性能测试指标 三、 性能测试种类 四、 性能…

【科技前沿探索】电路仿真软件SmartEDA:重塑教学新纪元,解锁学习无限可能

在信息爆炸的时代&#xff0c;科技的力量正以前所未有的速度改变着我们的生活方式&#xff0c;而教育领域也不例外。电路学&#xff0c;作为理工科教育中的基石&#xff0c;其复杂性与抽象性常让初学者望而生畏。但幸运的是&#xff0c;随着电路仿真软件SmartEDA的横空出世&…

MEDICAL SAM 2: SEGMENT MEDICAL IMAGES AS VIDEO VIA SEGMENT ANYTHING MODEL 2

Jiayuan ZhuUniversity of Oxfordjiayuan.zhuieee.orgYunli QiUniversity of OxfordJunde WuUniversity of Oxfordjundewuieee.org 原文链接:https://arxiv.org/pdf/2408.00874 代码链接&#xff1a;https://github.com/MedicineToken/Medical-SAM2 文章的主要贡献如下&…

TCRAG:图灵完备 RAG + 高效医学诊断

TCRAG&#xff1a;图灵完备 RAG 高效医学诊断 提出背景图灵完备过程解法拆解分析性关联图 论文&#xff1a;TC–RAG: Turing–Complete RAG’s Case study on Medical LLM Systems 提出背景 RAG技术大致可分为朴素RAG和高级RAG两类&#xff1a; 朴素RAG采用简单的"检索…

固态硬盘数据丢失了如何恢复?

在数字化时代&#xff0c;固态硬盘&#xff08;SSD&#xff09;因其高速读写性能成为许多用户首选的存储设备。然而&#xff0c;数据丢失的风险也随之而来。无论是误删除、系统崩溃还是硬件故障&#xff0c;都可能导致宝贵的数据瞬间消失。本文将为您提供一套全面的固态硬盘数据…

MinIO 企业级人工智能存储的数据和驱动器同等重要

为什么会这样&#xff1f;这是因为硬件故障发生在不同的级别。有一些中断会导致整个站点瘫痪。然后&#xff0c;会出现中断&#xff0c;导致集群中的一部分节点瘫痪。但是&#xff0c;在更精细的硬盘驱动器位级别也存在故障&#xff0c;这些故障需要复制本身无法提供的另一种类…

AI问答对比-谁是世界上最可爱的人?

无聊的时候突然想起皇后问魔镜问题的情节&#xff0c;于是突发奇想&#xff0c;找了几个AI问答助手试试”谁是世界上最可爱的人&#xff1f;”&#xff0c;看看AI们会怎么回答。 问之前还满怀期待的猜测&#xff1a;它们有可能回答自己的所属公司的老板吗&#xff0c;或是直白…