unity实现梦日记式传送组件

前言

在梦日记及派生中,能从一个世界中通过某些长得门,或是长得像门,或是根本不像门的东西传送到另一个世界。今天我们就来实现它。

方法

首先,要实现传送组件,就先需要两个世界,然后,你就可以实现它。

另一个世界的构建,可以用这些组件来完成*(这比你抄来说更方便)*,之后,你就可以传送了。

你要传送,就得有一个能传送的东西,以门来举例,我们先给门添加上wall组件,之后,我们给门添上一个用来传送的组件,这里叫door组件,door组件是门组件,相当于传送组件。

那么,如何来实现door组件呢?首先,先给door组件定义一些基本参数,像是朝向,坐标,传送的世界,及传送时玩家的xy坐标等。(也可以添加一些水把门淹了())

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor.SceneManagement;
using UnityEditor.SearchService;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class door : MonoBehaviour
{
    public map m;
    public move you;
    public wall w;
    public move.wasd front;
    public bool haveFront = true;
    public Image image;
    public float waitTime = 0.5f;
    public string worldName = "nexus";
    public int teleX = 0;
    public int teleY = 0;
    private IEnumerator go()
    {

    }

    void Start()
    {

    }

    void Update()
    {
        
    }
}

之后,我们要想传送,得先看符不符合传送的条件:如按下z键,走到门前*(除,因为它可以传送到地狱)*。符合的话就执行关于传送的操作:先执行动画,再播放转场动画,最后传送。

执行动画,只需要一个Animation组件与脚本配合。

播放转场动画,最简单的是黑屏,所以我们就将那个屏的不透明度进行上升,简单。

传送的话,这里需要在move组件里定义静态的传送坐标,及静态的传送朝向,完成后就能穿过层层门,将一个玩家从地狱跳到天堂。

如果你发现黑屏没法消失,说明游戏中你没眼睛,这就需要一个show组件,作用是将那个屏的不透明度进行下降,所以也叫白屏组件。

csharp 复制代码
//door.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor.SceneManagement;
using UnityEditor.SearchService;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class door : MonoBehaviour
{
    public map m;
    public move you;
    public wall w;
    public move.wasd front;
    public bool haveFront = true;
    public Image image;
    public float waitTime = 0.5f;
    public string worldName = "nexus";
    public int teleX = 0;
    public int teleY = 0;
    private IEnumerator go()
    {
        if (GetComponent<Animation>() != null)
        {
            GetComponent<Animation>().Play();
        }
        yield return new WaitForSeconds(waitTime);
        for (int i = 0; i < 50; i++)
        {
            image.color += new Color(0, 0, 0, 0.02f);
            yield return 5;
        }
        SceneManager.LoadScene(worldName);
        move.teleX = teleX;
        move.teleY = teleY;
        move.front = front;
        move.isTele = true;
    }

    void Start()
    {
        if ("" == worldName)
        {
            worldName = "nexus";
        }
        if (move.wasd.n == front)
        {
            haveFront = false;
            front = move.wasd.s;
        }
    }

    void Update()
    {
        if ((you.x + 1) % m.x == w.x && you.y == w.y && move.front == move.wasd.d && (!haveFront || move.wasd.a == front) && Input.GetKeyDown("z"))
        {
            //交互后动作
            StartCoroutine(go());
        }
        else if ((you.x - 1 < 0 ? m.x - 1 : you.x - 1) == w.x && you.y == w.y && move.front == move.wasd.a && (!haveFront || move.wasd.d == front) && Input.GetKeyDown("z"))
        {
            //交互后动作
            StartCoroutine(go());
        }
        if (you.x == w.x && (you.y + 1) % m.y == w.y && move.front == move.wasd.s && (!haveFront || move.wasd.w == front) && Input.GetKeyDown("z"))
        {
            //交互后动作
            StartCoroutine(go());
        }
        if (you.x == w.x && (you.y - 1 < 0 ? m.y - 1 : you.y - 1) == w.y && move.front == move.wasd.w && (!haveFront || move.wasd.s == front) && Input.GetKeyDown("z"))
        {
            //交互后动作
            StartCoroutine(go());
        }
    }
}
// ----------------
//move.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class move : MonoBehaviour
{
    public enum wasd
    {
        w,
        a,
        s,
        d,
        n
    };
    private bool isEnd = true;
    public static float waitTime = 0.01f;
    public int x = 5;
    public int y = 5;
    public static wasd front;
    public map m;
    private float high = 5;
    public static bool isTele = false;
    public static int teleX = 0;
    public static int teleY = 0;
    public static float speed = 1;
    wasd getwasd()
    {
        if (Input.GetKey("w"))
        {
            front = wasd.w;
        }
        else if (Input.GetKey("a"))
        {
            front = wasd.a;
        }
        else if (Input.GetKey("s"))
        {
            front = wasd.s;
        }
        else if(Input.GetKey("d"))
        {
            front = wasd.d;
        }
        if (Input.GetKey("w") && (m.verticalIsCycle ? (' ' == m.wmap[x, y - 1 >= 0 ? y - 1 : m.y - 1]) : (0 != y && ' ' == m.wmap[x, y - 1])))
        {
            m.wmap[x, y--] = ' ';
            if (y < 0)
            {
                transform.position = new Vector3(transform.position.x, high, m.minY - m.widthY / m.y / 2.0f);
                y = m.y - 1;
            }
            m.wmap[x, y] = 'I';
            return wasd.w;
        }
        else if (Input.GetKey("a") && (m.horizontalIsCycle ? (' ' == m.wmap[x - 1 >= 0 ? x - 1 : m.x - 1, y]) : (0 != x && ' ' == m.wmap[x - 1, y])))
        {
            m.wmap[x--, y] = ' ';
            if (x < 0)
            {
                transform.position = new Vector3(m.maxX + m.heightX / m.x / 2.0f, high, transform.position.z);
                x = m.x - 1;
            }
            m.wmap[x, y] = 'I';
            return wasd.a;
        }
        else if (Input.GetKey("s") && (m.verticalIsCycle ? (' ' == m.wmap[x, (y + 1) % m.y]):(y != m.y - 1 && ' ' == m.wmap[x, y + 1])))
        {
            m.wmap[x, y++] = ' ';
            if (y >= m.y)
            {
                transform.position = new Vector3(transform.position.x, high, m.maxY + m.widthY / m.y / 2.0f);
            }
            y %= m.y;
            m.wmap[x, y] = 'I';
            return wasd.s;
        }
        else if (Input.GetKey("d") && (m.horizontalIsCycle ? (' ' == m.wmap[(x + 1) % m.x, y]) : (x != m.x - 1 && ' ' == m.wmap[x + 1, y])))
        {
            m.wmap[x++, y] = ' ';
            if (x >= m.x)
            {
                transform.position = new Vector3(m.minX - m.heightX / m.x / 2.0f, high, transform.position.z);
            }
            x %= m.x;
            m.wmap[x, y] = 'I';
            return wasd.d;
        }
        else 
        {
            return wasd.n;
        }
    }

    IEnumerator pmove()
    {
        //初始
        isEnd = false;
        wasd i = getwasd();
        for (int j = 0; j < 20; j++)
        {
            switch (i)//移动
            {
                case wasd.w:
                    front = wasd.w;
                    transform.position += new Vector3(0, 0, m.widthY / m.y / 20.0f);
                    yield return new WaitForSeconds(0.2f / speed / 20.0f);
                    break;
                case wasd.a:
                    front = wasd.a;
                    transform.position += new Vector3(-m.heightX / m.x / 20.0f, 0, 0);
                    yield return new WaitForSeconds(0.2f / speed / 20.0f);
                    break;
                case wasd.s:
                    front = wasd.s;
                    transform.position += new Vector3(0, 0, -m.widthY / m.y / 20.0f);
                    yield return new WaitForSeconds(0.2f / speed / 20.0f);
                    break;
                case wasd.d:
                    front = wasd.d;
                    transform.position += new Vector3(m.heightX / m.x / 20.0f, 0, 0);
                    yield return new WaitForSeconds(0.2f / speed / 20.0f);//移动间隔时间
                    break;
                default://wasd.n时无
                    goto nowait;
            }
        }
        yield return new WaitForSeconds(waitTime);//移动等待时间
    nowait:
        isEnd = true;
        yield return null;
    }

    void Start()
    {
        //根据地图z轴进行高度计算
        high = transform.position.y;
        //根据地图xy轴进行位置计算
        transform.position = new Vector3(m.minX + m.heightX / m.x * (0.5f + x), high, m.maxY - m.widthY / m.y * (0.5f + y));
    }

    void Update()
    {
        if (isTele)
        {
            x = teleX; 
            y = teleY;
            transform.position = new Vector3(m.minX + m.heightX / m.x * (0.5f + x), high, m.maxY - m.widthY / m.y * (0.5f + y));
            isTele = false;
        }
        m.wmap[x, y] = 'I';
        if (isEnd)
        {
            StartCoroutine(pmove());
        }
    }
}

好了,将新组件用到世界中,开始玩吧,你也可以创世界。

后言

在梦日记及相关派生中,会有各种各样的效果,这些效果如自行车,眼珠手,红绿灯等。能让你获得各种增益,下篇博客就来实现它。

示例代码

相关推荐
kfaino32 分钟前
码农的AI翻身(六)你好,我叫 Parameter
后端·aigc
掘金者阿豪35 分钟前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
猪猪拆迁队2 小时前
虚拟工厂仿真引擎的架构设计:让一条产线可编程、可观测、可干预
后端·ai编程
字节跳动数据库2 小时前
文章分享——相似函数处理方法
人工智能·后端·程序员
云技纵横2 小时前
@Transactional 失效的 7 种场景:第 5 种最难排查
后端
用户6757049885022 小时前
你知道 Go 结构体和结构体指针调用的区别吗?一文带你彻底搞懂!
后端·go
程序员cxuan3 小时前
读懂 Claude Code 架构分析系列,第一篇,开始!
人工智能·后端·架构
用户6757049885023 小时前
面试官问“装饰器模式”,这样回答薪资多要 3000!
后端
tntxia3 小时前
Geo Scene域名修改引起的一些问题
后端
用户298698530143 小时前
Java 实现 Word 文档加密与权限解除
java·后端