的教程:【《迷失岛2》游戏框架开发01:实现场景转换|教程】

搭建场景

使用下载好的素材搭建场景H1-H4和H2A、永久的场景,将场景都拖拽到面板,只加载和H1和场景,将H1作为激活场景,并给每个场景中的场景切换图标添加一个带的空物体,只保留的场景中的相机,其余的场景的相机都删除,将相机的背景颜色设置为黑色,Size设置为5.4,Game面板的展示大小为1920*1080,这样图片就可以刚好完全展示在屏幕中。

脚本

实现逻辑:当点击对应的图标的时候,检测到其对应的碰撞体,如果这个碰撞体的游戏对象的标签为指定的类型标签则调用场景转换的方法。由于每个场景中都存在场景转换,所以场景转换的类为单例,便于调用

创建脚本:.cs、.cs、.cs、.cs。

// SingleTon.cs 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : Singleton<T> // 类型约束,类T必须继承Singleton
{
    // 单例
    protected static T instance;
    // 设置只读属性
    public static T Instance
    {
        get { return instance; }
    }
    private void Awake()
    {
        if (instance == null)
        {
            instance = (T)this;
        }
        else
        {
            Destroy(this);
        }
        DontDestroyOnLoad(this);
    }
    // 是否创建实例
    private bool IsInitial()
    {
        return instance != null;
    }
    // 销毁单例
    protected void OnDestroy()
    {
        if (instance == this)
        {
            instance = null;
        }
    }
}

CursorManager.cs脚本编辑:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CursorManager : MonoBehaviour
{
    // 将鼠标点击的屏幕坐标转换成世界坐标
    private Vector2 mouseWorldPoint => Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
    // 如果鼠标点击了
    private bool isClick;
    private Collider2D coll;
    // Update is called once per frame
    void Update()
    {
        isClick = ObjectAtMouseClick();
        if (isClick && Input.GetMouseButton(0))
        {
            // 根据游戏对象的不同标签来判断执行什么操作
            coll = ObjectAtMouseClick();
            ClickAction(coll.gameObject);
        }
    }
    public void ClickAction(GameObject clickObject)
    {
        switch (coll.gameObject.tag)
        {
            case "Teleport":
                // 获取对象上的Teleport组件,执行场景切换方法
                Teleport t = clickObject.GetComponent<Teleport>();
                t?.TransitionScene();
                break;
            default:
                break;
        }
    }
    public Collider2D ObjectAtMouseClick()
    {
        return Physics2D.OverlapPoint(mouseWorldPoint);
    }
}

每个场景中的切换图标物体都添加脚本.cs ,FIle—> 面板中点击“Add Open ”将所有的场景都添加进去

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SceneName
{
    H1,
    H2,
    H3,
    H4,
    H2A,
}
public class Teleport : MonoBehaviour
{
    // 现在处于的场景
    public SceneName from;
    // 要切换到的场景
    public SceneName to;
    public void TransitionScene()
    {
        // 场景切换
        TransitionManager.Instance.TransitionScene(from, to);
    }
}

场景切换

编辑脚本.cs,实现场景切换且未添加淡入淡出,未实现淡入淡出效果的时候的代码:

.;

..;

;

.;

.UI;

:

// 启动协程
public void TransitionScene(SceneName from, SceneName to)
{
    // 如果实现切换场景淡入淡出效果则不能进行场景切换
    StartCoroutine(SwitchScene(from, to));
}
/// 
/// 切换场景
/// 
/// 
/// 
/// 
public IEnumerator SwitchScene(SceneName from, SceneName to)
{
    // 屏蔽鼠标操作
    anim.gameObject.GetComponent().raycastTarget = true;
    // 卸载当前场景
    yield return AsyncOperation unloadScene = SceneManager.UnloadSceneAsync(from.ToString());
   
    // 加载要加载的场景
     yield return AsyncOperation loadScene = SceneManager.LoadSceneAsync(to.ToString(), LoadSceneMode.Additive);
    
    // 激活场景
    Scene newScene = SceneManager.GetSceneByName(to.ToString()); // 通过场景名称来获取场景
    SceneManager.SetActiveScene(newScene);
}

场景切换是正常的

但是加入淡入淡出相关函数的代码(如下)之后,


public IEnumerator SwitchScene(SceneName from, SceneName to)
    {
        // 当设置好场景后就加入Fade,1是全黑,0是透明
        yield return Fade(1);
        // 卸载当前场景
        yield return SceneManager.UnloadSceneAsync(from.ToString());
        // 加载要加载的场景
        yield return SceneManager.LoadSceneAsync(to.ToString(), LoadSceneMode.Additive);
        // 激活场景
        // Scene newScene = SceneManager.GetSceneByName(to.ToString()); // 通过场景名称来获取场景
        Scene newScene = SceneManager.GetSceneByBuildIndex((int)to); // 通过场景在build setting中的序号来获取场景,使用这个也会经常报错
        if (newScene == null)
        {
            SceneManager.SetActiveScene(newScene);
        }
        // 恢复场景可见
        yield return Fade(0);
        // 鼠标点击有效
        cp.blocksRaycasts = false;
    }
    
    /// 
    /// 设置转场时的遮罩颜色渐变
    /// 
    /// 
    private IEnumerator Fade(float alpha)
    {
        // 正在开始淡入特效
        isFade = true;
        // 屏蔽所有的鼠标点击
        cp.blocksRaycasts = true;
        // 计算淡入速度, 现在的alpha与目标alpha的差值再除以持续时间得到Fade速度
        float speed = Mathf.Abs(cp.alpha - alpha) / fadeDuaration;
        while (Mathf.Approximately(cp.alpha, alpha))
        {
            // 线性差值来实现Fade
            cp.alpha = Mathf.Lerp(cp.alpha, alpha, speed * Time.deltaTime);
            yield return null;
        }
        // 淡出后就重新设置isFade
        isFade = false;
    }
   

出现报错:: to is

具体是这句代码“ .(from.());”中的所获取到的无效

查阅网上找到信息:

使用.的时候,设置了要注意使用它以后的特点:使用它之后

是永远不会有返回的,意味着程序会卡在这句话上,而且如果有多个在排队进行,注意在进行中的如果没有结束下一个不会开始,使用的时候,如果当前只有一个激活的场景,另一个场景因为设置为等还没加载完毕,那不会正常执行并且会返回空,

此外如果某个一直进度为0,则它前面一般是有个没有执行完的,使用要特别注意特点,相关详见

API搜索,和

仔细看它们的说明和使用示例。 ———————————————— 版权声明:本文为CSDN博主「」的原创文章,遵循CC