热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[Unity2D]实现背景的移动

在游戏中通常会实现的效果是玩家主角移动的时候,背景也可以跟着移动,要实现这种效果其实就是获取主角的位置,然后再改变摄像机的位置就可以了&#

    在游戏中通常会实现的效果是玩家主角移动的时候,背景也可以跟着移动,要实现这种效果其实就是获取主角的位置,然后再改变摄像机的位置就可以了,这就需要通过脚本来实现。这个脚本添加到摄像机的GameObject上,相当于摄像机的控制器。

using UnityEngine;
using System.Collections;public class CameraController : MonoBehaviour
{
public PlayerStateController.playerStates currentPlayerState = PlayerStateController.playerStates.idle;public GameObject playerObject = null;//玩家游戏对象public float cameraTrackingSpeed = 0.2f;private Vector3 lastTargetPosition = Vector3.zero;//玩家最后的位置private Vector3 currTargetPosition = Vector3.zero;//玩家当前的位置private float currLerpDistance = 0.0f;void Start(){Vector3 playerPos = playerObject.transform.position;//玩家的位置Vector3 cameraPos = transform.position;//相机的位置Vector3 startTargPos = playerPos;//玩家初始化位置
startTargPos.z = cameraPos.z;lastTargetPosition = startTargPos;currTargetPosition = startTargPos;currLerpDistance = 1.0f;}void OnEnable(){PlayerStateController.onStateChange += onPlayerStateChange;}void OnDisable(){PlayerStateController.onStateChange -= onPlayerStateChange;}void onPlayerStateChange(PlayerStateController.playerStates newState){currentPlayerState = newState;}void LateUpdate(){onStateCycle();currLerpDistance += cameraTrackingSpeed;// 取两个向量之间的值transform.position = Vector3.Lerp(lastTargetPosition, currTargetPosition, currLerpDistance);}void onStateCycle(){switch (currentPlayerState){case PlayerStateController.playerStates.idle:trackPlayer();break;case PlayerStateController.playerStates.left:trackPlayer();break;case PlayerStateController.playerStates.right:trackPlayer();break;case PlayerStateController.playerStates.jump:trackPlayer();break;case PlayerStateController.playerStates.firingWeapon:trackPlayer();break;}}void trackPlayer(){Vector3 currCamPos = transform.position;//当前相机位置Vector3 currPlayerPos = playerObject.transform.position;//当前玩家位置if (currCamPos.x == currPlayerPos.x && currCamPos.y == currPlayerPos.y)//位置一样,不移动
{currLerpDistance = 1.0f;lastTargetPosition = currCamPos;currTargetPosition = currCamPos;return;}currLerpDistance = 0.0f;lastTargetPosition = currCamPos;//最后的位置为相机的位置
currTargetPosition = currPlayerPos;//当前的位置为玩家的位置
currTargetPosition.z = currCamPos.z;}void stopTrackingPlayer(){Vector3 currCamPos = transform.position;currTargetPosition = currCamPos;lastTargetPosition = currCamPos;currLerpDistance = 1.0f;}
}

    如果要把背景的元素区分开来,不同的背景对象有不同的移动速度那么实现的方式会稍微复杂一点点。

1、首先得把背景的GameObject进行一下分类,如下所示:

2、给这个背景GameObject的分组添加一个脚本,也就是给_ParallaxLayers添加脚本,主要需要的参数就是摄像机对象、背景GameObject的分类数组、移动速度等。

脚本如下所示:

using UnityEngine;
using System.Collections;public class ParallaxController : MonoBehaviour
{
public GameObject[] clouds;//云层public GameObject[] nearHills;//近山public GameObject[] farHills;//远山public GameObject[] lava;//地面// 移动的速度public float cloudLayerSpeedModifier;public float nearHillLayerSpeedModifier;public float farHillLayerSpeedModifier;public float lavalLayerSpeedModifier;public Camera myCamera;private Vector3 lastCamPos;void Start(){lastCamPos = myCamera.transform.position;//获取相机的位置
}void Update(){Vector3 currCamPos = myCamera.transform.position;float xPosDiff = lastCamPos.x - currCamPos.x;//计算相机x轴的变化
adjustParallaxPositionsForArray(clouds, cloudLayerSpeedModifier, xPosDiff);adjustParallaxPositionsForArray(nearHills, nearHillLayerSpeedModifier, xPosDiff);adjustParallaxPositionsForArray(farHills, farHillLayerSpeedModifier, xPosDiff);adjustParallaxPositionsForArray(lava, lavalLayerSpeedModifier, xPosDiff);lastCamPos = myCamera.transform.position;}// 数组来存储游戏对象void adjustParallaxPositionsForArray(GameObject[] layerArray, float layerSpeedModifier, float xPosDiff){// 遍历改变精灵的位置for (int i = 0; i ){Vector3 objPos = layerArray[i].transform.position;objPos.x += xPosDiff * layerSpeedModifier;layerArray[i].transform.position = objPos;}}
}

 

另外一种实现的方案脚本:

using UnityEngine;
using System.Collections;public class CameraFollow : MonoBehaviour
{
public float xMargin = 1f; // Distance in the x axis the player can move before the camera follows.public float yMargin = 1f; // Distance in the y axis the player can move before the camera follows.public float xSmooth = 8f; // How smoothly the camera catches up with it's target movement in the x axis.public float ySmooth = 8f; // How smoothly the camera catches up with it's target movement in the y axis.public Vector2 maxXAndY; // The maximum x and y coordinates the camera can have.public Vector2 minXAndY; // The minimum x and y coordinates the camera can have.private Transform player; // Reference to the player's transform.void Awake (){// Setting up the reference.// 查找玩家游戏对象player = GameObject.FindGameObjectWithTag("Player").transform;}// 检查边缘bool CheckXMargin(){// Returns true if the distance between the camera and the player in the x axis is greater than the x margin.// x轴变化的绝对值大于设定值return Mathf.Abs(transform.position.x - player.position.x) > xMargin;}// 检查边缘bool CheckYMargin(){// Returns true if the distance between the camera and the player in the y axis is greater than the y margin.// y轴变化的绝对值大于设定值return Mathf.Abs(transform.position.y - player.position.y) > yMargin;}void FixedUpdate (){TrackPlayer();}void TrackPlayer (){// By default the target x and y coordinates of the camera are it's current x and y coordinates.float targetX = transform.position.x;float targetY = transform.position.y;// If the player has moved beyond the x margin...if(CheckXMargin())// ... the target x coordinate should be a Lerp between the camera's current x position and the player's current x position.// 在当前位置和最新位置之间插值// Time.deltaTime 增量时间 以秒计算,完成最后一帧的时间(只读)。使用这个函数使和你的游戏帧速率无关targetX = Mathf.Lerp(transform.position.x, player.position.x, xSmooth * Time.deltaTime);// If the player has moved beyond the y margin...if(CheckYMargin())// ... the target y coordinate should be a Lerp between the camera's current y position and the player's current y position.targetY = Mathf.Lerp(transform.position.y, player.position.y, ySmooth * Time.deltaTime);// The target x and y coordinates should not be larger than the maximum or smaller than the minimum.// 把目标值限制在固定的范围targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);// Set the camera's position to the target position with the same z component.// 设置相机的位置transform.position = new Vector3(targetX, targetY, transform.position.z);}
}

 



推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 利用决策树预测NBA比赛胜负的Python数据挖掘实践
    本文通过使用2013-14赛季NBA赛程与结果数据集以及2013年NBA排名数据,结合《Python数据挖掘入门与实践》一书中的方法,展示如何应用决策树算法进行比赛胜负预测。我们将详细讲解数据预处理、特征工程及模型评估等关键步骤。 ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文将详细探讨Linux pinctrl子系统的各个关键数据结构,帮助读者深入了解其内部机制。通过分析这些数据结构及其相互关系,我们将进一步理解pinctrl子系统的工作原理和设计思路。 ... [详细]
author-avatar
北京超凡传媒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有