码迷,mamicode.com
首页 > 编程语言 > 详细

[Unity实战]剧情对话

时间:2015-04-11 11:51:57      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:剧情

在网上看到了一篇不错的文章,讲的是游戏中的剧情动画,感觉去做一做也是挺好玩的事,于是就有了这篇文章。游戏中的剧情(非CG动画)主要有两种,一种是自动播放的,另一种是含有对话的。可以把剧情中的一个个动画(这里的动画不仅仅包含角色动画,还包含位移,旋转,时间等待等等)当成一种种状态(有点像状态机),放到一个链表或者队列中,每当一个状态完成时便跳到下一个状态,于是就会形成连环的剧情动画了。


要注意的是,在普通状态下,一个动作完成会跳到下一个动作,但是在对话状态下,一个动作完成时不会自动跳到下一个动作,而是每出现一个新的对话,就会触发动作。


在这里给出核心代码(一个动作基类以及一个管理动作的类):

using UnityEngine;
using System.Collections;

public class Command {

    public virtual void Execute() { }
    public void Next() 
    {
        CommandManager.instance.Next2();
    } 
}

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

public class CommandManager : MonoBehaviour {

    public static CommandManager instance;

    private List<Command> commands = new List<Command>();
    private int nowIndex = 0;
    public bool isDialogueMode = false;

    //缓存Transform
    [SerializeField]
    public List<string> startObj = new List<string>();//一开始就存在的物体
    public Dictionary<string,Transform> allObj = new Dictionary<string,Transform>();

    void Awake()
    {
        instance = this;
    }

    void Start()
    {
        for (int i = 0; i < startObj.Capacity;i++ )
            allObj.Add(startObj[i], GameObject.Find(startObj[i]).transform);

        commands.Add(new CommandMusic("Taylor Swift - Red"));

        //场景一 对话驱动画面
        commands.Add(new CommandDialogueModeEnter());

        commands.Add(new CommandDialogue("Story1", 0, 0, 1));
        commands.Add(new CommandMove("Main Camera", new Vector3(-3.5f, 3.4f, -5.5f), 6f));

        commands.Add(new CommandDialogue("Story1", 1, 1, 2));
        commands.Add(new CommandMove("Main Camera", new Vector3(-4.8f, 3.4f, -4.8f), 0f));
        commands.Add(new CommandMove("Main Camera", new Vector3(-2.5f, 3.4f, -4.8f), 5f));

        commands.Add(new CommandDialogue("Story1", 2, 2, 3));
        commands.Add(new CommandRotate("Main Camera", new Vector3(10f, 180f, 0f), 0f));
        commands.Add(new CommandMove("Main Camera", new Vector3(-2.5f, 3.4f, -1f), 0f));
        commands.Add(new CommandMove("Main Camera", new Vector3(-4.6f, 3.4f, -1f), 5f));

        commands.Add(new CommandDialogueModeExit());

        //场景二 自动
        commands.Add(new CommandMove("Main Camera", new Vector3(-20.5f, 5.8f, -7.9f), 0f));
        commands.Add(new CommandRotate("Main Camera", new Vector3(12f, 180f, 0f), 0f));

        commands.Add(new CommandWait(2f));
        commands.Add(new CommandPlayAnim("skeleton_warrior1", AnimatorManager.instance.run));
        commands.Add(new CommandPlayAnim("skeleton_warrior2", AnimatorManager.instance.run));
        commands.Add(new CommandPlayAnim("skeleton_warrior3", AnimatorManager.instance.run));
        commands.Add(new CommandPlayAnim("skeleton_warrior4", AnimatorManager.instance.run));
        commands.Add(new CommandPlayAnim("skeleton_warrior5", AnimatorManager.instance.run));

        commands.Add(new CommandWait(2f));
        commands.Add(new CommandPlayAnim("magic", AnimatorManager.instance.attack1));

        commands.Add(new CommandWait(1f));
        commands.Add(new CommandPlayAnim("skeleton_warrior1", AnimatorManager.instance.dead));
        commands.Add(new CommandPlayAnim("skeleton_warrior2", AnimatorManager.instance.dead));
        commands.Add(new CommandPlayAnim("skeleton_warrior3", AnimatorManager.instance.dead));
        commands.Add(new CommandPlayAnim("skeleton_warrior4", AnimatorManager.instance.dead));
        commands.Add(new CommandPlayAnim("skeleton_warrior5", AnimatorManager.instance.dead));

        commands.Add(new CommandPlayAnim("magic", AnimatorManager.instance.stand));

        commands.Add(new CommandDialogue("Story1", 3, 5, 0));

        commands.Add(new CommandWait(1f));
    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
            commands[nowIndex].Execute();
    }

    //对话模式下直接进入下一状态
    public void Next()
    {
        nowIndex++;
        if (nowIndex < commands.Count)
            commands[nowIndex].Execute();
    }

    //自动模式下直接进入下一状态
    public void Next2()
    {
        if (isDialogueMode)
            return;
        else
            Next();
    }
}

只需要根据自身的需要,写一些继承Command的类即可达到想要的效果了。以下是本人自己扩展的类:

技术分享


效果图:

技术分享

技术分享

技术分享

技术分享


完整视频链接:http://v.youku.com/v_show/id_XOTMxMjIyMDU2.html

大约两分钟,建议全屏模式下播放(因为不太清晰),自认为剧情还是挺好的。。。

一个更好的方法是写一个编辑器类,将配置保存下来(保存在xml或者json文件),每次运行时读取。不过这里先放一放,最近好忙啊(因为课程的关系,大二下比之前都要忙啊),也不知道下一次写博客是什么时候!哎!

[Unity实战]剧情对话

标签:剧情

原文地址:http://blog.csdn.net/lyh916/article/details/44992805

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!