首页 > 解决方案 > 如何为在播放模式下实例化并在 Unity 3d 中使用相机位置重新创建的对象添加视差

问题描述

所以我无尽的 2d 游戏在背景中有 2 层山脉,我想在上面添加视差,近层需要比演员/相机慢,而远层要最慢。问题是,我不能直接向它们添加动作脚本,因为它们是根据随机主题颜色在播放模式下随机实例化的,所以它们是从下面的脚本中一个接一个地创建的,但我想添加一个动作在它们上的 x 轴上比相机速度慢,同时也让它在最后一个结束时连续重新创建。

这是创建新山脉的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PathManager : MonoBehaviour {

public static PathManager Instance;
public GameObject CoinFragments;
public GameObject SlideArrow;

public float parallaxSpeed = 5f; //

private GameObject lastPathObject;
private float PathXPosition;

private GameObject lastMountainFar;
private float MountainFarXPosition;
private GameObject lastMountainNear;
private float MountainNearXPosition;

private float StarXPostion;

private float lastCameraX;  //

// Use this for initialization
void Start () {
    Instance = this;
}

// Update is called once per frame
void Update()
{

}


private void LateUpdate()
{
    // Check for new Near Mountain
    if (lastMountainNear != null && GamePlayCameraManager.Instance.MainCamera.transform.position.x > lastMountainNear.transform.position.x)
    {
        this.GenerateNearMountain();
    }

    // Check for new Far Mountain
    if (lastMountainFar != null && GamePlayCameraManager.Instance.MainCamera.transform.position.x > lastMountainFar.transform.position.x)
    {
        this.GenerateFarMountain();
    }
}



// Start Creating Mountains
public void StartMountainCreation(){
    MountainNearXPosition = GamePlayCameraManager.Instance.MainCamera.transform.position.x;
    MountainFarXPosition = GamePlayCameraManager.Instance.MainCamera.transform.position.x;
    this.GenerateNearMountain();
    this.GenerateFarMountain();
}

private void GenerateNearMountain(){
    Vector3 MountainPosition = new Vector3(MountainNearXPosition - 4f, -3.6f, 10f);
    lastMountainNear = Instantiate(ThemeManager.Instance.SelectedMountainNear, MountainPosition, Quaternion.identity);
    MountainNearXPosition = MountainNearXPosition + lastMountainNear.GetComponent<Renderer>().bounds.size.x - 0.01f;

    //float deltaX = GamePlayCameraManager.Instance.MainCamera.transform.position.x - lastCameraX;
    //lastCameraX = GamePlayCameraManager.Instance.MainCamera.transform.position.x;
    //lastMountainNear.transform.position += Vector3.right * (deltaX * parallaxSpeed);
}

private void GenerateFarMountain(){
    Vector3 MountainPosition = new Vector3(MountainFarXPosition - 4f, -3.6f, 22f);
    lastMountainFar = Instantiate(ThemeManager.Instance.SelectedMountainFar, MountainPosition, Quaternion.identity);
    MountainFarXPosition = MountainFarXPosition + lastMountainFar.GetComponent<Renderer>().bounds.size.x - 0.01f;
}

这是我的相机移动脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GamePlayCameraManager : MonoBehaviour {

public static GamePlayCameraManager Instance;   // Singleton Instance
public Camera MainCamera;   // Main Camera

private Vector3 offset;

// Use this for initialization
void Start () {
    Instance = this;
    MainCamera.transform.position = new Vector3(0, 0, -10);
}

// Update is called once per frame
void Update () {

}

void LateUpdate()
{
    if (GameStateManager.GameState == GameState.Set || GameStateManager.GameState == GameState.Playing)
        MainCamera.transform.position = new Vector3(this.offset.x + ActorManager.Instance.Actor.transform.position.x + 0.8f, 0, -10);
}

// Fixed Update Method
void FixedUpdate(){

}

public void FindCameraOffset(){
    this.offset = ActorManager.Instance.Actor.transform.position - MainCamera.transform.position + new Vector3(1.5f, 0f, 0f);
}
}

标签: c#unity3d2d-gamesgame-developmentunity3d-2dtools

解决方案


首先,您应该考虑合并您的山对象,这样您就不会无休止地浪费 CPU 和内存来创建它们。

一旦你将它们汇集到你的 中PathManager,你首先需要知道相机在最后一帧中移动了多远,然后告诉山脉根据它移动。您将不得不PathManager在您的相机管理器中引用您的。

在您的相机管理器中LateUpdate

if (GameStateManager.GameState == GameState.Set || GameStateManager.GameState == GameState.Playing) {     
    Vector3 newPosition = new Vector3(this.offset.x + ActorManager.Instance.Actor.transform.position.x + 0.8f, 0, -10);
    float cameraMoveAmount = newPosition.x - MainCamera.transform.position.x;
    MainCamera.transform.position = newPosition;
    pathManager.MoveMountains(cameraMoveAmount) 
}

然后,在您的 PathManager 中,使用 moveAmount 更改所有山脉的位置,以及创建下一个山脉的位置。在此之后,您应该检查是否需要显示新的山脉,而不是在 PathManager 的LateUpdate. 这是因为您需要在检查添加新的山脉之前移动山脉,并且如果您在不同的LateUpdate调用中拥有它们,则无法保证哪个先发生。

像这样的东西:

// How fast the mountain layers are going to move in the direction of the camera.    
// 0.0f - will not move with the camera, mountains will slide out of frame at normal speed.
// 1.0f - will move with the camera, no movement will be visible in frame.
public float nearMountainMoveSpeed = 0.5;
public float farMountainMoveSpeed = 0.9f;

. . .

public void MoveMountains(float cameraMoveAmount) {
    float nearMountainParallaxMove = nearMountainMoveSpeed * cameraMoveAmount;
    float farMountainParallaxMove = farMountainMoveSpeed * cameraMoveAmount;

    // Move the near mountains & their next placement
    MountainNearXPosition += nearMountainParallaxMove;
    foreach (GameObject nearMountain in pooledNearMountains) {
        nearMountain.transform.position = nearMountain.transform.position + new Vector3(nearMountainParallaxMove,0f,0f);
    }    

    // Check for new Near Mountain
    if (lastMountainNear != null && GamePlayCameraManager.Instance.MainCamera.transform.position.x > lastMountainNear.transform.position.x) {
        this.GenerateNearMountain();
    }

    // Move the far mountains & their next placement
    MountainFarXPosition += farMountainParallaxMove;
    foreach (GameObject farMountain in pooledFarMountains) {
        farMountain.transform.position = farMountain.transform.position + new Vector3(farMountainParallaxMove,0f,0f);
    }

    // Check for new Far Mountain
    if (lastMountainFar != null && GamePlayCameraManager.Instance.MainCamera.transform.position.x > lastMountainFar.transform.position.x) {
        this.GenerateFarMountain();
    }
}

顺便说一句,如果您最终更改了代码并拥有一个将所有 farMountains 作为子项的游戏对象和一个将所有 nearMountains 作为子项的游戏对象,那么您可以只移动这些父游戏对象的变换,而不是循环遍历每个个别山。当然,您需要移动它的数量是相同的。


推荐阅读