# 依靠Unity实现的一款小游戏
# 游戏效果 牧师与恶魔 (bilibili.com)
# 源码链接 someoneLikeC/PriestsAndDevils at master (github.com)
游戏介绍
游戏名称:牧师与恶魔
游戏规则介绍:有三个牧师正在押送三个恶魔,现在他们到了一条河前,河面上有一艘船,船上只能承载两个人。我们要控制牧师将恶魔押送过河。值得注意的是:当河的一岸牧师的数量少于恶魔时,恶魔将杀死牧师,押送任务就失败了,船只能由牧师来掌控(即船上一定要有一个牧师才能开),恶魔十分讲义气,即使只有一个恶魔在河的对岸,魔鬼也不会逃跑。聪明的你需要想办法帮助牧师成功完成此次押送任务。
游戏制作
1. 游戏对象的创建
1. 创建对象:
在红框区域鼠标右键点击,选择立方体
创建完成后,在检查器中调整他的位置与大小。
将方块重命名为River
2. 给对象加颜色
在红框处点击鼠标右键
在创建中选择材质,命名为riverColor
在检查器中点击箭头所指位置,在取色框内选择自己喜欢的颜色
将材质通过点击鼠标左键不松手拖动到River上即可
3. 创建对象预制体(就是提前制作好的东西,需要的时候可以直接用)
将River拖到箭头所指的位置即可
完成后将场景中的River删除
4. 按照前三个不走制作出三个牧师、三个恶魔、一个河岸、一艘船。
河岸参数:
形状:Cube
名称:Bank
缩放参数:X:10; Y:1; Z:2
牧师参数(不同牧师只是颜色不同):
形状:Cube
名称:Priest_i(i = 1,2,3)
缩放参数:X:0.5; Y:1; Z:0.5
恶魔参数(不同恶魔只是颜色不同):
形状:Sphere
名称:Devil_i(i = 1,2,3)
缩放参数:X:0.5; Y:1; Z:0.5
船参数:
形状:Cube
名称:Boat
缩放参数:X:0.5; Y:0.25; Z:1.5
完成后我们将拥有这些东西
嫌乱可以按照以下步骤建立文件夹进行管理
在红框的空白处点击鼠标右键
选择创建文件夹,我们一个创建三个文件夹,一个名为Prefabs,用于存放我们的预制体;一个叫Materials,用于存放我们创建的材质;一个名为Scripts,用于存放我们之后的代码。
这是完成后的样子
2. 代码编写
点击进入Scripts文件夹中
在红框处点击鼠标右键
选择创建C#脚本,并命名为GameManager
双击GameManager进入代码编写,将下述代码复制到GameManager中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject[] gameObjects = new GameObject[9];
public int leftBankPriestCount = 3;
public int rightBankPriestCount = 0;
public int leftBankDevilCount = 3;
public int rightBankDevilCount = 0;
public int peopleOnBoat = 0;
public bool moving = false;
public bool isRight = false;
private bool win = false;
private bool firstSeatFull = false;
private bool lastSeatFull = false;
private int priestCount = 0;
private int devilCount = 0;
private GameObject river;
private GameObject[] bank = new GameObject[2];
private GameObject[] priest = new GameObject[3];
private GameObject[] devil = new GameObject[3];
private GameObject boat;
// Start is called before the first frame update
void Start()
{
Init();
}
void Update()
{
if (moving)
{
if (!isRight)
{
boat.transform.position += new Vector3(0, 0, 1 * Time.deltaTime);
}
else
{
boat.transform.position += new Vector3(0, 0, -1 * Time.deltaTime);
}
}
if (boat.transform.position.z < -2.25 || boat.transform.position.z > 2.25)
{
moving = false;
if (isRight)
{
boat.transform.position = new Vector3(0, 0.5f, -2.25f);
}
else
{
boat.transform.position = new Vector3(0, 0.5f, 2.25f);
}
isRight = !isRight;
}
}
private void OnGUI()
{
GUI.Box(new Rect(30, 25, 80, 220), "");
if (GUI.Button(new Rect(35, 30, 70, 30), "重启")) Init();
GUI.Box(new Rect(35, 65, 30, 140), "P");
GUI.Box(new Rect(75, 65, 30, 140), "D");
if (!gameOver())
{
if (GUI.Button(new Rect(35, 85, 30, 30), "1")) movePeople(priest[0]);
if (GUI.Button(new Rect(35, 125, 30, 30), "2")) movePeople(priest[1]);
if (GUI.Button(new Rect(35, 165, 30, 30), "3")) movePeople(priest[2]);
if (GUI.Button(new Rect(75, 85, 30, 30), "1")) movePeople(devil[0]);
if (GUI.Button(new Rect(75, 125, 30, 30), "2")) movePeople(devil[1]);
if (GUI.Button(new Rect(75, 165, 30, 30), "3")) movePeople(devil[2]);
if (GUI.Button(new Rect(35, 210, 70, 30), "开船")) boatMov();
}
else
{
if (win)
{
GUI.Box(new Rect(320, 150, 50, 50), "你赢了");
}
else
{
GUI.Box(new Rect(320, 150, 50, 50), "你输了");
}
}
}
void Init()
{
// 初始化变量
leftBankPriestCount = 3;
rightBankPriestCount = 0;
leftBankDevilCount = 3;
rightBankDevilCount = 0;
peopleOnBoat = 0;
moving = false;
isRight = false;
priestCount = 0;
devilCount = 0;
firstSeatFull = false;
lastSeatFull = false;
win = false;
// 重启时消除原先生成的游戏对象
GameObject[] obj = FindObjectsOfType(typeof(GameObject)) as GameObject[];
foreach (GameObject child in obj)
{
if (child.name == "River(Clone)" || child.name == "Bank(Clone)" || child.name == "Boat(Clone)"
|| child.name == "Priest_1(Clone)" || child.name == "Devil_1(Clone)"
|| child.name == "Priest_2(Clone)" || child.name == "Devil_2(Clone)"
|| child.name == "Priest_3(Clone)" || child.name == "Devil_3(Clone)")
{
Destroy(child);
}
}
// 生成游戏对象
river = Instantiate(gameObjects[1], Vector3.zero, transform.rotation);
boat = Instantiate(gameObjects[2], new Vector3(0, 0.5f, -2.25f), transform.rotation);
bank = new GameObject[2];
priest = new GameObject[3];
devil = new GameObject[3];
for (int i = 0; i < 2; i++)
{
bank[i] = Instantiate(gameObjects[0], new Vector3(0, 0, 3.0f * (i - 0.5f) * 2), transform.rotation);
}
for (int i = 0; i < 3; i++)
{
devil[i] = Instantiate(gameObjects[3 + i], new Vector3(2 + i, 0.5f, -3.5f), transform.rotation);
devil[i].GetComponent<settings>().onBoat = false;
devil[i].GetComponent<settings>().isRight = false;
}
for (int i = 0; i < 3; i++)
{
priest[i] = Instantiate(gameObjects[6 + i], new Vector3(-4 + i, 0.5f, -3.5f), transform.rotation);
priest[i].GetComponent<settings>().onBoat = false;
priest[i].GetComponent<settings>().isRight = false;
}
}
void movePeople(GameObject gameObject)
{
if (!moving)
{
if (!gameObject.GetComponent<settings>().onBoat)
{
if (gameObject.GetComponent<settings>().isRight == isRight)
{
if (peopleOnBoat == 0)
{
gameObject.transform.position = boat.transform.position + new Vector3(0, 0, 0.3f);
gameObject.transform.parent = boat.transform;
peopleOnBoat++;
firstSeatFull = true;
gameObject.GetComponent<settings>().onBoat = true;
if (gameObject.name == "Priest_1(Clone)" || gameObject.name == "Priest_2(Clone)"
|| gameObject.name == "Priest_3(Clone)")
{
priestCount++;
}
else
{
devilCount++;
}
}
else if (peopleOnBoat == 1)
{
if (firstSeatFull)
{
gameObject.transform.position = boat.transform.position + new Vector3(0, 0, -0.3f);
lastSeatFull = true;
}
else if (lastSeatFull)
{
gameObject.transform.position = boat.transform.position + new Vector3(0, 0, 0.3f);
firstSeatFull = true;
}
gameObject.transform.parent = boat.transform;
peopleOnBoat++;
gameObject.GetComponent<settings>().onBoat = true;
if (gameObject.name == "Priest_1(Clone)" || gameObject.name == "Priest_2(Clone)"
|| gameObject.name == "Priest_3(Clone)")
{
priestCount++;
}
else
{
devilCount++;
}
}
else return;
}
}
else
{
if(gameObject.transform.position == boat.transform.position + new Vector3(0, 0, 0.3f))
{
firstSeatFull = false;
}
else
{
lastSeatFull = false;
}
if (isRight)
{
if(gameObject.name == "Priest_1(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-4, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if(gameObject.name == "Priest_2(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-3, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if(gameObject.name == "Priest_3(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-2, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if(gameObject.name == "Devil_1(Clone)")
{
devilCount--;
gameObject.transform.position = new Vector3(2, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if(gameObject.name == "Devil_2(Clone)")
{
devilCount--;
gameObject.transform.position = new Vector3(3, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else
{
devilCount--;
gameObject.transform.position = new Vector3(4, 0.5f, 3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
}
else
{
if (gameObject.name == "Priest_1(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-4, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if (gameObject.name == "Priest_2(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-3, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if (gameObject.name == "Priest_3(Clone)")
{
priestCount--;
gameObject.transform.position = new Vector3(-2, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if (gameObject.name == "Devil_1(Clone)")
{
devilCount--;
gameObject.transform.position = new Vector3(2, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else if (gameObject.name == "Devil_2(Clone)")
{
devilCount--;
gameObject.transform.position = new Vector3(3, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
else
{
devilCount--;
gameObject.transform.position = new Vector3(4, 0.5f, -3.5f);
gameObject.GetComponent<settings>().onBoat = false;
}
}
gameObject.GetComponent<settings>().isRight = isRight;
peopleOnBoat--;
gameObject.transform.parent = null;
}
}
}
void boatMov()
{
if (priestCount >= 1)
{
moving = true;
if (!isRight)
{
leftBankDevilCount = 3 - devilCount - rightBankDevilCount;
leftBankPriestCount = 3 - priestCount - rightBankPriestCount;
}
else
{
rightBankDevilCount = 3 - devilCount - leftBankDevilCount;
rightBankPriestCount = 3 - priestCount - leftBankPriestCount;
}
}
else
{
return;
}
}
bool gameOver()
{
if ((leftBankDevilCount > leftBankPriestCount && leftBankPriestCount != 0)
|| (rightBankDevilCount > rightBankPriestCount && rightBankPriestCount != 0))
{
win = false;
return true;
}
else if (rightBankPriestCount + priestCount == 3 && rightBankDevilCount + devilCount == 3)
{
win = true;
return true;
}
else return false;
}
}
按照上诉步骤再新建一个脚本命名为settings,将下述代码复制到settings中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class settings : MonoBehaviour
{
public bool onBoat;
public bool isRight;
}
完成后进入Prefabs文件夹
依次选择恶魔于牧师,点击添加组件
为他们添加Settings组件
3. 游戏运行
在红框处点击鼠标右键
选择创建空对象,命名为GameManager
点击小箭头值向的GameManager游戏对象,用鼠标将GameManager脚本拖到指定位置
按照图中顺序添加元素
为了由更好的视觉效果,我们调整一下相机的参数
点击主相机,将相机位置改为X: 0; Y: 10; Z: 0; 旋转改为X轴旋转90度,投影方式改为正交,大小调节为4
点击这个播放键就可以玩游戏了