大家好,又见面了,我是你们的朋友全栈君。
推荐阅读
一、前言
游戏灵感来自于“火柴人亨利(Henry Stickmin)”系列游戏,以及一些上世纪80年代的《惊险岔路口》冒险丛书。游戏根据玩家的不同选择来展开故事情节,通常会拥有多重结局。
效果图
二、示例工程下载
https://download.csdn.net/download/q764424567/12472942
三、程序设计
3-1、基本程序设计(故事卡)
游戏会为玩家呈现一个“故事卡”。故事卡上包含一些文字,其中一部分是用于描述玩家当前的状态,另外一部分是在当前情况下玩家可以做出的一系列选择。
根据玩家的不同选择,剧情也会按照不同的分支向前发展,并持续出现新的卡片与选择,直到最终的卡片不再有新的选择,则游戏结束。
制作一张“故事卡”很简单。根据上诉需求,我们新建StoryItemBase脚本,脚本代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StoryItemBase : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public virtual void Activate(GameManager gm)
{
}
}
我们新建StoryCard脚本,脚本代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StoryCard : StoryItemBase
{
public string Description;
public string[] Options;
public StoryItemBase[] Items;
public StoryState[] StatesToSetTrue;
public StoryState[] StatesToSetFalse;
public override void Activate(GameManager gm)
{
gm.SetCardDetails(Description, Options, Items);
UpdateStates();
}
private void UpdateStates()
{
if (StatesToSetTrue != null)
{
foreach (StoryState s in StatesToSetTrue)
s.Value = true;
}
if (StatesToSetFalse != null)
{
foreach (StoryState s in StatesToSetFalse)
s.Value = false;
}
}
}
StoryCard在检视面板中显示如下:
您需要在StoryCard脚本:
Description:输入卡片描述(玩家可以在屏幕上看到的文本)
Options:玩家在选项按钮上看到的文字(目前该程序最多支持4个按钮)
Items:以及按下对应按钮后跳转的故事卡(即为分支,稍后会介绍)
StoryCard脚本还包含两个故事状态属性“States to Set True”以及“States to Set False”,这两个属性分别有何作用呢?下面就来看看。
3-2、故事状态与分支
其实整个系统可以完全使用“故事卡”来制作,但仅使用“故事卡”的话,游戏流程就变得很枯燥无味。
假设有某个选项,玩家点击了该按钮,但该选项所导致的后果并不会立即在剧情中呈现,而是在随后的剧情中缓慢展开。
假使仅使用“故事卡”,就需要立即从该选项开始出现分支,并且直至该选项导致的最终影响出现之前,都要在所有剧情分支上重复同样的步骤。
因此,我们需要一个更好的解决办法。
前面提出了“故事状态”的概念用于存储状态值,这其实只是一个布尔值容器。
卡片在被激活时可以根据需要对特定的状态进行赋值。新建StoryState脚本,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StoryState : MonoBehaviour
{
public bool Value;
}
StoryState脚本在检视面板中显示如下图:
该方法解决了记住状态值的问题,下面通过“剧情分支(Story Branch)”来应用这些状态值。
一个分支会引用一个状态以及剧情发展的两个不同方向(可以是“故事卡”或者剧情分支),被引用的状态值用于决定剧情走向何种结果。
3-3、游戏管理器
这个管理器用于承载整个剧情的发展,其作用是将目前的“故事卡”状态更新到UI上,在不同按钮按下时做出对应的动作,并引导剧情前进。
这个管理器也需要一个“故事卡”来作为故事的开端。以下是GameManager脚本的内容:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class GameManager : MonoBehaviour
{
public Text Description;
public Button[] OptionButtons;
public StoryItemBase CurrentItem;
private int _numButtons;
private Text[] _buttonTexts;
private string[] _optionTexts;
private StoryItemBase[] _optionItems;
// Use this for initialization
void Start()
{
_numButtons = OptionButtons.GetLength(0);
GetButtonTexts();
CurrentItem.Activate(this);
}
// Update is called once per frame
void Update()
{
}
private void GetButtonTexts()
{
_buttonTexts = new Text[_numButtons];
for (int i = 0; i < _numButtons; i++)
{
_buttonTexts[i] =
OptionButtons[i].GetComponentInChildren<Text>(true);
}
}
public void SetCurrentStoryItem(StoryItemBase item)
{
CurrentItem = item;
CurrentItem.Activate(this);
}
public void OnButton(int index)
{
SetCurrentStoryItem(_optionItems[index]);
}
public void SetCardDetails(string desc, string[] optionTexts,
StoryItemBase[] optionItems)
{
Description.text = desc;
_optionTexts = optionTexts;
_optionItems = optionItems;
UpdateButtons();
}
public void UpdateButtons()
{
int numOptionTexts = _optionTexts == null ? 0 :
_optionTexts.GetLength(0);
int numOptionItems = _optionItems == null ? 0 :
_optionItems.GetLength(0);
int numActiveButtons = Math.Min(numOptionItems, numOptionTexts);
for (int i = 0; i < _numButtons; i++)
{
if (i < numActiveButtons)
{
OptionButtons[i].gameObject.SetActive(true);
_buttonTexts[i].text = _optionTexts[i];
}
else
{
OptionButtons[i].gameObject.SetActive(false);
}
}
}
}
其中SetCurrentStoryItem函数用于设置当前显示的剧情节点。
SetCardDetails函数用于设置“故事卡”的细节,例如剧情描述,选项按钮及描述等。
UpdateButtons函数用于更新所有选项按钮及其响应事件。
GameManager脚本在检视面板中显示如下图:
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141326.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...