前言
在梦日记及派生中,能从一个世界中通过某些长得门,或是长得像门,或是根本不像门的东西传送到另一个世界。今天我们就来实现它。
方法
首先,要实现传送组件,就先需要两个世界,然后,你就可以实现它。
另一个世界的构建,可以用这些组件来完成*(这比你抄来说更方便)*,之后,你就可以传送了。
你要传送,就得有一个能传送的东西,以门来举例,我们先给门添加上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());
}
}
}
好了,将新组件用到世界中,开始玩吧,你也可以创世界。

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