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());
        }
    }
}

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

后言

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

示例代码

相关推荐
枯萎穿心攻击9 分钟前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
Eiceblue2 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
tan180°2 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
优创学社23 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
why技术3 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理3 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
ai小鬼头4 小时前
AIStarter如何助力用户与创作者?Stable Diffusion一键管理教程!
后端·架构·github
简佐义的博客5 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
Code blocks5 小时前
使用Jenkins完成springboot项目快速更新
java·运维·spring boot·后端·jenkins