【问题标题】:Unity3D - Keep Clouds PositionsUnity3D - 保持云的位置
【发布时间】:2015-10-14 04:33:44
【问题描述】:

我在谷歌上搜索了好几个小时,试图在重新加载场景时保持云的位置,但仍然没有运气。

您能指出我在代码中的错误吗?

using UnityEngine;
using System.Collections;

public class MenuScript : MonoBehaviour {

 public Transform[] clouds;
 public float speed = 0.2f;

 void Update () {
     for(int i = 0; i < instance.clouds.Length; i++){
         if(instance.clouds[i].position.x >= 10f){
             instance.clouds[i].position = new Vector3(-10f, instance.clouds[i].position.y, 0);
         }
         Vector3 vec = instance.clouds[i].position;
         vec.x += speed * Time.deltaTime;
         instance.clouds[i].position = vec;
     }
 }

 static MenuScript instance;

 void Awake(){
     if(instance == null){
         instance = this;
         DontDestroyOnLoad(gameObject);
     }else{
         Destroy(gameObject);
     }
 }
}

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    使用 PlayerPrefs 替换 DontDestroyOnLoad:

    PlayerPrefs.SetFloat("x", 10.0f);
    

    要取回值,请使用

    PlayerPrefs.GetFloat("x");
    

    PlayerPrefs 存储和访问游戏会话之间的玩家偏好。

    • 在 Mac OS X 上,PlayerPrefs 存储在 ~/Library/Preferences 文件夹中名为 unity.[company name].[product name].plist 的文件中,其中公司和产品名称是在项目设置。相同的 .plist 文件用于在编辑器中运行的项目和独立播放器。

    • 在 Windows 上,PlayerPrefs 存储在注册表中 HKCU\Software[company name][product name] 键下,其中公司和产品名称是在项目设置中设置的名称。

    • 在 Linux 上,可以使用项目设置中指定的公司和产品名称再次在 ~/.config/unity3d/[CompanyName]/[ProductName] 中找到 PlayerPrefs。

    • 在 Windows 应用商店应用中,可以在 %userprofile%\AppData\Local\Packages[ProductPackageId]>\LocalState\playerprefs.dat 中找到播放器首选项

    【讨论】:

    • 这是一个不错的选择,但我想了解 DontDestroyOnLoad 的工作原理。谢谢!
    • 使用 DontDestroyOnLoad 不是一个好习惯,这在别处已经讨论过了。
    • 为什么使用DontDestroyOnLoad 不再是一个好习惯了?
    • 你可以搜索谷歌看看为什么。例如,使用 DontDestroy... 可以强制场景之间的紧密耦合。
    • 好主意,伙计。谢谢
    【解决方案2】:

    这可能取决于填充云阵列的方式。 MenuScript 类可能不会被销毁,但个别云可能会被销毁并重新加载。

    如果只需要保存云的位置,您可以创建一个数组来存储 MenuScript 上每个云的位置,以确保保存这些值。

    【讨论】:

    • 场景中已经有 5 朵云。我只是将它们填充到 MenuScript 类中。我该如何做到这一点,这样云阵列也不会被破坏?谢谢。
    • 编辑了答案以显示如何将每个设置为在加载时不破坏。
    • 这是我得到的结果:The object of type 'Transform' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
    • 老实说,如果我在这种情况下为您编写和测试代码,我觉得您不会了解它是如何工作的,并且可能会给您带来更多问题。我建议查看发生错误的行,并尝试思考为什么此时仍无法加载它。
    • 最好将云类附加到每个云上,这会告诉云移动。然后,您可以将它们设置为不从那里破坏。当然,您必须有办法确保在重新加载场景时它们不会产生第二组,因此它可能不适用于您正在做的事情。
    【解决方案3】:

    终于找到了解决这个问题的办法:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class MenuScript : MonoBehaviour {
    
    public Transform[] clouds;
    public float speed = 0.2f;
    
    public static List<Vector3> cloudsPositions;
    
    void Start(){
        if(cloudsPositions == null){
            cloudsPositions = new List<Vector3>();
            for(int i = 0; i < clouds.Length; i++){
                cloudsPositions.Add(clouds[i].transform.position);
            }
        }else{
            for(int i = 0; i < clouds.Length; i++){
                clouds[i].position = cloudsPositions[i];
            }
        }
    }
    
    public void UpdateCloudsPositions(){
        cloudsPositions.Clear();
        for(int i = 0; i < clouds.Length; i++){
            cloudsPositions.Add(clouds[i].transform.position);
        }
    }
    
    void Update () {
        for(int i = 0; i < clouds.Length; i++){
            if(clouds[i].position.x >= 10f){
                clouds[i].position = new Vector3(-10f, clouds[i].position.y, 0);
            }
            Vector3 vec = clouds[i].position;
            vec.x += speed * Time.deltaTime;
            clouds[i].position = vec;
        }
    }
    }
    

    我所做的是将云的 position 存储到静态列表中,因此当重新加载场景时,脚本将更新它们在 Start 函数上的位置。

    感谢所有帮助过我的人:)

    【讨论】:

      猜你喜欢
      • 2022-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      相关资源
      最近更新 更多