我正在尝试构建一个简单的飞行游戏。我有两个场景 - 一个用于生成GameManager和SceneController实例的管理场景,以及一个载入玩家可以飞过一些红门的游戏场景。
一旦加载了游戏场景,我就会添加一些门。但是,在层次结构中,这些场景下的门不显示 - 它们出现在管理场景下。预制件确实出现在游戏场景中。我希望所有这些都能在游戏场景中出现。
两个问题:
SceneController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneController : MonoBehaviour {
// This is a singleton
private static SceneController _instance;
public static SceneController Instance { get { return _instance; } }
private void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(this.gameObject);
} else {
_instance = this;
}
}
// Scene names
private string sceneNameGameScene = "GameScene";
// Use this for initialization
void Start () {
SceneManager.sceneLoaded += OnSceneLoaded;
StartCoroutine(LoadSceneAdditive(sceneNameGameScene, LoadSceneMode.Additive));
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode) {
if (scene.name == sceneNameGameScene) {
SceneManager.SetActiveScene(scene);
Debug.Log("OnSceneLoaded Active Scene : " + SceneManager.GetActiveScene().name);
SetupGameScene();
}
}
IEnumerator LoadSceneAdditive(string sceneName, LoadSceneMode loadSceneMode){
AsyncOperation _async = new AsyncOperation();
_async = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
while (!_async.isDone) {
yield return null;
}
Scene nextScene = SceneManager.GetSceneByName( name );
if (nextScene.IsValid ()) {
SceneManager.SetActiveScene (nextScene);
}
}
private void SetupGameScene() {
// Create a game map
GameMap gameMap = new GameMap();
gameMap.Setup(this.transform);
}
}
GameMap代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameMap {
private GameObject gatePrefab = GameObject.Instantiate(Resources.Load("GatePrefab")) as GameObject;
private Transform transform;
public GameMap() {}
public void Setup (Transform parentTransform) {
transform = parentTransform;
Vector3 position;
Quaternion rotation;
position = new Vector3(0, 0, 0);
rotation = Quaternion.identity;
CreateGate(position, rotation, 10.0f, 2.0f, "Gate 1");
position = new Vector3(0, 0, 20);
rotation = Quaternion.identity * Quaternion.Euler(0, 45, 0);
CreateGate(position, rotation, 10.0f, 1.0f, "Gate 2");
position = new Vector3(20, 0, 20);
rotation = Quaternion.identity * Quaternion.Euler(0, 90, 0);
CreateGate(position, rotation, 8.0f, 1.0f, "Gate 3");
CreateGround();
}
private void CreateGate(Vector3 position, Quaternion rotation, float lengthOfSide, float thickness, string name) {
// Create the gates, and call the "Initialize" method to populate properties as Unity doesn't have constructors.
GameObject clone = GameObject.Instantiate(gatePrefab, position, rotation, transform) as GameObject;
clone.name = name;
clone.GetComponent<Gate>().Initialize(lengthOfSide, thickness);
}
private void CreateGround() {
Debug.Log("OnSceneLoaded Active Scene : " + SceneManager.GetActiveScene().name);
GameObject ground = GameObject.CreatePrimitive(PrimitiveType.Plane);
ground.name = "Ground";
ground.transform.parent = transform;
ground.transform.localPosition = new Vector3(0, -10, 0);
ground.transform.localRotation = Quaternion.identity;
ground.transform.localScale = new Vector3(50, 1, 50);
ground.GetComponent<Renderer>().material.color = Color.grey;
}
}
门码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gate : MonoBehaviour {
float lengthOfSide;
float thickness;
public void Initialize (float lengthOfSide, float thickness) {
this.lengthOfSide = lengthOfSide;
this.thickness = thickness;
}
// Use this for initialization
void Start () {
SetupRigidBody();
Setup3dEntities();
}
void SetupRigidBody() {
Rigidbody rb = this.gameObject.AddComponent<Rigidbody>();
rb.detectCollisions = true;
rb.mass = 1000;
rb.useGravity = false;
}
// Create the physical gate
void Setup3dEntities() {
Vector3 position;
Vector3 scale;
float lengthOfVeritcalSegment = lengthOfSide - (2 * thickness);
float yPosHorizontalSegment = (lengthOfSide - thickness) / 2;
float xPosVerticalSegment = lengthOfSide - thickness;
// Bottom
position = new Vector3(0, -yPosHorizontalSegment, 0);
scale = new Vector3(lengthOfSide, thickness, thickness);
CreatePrimitiveCube(position, scale);
// Top
position = new Vector3(0, yPosHorizontalSegment, 0);
scale = new Vector3(lengthOfSide, thickness, thickness);
CreatePrimitiveCube(position, scale);
// Left
position = new Vector3(xPosVerticalSegment/2, 0, 0);
scale = new Vector3(thickness, lengthOfVeritcalSegment, thickness);
CreatePrimitiveCube(position, scale);
// Right
position = new Vector3(-xPosVerticalSegment/2, 0, 0);
scale = new Vector3(thickness, lengthOfVeritcalSegment, thickness);
CreatePrimitiveCube(position, scale);
}
void CreatePrimitiveCube(Vector3 position, Vector3 scale) {
// Create a primitive cube. Note that we want to set the position and rotation to match the parent!
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.parent = gameObject.transform;
cube.transform.localPosition = position;
cube.transform.localRotation = Quaternion.identity;
cube.transform.localScale = scale;
// TODO: Make a better color/material mechanism!
cube.GetComponent<Renderer>().material.color = Color.red;
// Debug.Log("Cube.parent: " + cube.transform.parent.gameObject.name);
// Debug.Log("Cube.localScale: " + cube.transform.localScale);
}
}
截图 - 笔记层次结构很奇怪:
答案 0 :(得分:2)
您的SceneController将其变换传递给GameMap Setup方法。 (我假设SceneController转换是“app”对象?)
GameMap Setup方法然后创建门并使用给定的parentTransform 作为每个门的父级(因为它是GameObject.Instantiate方法中的passend)
所以我觉得Gate对象是管理场景中“app”对象的孩子是否有意义?
如果你想让他们在另一个场景中,那么你必须传递一个不同的父母或没有父母。
答案 1 :(得分:0)
所以,据我所知,你想要一个管理场景,你可以用脚本来管理游戏。
我的想法是你不要使用LoadSceneAdditive
而是使用DontDestroyOnLoad。这将使您的脚本仍然加载,即使您加载另一个场景。这也将使游戏对象在当前加载的场景中产生。
因此,您只需使用LoadSceneMode.Single
代替LoadSceneMode.Additive
另一种选择是使用SceneManager.SetActiveScene来更改要设置为&#34;父级场景&#34;或者想要在其上产生游戏对象的场景。