c# - 如何为在播放模式下实例化并在 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);
}
}
解决方案
首先,您应该考虑合并您的山对象,这样您就不会无休止地浪费 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 作为子项的游戏对象,那么您可以只移动这些父游戏对象的变换,而不是循环遍历每个个别山。当然,您需要移动它的数量是相同的。
推荐阅读
- python - Makefile 不能使用`conda activate`
- protractor - 从函数内的 promise 返回一个值到测试规范
- javascript - contenteditable 选择文本时添加粗体、斜体格式选项
- wordpress - 登录后需要重定向wordpress用户并删除wp-admin工具栏并限制对wp-admin和个人资料页面的访问
- c# - 如何在 Python Flask 应用程序的后端运行 C# 项目?
- angular - 是否可以从本地服务结构集群内部使用 UseProxyToSpaDevelopmentServer?
- java - 为什么 Cat 类使用 Cat 父级作为实例变量?
- python - Python - 如何将一个脚本的值赋予另一个脚本?
- amazon-web-services - 配置 AWS 实例以使用 IPv6
- apache-spark - 使用自定义模式时在 pyspark 数据框中设置列长度