[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 = ; i < layerArray.Length; 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);
- }
- }
[Unity2D]实现背景的移动的更多相关文章
- Unity2D 背景图铺满与Camera.Size的计算公式
在unity制作2D游戏的教程,背景图sprite铺满显示时Camaer的Size调到多少合适,作个笔记. 资源参数 background.png 2048x640,Sprite的像素单位:100 调 ...
- unity2D背景移动补偿从而获得3d错觉效果
2d平台跳跃游戏当相机移动的时候背景跟随进行微调移动,从而使得玩家获得3d的错觉 using System.Collections;using System.Collections.Generic;u ...
- unity2D限制位置的背景移动补偿效果
有时候我们想要背景可以跟随相机移动补偿,但是又不想该背景物体离原来的位置太远,比如我们想要一棵树在一个房子的后面,然后使用相机补偿使其跟随移动,达到3D错觉效果,但是我们又不想该物体偏离房屋太远.假设 ...
- Unity2D多分辨率屏幕适配方案(转载)
一下内容转自:http://imgtec.eetrend.com/forum/3992 此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有 ...
- [Unity2D]游戏引擎介绍
由于手机游戏的流行,目前2D游戏开发的需求量也越来越大了,因此Unity3D游戏引擎也增加了2D游戏开发的支持,之前是可以通过第三方的2D游戏组件可以支持2D游戏开发,现在是官方的版本就支持了.Uni ...
- [原创]一种Unity2D多分辨率屏幕适配方案
此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有使用第三方2D插件,如Uni2D,2D toolkit等开发的游戏,NGUI插件不受这个 ...
- 一种Unity2D多分辨率屏幕适配方案
http://www.cnblogs.com/flyFreeZn/p/4073655.html 此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏 ...
- CSS3 background-image背景图片相关介绍
这里将会介绍如何通过background-image设置背景图片,以及背景图片的平铺.拉伸.偏移.设置大小等操作. 1. 背景图片样式分类 CSS中设置元素背景图片及其背景图片样式的属性主要以下几个: ...
- 冒泡,setinterval,背景图的div绑定事件,匿名函数问题
1.会冒泡到兄弟元素么? $(function(){ $("#a").click(function(){alert("a")}) $("#b" ...
随机推荐
- The CompilerVersion constant identifies the internal version number of the Delphi compiler.
http://delphi.wikia.com/wiki/CompilerVersion_Constant The CompilerVersion constant identifies the in ...
- django-cms 代码研究(七)杂七杂八
实体关系图 核心对象: cms_page/cms_placeholder/cms_cmsplugin. page模型类继承关系图 CMSPlugin&Placeholder模型类继承关系图 = ...
- javascript quine
javascript有一些奇怪的性质,恩,比如说,非常容易写一个quine,即自己输出自己代码的东西. function a(){console.log(a.toString()+";a() ...
- 【系统】CentOS、Ubuntu、Debian三个linux比较异同
CentOS.Ubuntu.Debian三个linux比较异同 2014-07-31 12:58 53428人阅读 评论(6) ...
- Product of Array Exclude Itself
Given an integers array A. Define B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], calculate B WI ...
- Sybase IQ导出文件的几种方式
IQ有四种方法,将表的数据导出为文本文件:1.重定向 SELECT * FROM TABLE1 ># D:MYDATATABLE1.TXT -- 文件生成在执行语句的客户端上 2.通过选项导出 ...
- wx.html2.WebView在 target="_blank" or rel="external" 没有反映的解决方法
在wx.html2.EVT_WEBVIEW_LOADED中,用WebView.RunScript运行删除链接目标的脚本 javaScriptStr = '''function deleteBlank( ...
- HDU 5724 Chess (状态压缩sg函数博弈) 2016杭电多校联合第一场
题目:传送门. 题意:有n行,每行最多20个棋子,对于一个棋子来说,如果他右面没有棋子,可以移动到他右面:如果有棋子,就跳过这些棋子移动到后面的空格,不能移动的人输. 题解:状态压缩博弈,对于一行2^ ...
- 2.简单工厂模式(Simple Factory)
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //如果 ...
- UVa 11524:In-Circle(解析几何)
Problem EIn-CircleInput: Standard Input Output: Standard Output In-circle of a triangle is the circl ...