的教程:【《迷失島2》游戲框架開發(fā)01:實(shí)現(xiàn)場(chǎng)景轉(zhuǎn)換|教程】

搭建場(chǎng)景

使用下載好的素材搭建場(chǎng)景H1-H4和H2A、永久的場(chǎng)景,將場(chǎng)景都拖拽到面板,只加載和H1和場(chǎng)景,將H1作為激活場(chǎng)景,并給每個(gè)場(chǎng)景中的場(chǎng)景切換圖標(biāo)添加一個(gè)帶的空物體,只保留的場(chǎng)景中的相機(jī),其余的場(chǎng)景的相機(jī)都刪除,將相機(jī)的背景顏色設(shè)置為黑色,Size設(shè)置為5.4,Game面板的展示大小為1920*1080,這樣圖片就可以剛好完全展示在屏幕中。

腳本

實(shí)現(xiàn)邏輯:當(dāng)點(diǎn)擊對(duì)應(yīng)的圖標(biāo)的時(shí)候,檢測(cè)到其對(duì)應(yīng)的碰撞體,如果這個(gè)碰撞體的游戲?qū)ο蟮臉?biāo)簽為指定的類型標(biāo)簽則調(diào)用場(chǎng)景轉(zhuǎn)換的方法。由于每個(gè)場(chǎng)景中都存在場(chǎng)景轉(zhuǎn)換,所以場(chǎng)景轉(zhuǎn)換的類為單例,便于調(diào)用

創(chuàng)建腳本:.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;
    // 設(shè)置只讀屬性
    public static T Instance
    {
        get { return instance; }
    }
    private void Awake()
    {
        if (instance == null)
        {
            instance = (T)this;
        }
        else
        {
            Destroy(this);
        }
        DontDestroyOnLoad(this);
    }
    // 是否創(chuàng)建實(shí)例
    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
{
    // 將鼠標(biāo)點(diǎn)擊的屏幕坐標(biāo)轉(zhuǎn)換成世界坐標(biāo)
    private Vector2 mouseWorldPoint => Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
    // 如果鼠標(biāo)點(diǎn)擊了
    private bool isClick;
    private Collider2D coll;
    // Update is called once per frame
    void Update()
    {
        isClick = ObjectAtMouseClick();
        if (isClick && Input.GetMouseButton(0))
        {
            // 根據(jù)游戲?qū)ο蟮牟煌瑯?biāo)簽來判斷執(zhí)行什么操作
            coll = ObjectAtMouseClick();
            ClickAction(coll.gameObject);
        }
    }
    public void ClickAction(GameObject clickObject)
    {
        switch (coll.gameObject.tag)
        {
            case "Teleport":
                // 獲取對(duì)象上的Teleport組件,執(zhí)行場(chǎng)景切換方法
                Teleport t = clickObject.GetComponent<Teleport>();
                t?.TransitionScene();
                break;
            default:
                break;
        }
    }
    public Collider2D ObjectAtMouseClick()
    {
        return Physics2D.OverlapPoint(mouseWorldPoint);
    }
}

每個(gè)場(chǎng)景中的切換圖標(biāo)物體都添加腳本.cs ,F(xiàn)Ile—> 面板中點(diǎn)擊“Add Open ”將所有的場(chǎng)景都添加進(jìn)去

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SceneName
{
    H1,
    H2,
    H3,
    H4,
    H2A,
}
public class Teleport : MonoBehaviour
{
    // 現(xiàn)在處于的場(chǎng)景
    public SceneName from;
    // 要切換到的場(chǎng)景
    public SceneName to;
    public void TransitionScene()
    {
        // 場(chǎng)景切換
        TransitionManager.Instance.TransitionScene(from, to);
    }
}

場(chǎng)景切換

編輯腳本.cs,實(shí)現(xiàn)場(chǎng)景切換且未添加淡入淡出,未實(shí)現(xiàn)淡入淡出效果的時(shí)候的代碼:

.;

..;

;

.;

.UI;

:

// 啟動(dòng)協(xié)程
public void TransitionScene(SceneName from, SceneName to)
{
    // 如果實(shí)現(xiàn)切換場(chǎng)景淡入淡出效果則不能進(jìn)行場(chǎng)景切換
    StartCoroutine(SwitchScene(from, to));
}
/// 
/// 切換場(chǎng)景
/// 
/// 
/// 
/// 
public IEnumerator SwitchScene(SceneName from, SceneName to)
{
    // 屏蔽鼠標(biāo)操作
    anim.gameObject.GetComponent().raycastTarget = true;
    // 卸載當(dāng)前場(chǎng)景
    yield return AsyncOperation unloadScene = SceneManager.UnloadSceneAsync(from.ToString());
   
    // 加載要加載的場(chǎng)景
     yield return AsyncOperation loadScene = SceneManager.LoadSceneAsync(to.ToString(), LoadSceneMode.Additive);
    
    // 激活場(chǎng)景
    Scene newScene = SceneManager.GetSceneByName(to.ToString()); // 通過場(chǎng)景名稱來獲取場(chǎng)景
    SceneManager.SetActiveScene(newScene);
}

場(chǎng)景切換是正常的

但是加入淡入淡出相關(guān)函數(shù)的代碼(如下)之后,


public IEnumerator SwitchScene(SceneName from, SceneName to)
    {
        // 當(dāng)設(shè)置好場(chǎng)景后就加入Fade,1是全黑,0是透明
        yield return Fade(1);
        // 卸載當(dāng)前場(chǎng)景
        yield return SceneManager.UnloadSceneAsync(from.ToString());
        // 加載要加載的場(chǎng)景
        yield return SceneManager.LoadSceneAsync(to.ToString(), LoadSceneMode.Additive);
        // 激活場(chǎng)景
        // Scene newScene = SceneManager.GetSceneByName(to.ToString()); // 通過場(chǎng)景名稱來獲取場(chǎng)景
        Scene newScene = SceneManager.GetSceneByBuildIndex((int)to); // 通過場(chǎng)景在build setting中的序號(hào)來獲取場(chǎng)景,使用這個(gè)也會(huì)經(jīng)常報(bào)錯(cuò)
        if (newScene == null)
        {
            SceneManager.SetActiveScene(newScene);
        }
        // 恢復(fù)場(chǎng)景可見
        yield return Fade(0);
        // 鼠標(biāo)點(diǎn)擊有效
        cp.blocksRaycasts = false;
    }
    
    /// 
    /// 設(shè)置轉(zhuǎn)場(chǎng)時(shí)的遮罩顏色漸變
    /// 
    /// 
    private IEnumerator Fade(float alpha)
    {
        // 正在開始淡入特效
        isFade = true;
        // 屏蔽所有的鼠標(biāo)點(diǎn)擊
        cp.blocksRaycasts = true;
        // 計(jì)算淡入速度, 現(xiàn)在的alpha與目標(biāo)alpha的差值再除以持續(xù)時(shí)間得到Fade速度
        float speed = Mathf.Abs(cp.alpha - alpha) / fadeDuaration;
        while (Mathf.Approximately(cp.alpha, alpha))
        {
            // 線性差值來實(shí)現(xiàn)Fade
            cp.alpha = Mathf.Lerp(cp.alpha, alpha, speed * Time.deltaTime);
            yield return null;
        }
        // 淡出后就重新設(shè)置isFade
        isFade = false;
    }
   

出現(xiàn)報(bào)錯(cuò):: to is

具體是這句代碼“ .(from.());”中的所獲取到的無效

查閱網(wǎng)上找到信息:

使用.的時(shí)候,設(shè)置了要注意使用它以后的特點(diǎn):使用它之后

是永遠(yuǎn)不會(huì)有返回的,意味著程序會(huì)卡在這句話上,而且如果有多個(gè)在排隊(duì)進(jìn)行,注意在進(jìn)行中的如果沒有結(jié)束下一個(gè)不會(huì)開始,使用的時(shí)候,如果當(dāng)前只有一個(gè)激活的場(chǎng)景,另一個(gè)場(chǎng)景因?yàn)樵O(shè)置為等還沒加載完畢,那不會(huì)正常執(zhí)行并且會(huì)返回空,

此外如果某個(gè)一直進(jìn)度為0,則它前面一般是有個(gè)沒有執(zhí)行完的,使用要特別注意特點(diǎn),相關(guān)詳見

API搜索,和

仔細(xì)看它們的說明和使用示例。 ———————————————— 版權(quán)聲明:本文為CSDN博主「」的原創(chuàng)文章,遵循CC