RPG游戏《黑暗之光》流程介绍与代码分析之(四):任务系统的实现

第四章:任务系统


这部分主要对任务系统进行设计,游戏的关键因素之一就是任务系统与玩家的交互,但在代码实现中并不算复杂。本篇博客主要通过一下几个方面实现任务系统。
  1. 任务模型的导入与任务UI界面的创建
  2. 任务的接受与完成
  3. 针对不同对象的指针修改(提高可玩性)

4.1 任务NPC模型的导入、任务UI界面的设计

首先添加接受任务信息的老爷爷, 在Model中找到NPC老爷爷,拖入场景Map中,并调整朝向。因为NPC不参与具体战斗,不需要精确点击,因此创建一个Box Collider,使其包围住老爷爷即可。

之后要设计任务对话框,在UI Root界面中导入Atlas,在Sprite中添加游戏任务背景,将背景图片导入。之后对这个背景添加一个tween——>position,修改红框处,其中from 1000~169表示一个运动方向,即对话框从视线之外运动进来,下面的曲线表示运动速度。


4.2 任务的接受与完成

任务界面应包括如下几个方面
  1. 点击NPC时,出现任务描述
  2. 接受任务后,出现任务提示
  3. 完成任务后,提交获取奖励

4.2.1 点击NPC后,应出现提示信息

在任务面板中添加一个Label实现该功能,设计如下

为了在点击任务面板时不移动,给UI控件attach一个box collider,在PlayerDirection中加入判断,即在鼠标点击后判断鼠标是否碰到UI控件,如果碰到,则不移动。
if (Input.GetMouseButtonDown (0) && UICamera.hoveredObject == null)
即可实现。

为了实现点击老爷爷显示界面的效果,我们给NPC老爷爷新建一个脚本BarNPC,代码如下
using UnityEngine;
using System.Collections;
public class BarNPC : MonoBehaviour {
    public TweenPosition questTween;
    void OnMouseOver()    //当鼠标发出射线发生碰撞
    {
        if (Input.GetMouseButtonDown(0))    //此时点下鼠标
        {
            ShowQuest();
        }
    }
    void ShowQuest()
    {
        questTween.gameObject.SetActive (true);    //将quest激活
        questTween.PlayForward ();    //显示动画
    }
}
即可
为了实现点击“X”按钮隐藏并播放动画,我们对X按钮进行代码设计
    public void CloseQuest()
    {
        HideQuest ();
    }
    void HideQuest()
    {
        questTween.PlayReverse ();    //与PlayForward相反,实现关闭的动画效果
    }
即可

4.2.2 点击Accept后,出现任务提示

在点击Accept之后,Accept和Cancel按钮应当消失,并且任务描述应当改为任务更新。并出现OK按钮用于在完成任务时提交任务。
接下来这段BarNPC中的代码表示接受任务到完成任务这一系列的所有操作
using UnityEngine;
using System.Collections;
public class BarNPC : MonoBehaviour {
    public TweenPosition questTween;
    public bool isOnTask = false;    //是否处于任务状态的标志位
    public int killWolfNumber = 0;    //当前杀死的狼    
    public int wolfKilledAcquire = 10;    //需要杀死狼的个数
    public UILabel describeLabel;    //控制任务描述与进度显示
    public GameObject AcceptBtnGO;    //控制三个按钮
    public GameObject OKBtnGO;
    public GameObject CancelBtnGO;

    void OnMouseOver()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if(isOnTask)    //如果处在任务状态,即按下Accept,显示任务进度
            {
                ShowTaskProgress();
            }
            else    //否则显示任务描述
            {
                ShowTaskDes();
            }
            ShowQuest();
        }
    }
    void ShowQuest()    //任务界面的动画效果
    {
        questTween.gameObject.SetActive (true);
        questTween.PlayForward ();
    }
    void HideQuest()
    {
        questTween.PlayReverse ();
    }
    void ShowTaskDes()    //任务描述
    {
        describeLabel.text = "任务:\n杀死" + wolfKilledAcquire+"只小野狼\n\n奖励:\n1000金币";
        AcceptBtnGO.gameObject.SetActive (true);
        OKBtnGO.gameObject.SetActive (false);
    }
    void ShowTaskProgress()    //任务进度
    {
        describeLabel.text = "任务:\n你已经杀死了" + killWolfNumber + "/"+wolfKilledAcquire+"只小野狼\n\n奖励:\n1000金币";
        AcceptBtnGO.gameObject.SetActive (false);
        OKBtnGO.gameObject.SetActive (true);
    }
    public void OnCloseQuest()    //点击关闭按钮
    {
        HideQuest ();
    }
    public void OnAcceptQuest()    //点击接受按钮
    {
        isOnTask = true;
        ShowTaskProgress ();
    }
}
如下图所示

4.2.3 完成任务后,获取任务奖励并更新任务描述

如果任务完成,点击OK按钮可以提交任务,获得奖励,并把Label显示为新的任务描述

接下来要实现任务奖励的获取和任务更新,首先需要在Magician的PlayerStatus的脚本中添加一段函数,用以控制金币变化
    public void GetCoin(int coinNumber)
    {
        coin += coinNumber;
    }
之后需要在BarNPC中调用这个函数
    private PlayerStatus state;
    void Start()    //在Start中找到对应的脚本
    {
        state = GameObject.FindGameObjectWithTag (Tags.player).GetComponent<PlayerStatus> ();
    }
并在OK的按钮功能中加入
public void OnOKQuest()
    {
        if (killWolfNumber >= wolfKilledAcquire)    //若完成目标,即杀死的狼数量大于等于任务目标
        {
            state.GetCoin(1000);    //调用GetCoin()增加金币
            killWolfNumber = 0;    //进度归零
            ShowTaskDes();    //显示新的任务描述
        }
        else
        {
            HideQuest();    //若没完成,隐藏界面
        }
    }

4.3 点击不同对象出现不同指针

为了让玩家在点击不同对象时出现不同的鼠标,作为提示。我们将所有用到的鼠标指针(RPG——>GUI——>mouse cursor)存到一个类中。脚本编辑为
using UnityEngine;
using System.Collections;
public class MouseSetting : MonoBehaviour {
    public static MouseSetting _instance;    //一个单例,到时候通过单例调用不同指( ps:单例是用来取代以前的全局函数变量)
相比全局函数,单例不会重名,应用域明确,可以管理生命周期,可封装,可以通过继承扩展(重要!)
    public Texture2D cursor_normal;    //所有功能的鼠标指针外观
    public Texture2D cursor_npcTalk;
    public Texture2D cursor_attack;
    public Texture2D cursor_pick;
    public Texture2D cursor_lockTarget;
    public Vector2 hotspot = Vector2.zero;
    public CursorMode mode = CursorMode.Auto;
    void Start()
    {
        _instance = this;
    }
    public void SetNormalCursor()
    {
        Cursor.SetCursor (cursor_normal, hotspot, mode);
    }
    public void SetNPCTalkCursor()
    {
        Cursor.SetCursor (cursor_npcTalk, hotspot, mode);
    }
}
为了让每个NPC都能适用于鼠标变换,我们在Script——NPC中新建一个CommonNPC脚本表示对所有NPC都适用的操作,添加
using UnityEngine;
using System.Collections;
public class NPC : MonoBehaviour {
    void OnMouseEnter()    //碰撞到GUI控件时调用一次,不同于OnMouseOver的每帧调用
    {
        MouseSetting._instance.SetNPCTalkCursor ();
    }
    void OnMouseExit()
    {
        MouseSetting._instance.SetNormalCursor ();
    }
}
即可,再将public class BarNPC :MonoBehaviour改为public class BarNPC : CommmonNPC ,即BarNPC中的所有NPC能继承CommonNPC脚本中的数据。


总结:任务系统是游戏的重要组成部分,但从代码实现来说,难度并不大。之后会陆续更新面板、道具、装备、系统设置等信息。



猜你喜欢

转载自blog.csdn.net/s1314_jhc/article/details/79659642
今日推荐