Как добавить параллакс к объектам, созданным в режиме воспроизведения и воссозданным с позиции камеры в Unity 3d - PullRequest
0 голосов
/ 20 октября 2018

Итак, моя бесконечная 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);
}
}

1 Ответ

0 голосов
/ 20 октября 2018

Во-первых, вы должны изучить объединение ваших горных объектов, чтобы не тратить впустую ресурсы процессора и памяти на их создание.

Как только они будут объединены в вашем 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.

Что-то вродеthis:

// 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 как дети, тогда вы можете просто переместитьпреобразование этих родительских игровых объектов вместо прохождения каждой отдельной горы.Конечно, сумма, необходимая для ее перемещения, одинакова.

...