博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Unity2D]实现背景的移动
阅读量:6239 次
发布时间:2019-06-22

本文共 7520 字,大约阅读时间需要 25 分钟。

    在游戏中通常会实现的效果是玩家主角移动的时候,背景也可以跟着移动,要实现这种效果其实就是获取主角的位置,然后再改变摄像机的位置就可以了,这就需要通过脚本来实现。这个脚本添加到摄像机的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 < 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);    }}

 

转载地址:http://yjdia.baihongyu.com/

你可能感兴趣的文章
Linux coredump
查看>>
Ubuntu 10.04安装水晶(Mercury)无线网卡驱动
查看>>
我的友情链接
查看>>
ElasticSearch 2 (32) - 信息聚合系列之范围限定
查看>>
VS2010远程调试C#程序
查看>>
windows查看端口占用
查看>>
Yii用ajax实现无刷新检索更新CListView数据
查看>>
App 卸载记录
查看>>
JavaScript变量和作用域
查看>>
开源SIP服务器加密软件NethidPro升级
查看>>
Apache Pulsar中的地域复制,第1篇:概念和功能
查看>>
python pip install 出现 OSError: [Errno 1] Operation not permitted
查看>>
从源码分析scrollTo、scrollBy、Scroller方法的区别和作用
查看>>
ObjectOutputStream和ObjectInputStream
查看>>
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
计算机网络与Internet应用
查看>>
oracle在线迁移同步数据,数据库报错
查看>>
linux性能剖析工具
查看>>
flutter中的异步
查看>>
计算机高手也不能编出俄罗斯方块——计算机达人成长之路(16)
查看>>