游戏开发常见操作梳理之NPC任务系统

多数游戏存在任务系统,接下来介绍通过NPC触发任务的游戏制作代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 一个用于控制任务管理者NPC的脚本
/// </summary>
public class BarNPC : NPC
{
    public static BarNPC _instance;
    //对于动画的控制
    public TweenPosition questTween;

    //表示是否在任务之中
    public bool isInTask=false;
    //表示任务进度
    public int killCount = 0;

    //对于接受按钮的点击
    public UIButton btnAccept;
    //对于取消按钮的点击
    public UIButton btnCancel;
    //对于确定按钮的点击
    public UIButton btnOk;
    //对于关闭按钮的点击
    public UIButton btnClose;

    //关联面板上面的文字
    public UILabel desLabel;

    //关联外来脚本
    private PlayerStatus status;

    //关联任务面板
    public GameObject TaskPanel;
    public UILabel taskProgress;
    public UILabel taskNotFinished;
    public UILabel taskFinished;
    //private TweenAlpha tween;
    //public UISprite task1;


    private void Awake()
    {
        _instance= this;
       // tween = task1.GetComponent<TweenAlpha>();
    }
    //初始化这些按钮的点击
    void Start()
    {
        //关联脚本
        status=GameObject.FindGameObjectWithTag(Tags.player).GetComponent<PlayerStatus>();

        //对于接受按钮的点击
        btnAccept.onClick.Add(new EventDelegate(() =>
        {
            ShowTaskProgress();
            //表示在任务中
            isInTask= true;
            TaskPanel.SetActive(true);
            taskProgress.text = "任务进度(" + killCount + "//10)";
            taskNotFinished.gameObject.SetActive(true);
            taskFinished.gameObject.SetActive(false);

        }));
        //对于取消按钮的点击
        btnCancel.onClick.Add(new EventDelegate(() =>
        {
            //取消后隐藏
            HideQuest();
        }));
        //对于确定按钮的点击
        btnOk.onClick.Add(new EventDelegate(() =>
        {
            //完成任务
            if(killCount>=10)
            {
                //获取金币,清空任务量计算
                Inventory._instance.AddCoin(1000);
                killCount = 0;
                ShowTaskDes();
               // TaskPanel.SetActive(false);
            }
            //没有完成任务
            else
            {
                HideQuest();
            }
        }));
        //对于关闭按钮的点击
        btnClose.onClick.Add(new EventDelegate(() =>
        {
            //隐藏面板
            HideQuest();
        }));
    }
    private void Update()
    {
        taskProgress.text = "任务进度(" + killCount + "//10)";
        if (killCount >= 10)
        {
            taskNotFinished.gameObject.SetActive(false);
            taskFinished.gameObject.SetActive(true);
        }


    }
    void ShowTaskDes()
    {
        //更新任务
        desLabel.text = "任务:\n杀死10只小野狼\n\n奖励:\n1000金币";
        //隐藏OK按钮
        btnOk.gameObject.SetActive(false);
        //显示自己和取消按钮
        btnAccept.gameObject.SetActive(true);
        btnCancel.gameObject.SetActive(true);
       
    }
    void ShowTaskProgress()
    {
        //更新任务
        desLabel.text = "任务:\n你已经杀死了" + killCount + "\\10只小野狼\n\n奖励:\n1000金币";
        //显示OK按钮
        btnOk.gameObject.SetActive(true);
        //隐藏自己和取消按钮
        btnAccept.gameObject.SetActive(false);
        btnCancel.gameObject.SetActive(false);
    }
    private void OnMouseOver()
    {
        //当鼠标位于这个collider之上的时候
        //点击NPC的时候
        if(Input.GetMouseButtonDown(0)&&UICamera.isOverUI == false)
        {
            GetComponent<AudioSource>().Play();
            if(isInTask)
            {
                ShowTaskProgress();
            }
            else
            {
                ShowTaskDes();
            }
            ShowQuest();
        }
    }

    void ShowQuest()
    {
        questTween.gameObject.SetActive(true);
        //正向播放
        questTween.PlayForward();
    }
    void HideQuest()
    {
        //倒向播放
        questTween.PlayReverse();
    }
    //任务系统 点击对话框上面的按钮 进行的一些处理

    public void OnKillWolf()
    {
        if(isInTask)
        {
            killCount++;
        }
    }
}

为了暗示玩家点击NPC对话,我们通常还会制作不同的鼠标指针提示玩家。鼠标指针的提示管理逻辑:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CursorManager : MonoBehaviour
{
    public static CursorManager _instance;
    public Texture2D cursor_normal;
    public Texture2D cursor_npc_talk;
    public Texture2D cursor_attack;
    public Texture2D cursor_lockTarget;
    public Texture2D cursor_pick;

    private Vector2 hotspot=Vector2.zero;
    private CursorMode mode = CursorMode.Auto;
    // Start is called before the first frame update
    void Start()
    {
        _instance= this;
    }
    public void SetNormal()
    {
        Cursor.SetCursor(cursor_normal,hotspot,mode);
    }
    public void SetNpcTalk()
    {
        Cursor.SetCursor(cursor_npc_talk,hotspot,mode);
    }
    public void SetAttack()
    {
        Cursor.SetCursor(cursor_attack,hotspot,mode);
    }
    public void SetLockTarget()
    {
        Cursor.SetCursor(cursor_lockTarget,hotspot,mode);
    }

}

由于一个游戏中不止一个NPC,所以我们通常还要制作一个NPC 的管理类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NPC : MonoBehaviour
{
    //进入
    private void OnMouseEnter()
    {
        if(UICamera.isOverUI == false)
           CursorManager._instance.SetNpcTalk();
    }
    //移出
    private void OnMouseExit()
    {
        if (UICamera.isOverUI == false)
            CursorManager._instance.SetNormal();
    }
}

将任务面板显示在玩家左边,使其更加清晰地提醒玩家,相关逻辑:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TaskPanel : MonoBehaviour
{
    //关联隐藏按钮
    public UIButton btnHide;
    //关联呼出按钮
    public UIButton btnShow;
    //关联动画
    private TweenAlpha tweentitle;
    private TweenAlpha tweentask;
    public UISprite Title;
    public UISprite task;
    private void Awake()
    {
        tweentitle = Title.GetComponent<TweenAlpha>();
        tweentask = task.GetComponent<TweenAlpha>();
    }

    private void Start()
    {
        btnHide.onClick.Add(new EventDelegate(() =>
        {
            tweentask.PlayReverse();
            tweentitle.PlayReverse();
            btnShow.gameObject.SetActive(true);
            btnHide.gameObject.SetActive(false);
        }));
        btnShow.onClick.Add(new EventDelegate(() =>
        {
            tweentask.PlayForward();
            tweentitle.PlayForward();
            btnHide.gameObject.SetActive(true);
            btnShow.gameObject.SetActive(false);
        }));
    }
}

以上就是任务系统的完整逻辑了,适合于有一定基础的小伙伴,没有基础的小伙伴只需要正确拼接应该有的UI以及NPC即可,有一些逻辑可能关联了其它的系统,你可以自行选择删除,如果有疑问的点欢迎大家来向我提问,我很高兴为大家解答。以上代码还有优化空间,但是简单的核心逻辑已经全部写出了,希望对你有一定的帮助,喜欢就点个赞支持一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nicole Potter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值