Unity 回合制战斗系统(初级篇)

项目文件找出来了(后面中级/高级的),老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的。

需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成

项目包下载

————————————————————————

最近学习了Unity之后,结合各种网上的教材和资料后自己实现了一套简单的回合制战斗系统,如下

系统实现效果简介:

1. 目前为1V1的固定回合战斗

2. 玩家操作通过界面按钮输入,怪物操作为自动

3. 包含了简单的游戏状态控制(菜单状态、战斗状态、结束状态)

4. 单位攻击、受击、死亡时播放对应动画

装备工作:

1. 模型动画资源

下载自AssetStore,资源名:Animated Knight and Slime Monster(免费)

2. 场景添加玩家和怪物模型

为了方便,怪物和角色用了相同的模型和Animator,创建空物体用于挂载控制回合战斗的脚本

3. 为角色模型添加Animator

,添加待机、攻击和受击3个动画片段至Animator,设置待机动画为默认状态

创建从Any State到待机、攻击和死亡的状态转移,并添加trigger类型的Parameters,作为对应状态转移的条件,不勾选Has Exit Time

脚本:

添加到玩家对象的脚本

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

public class PlayerControl : MonoBehaviour {
    //主角属性
    public int hp = 100;
    public int attack = 10;
    public int defence = 2;

    //回合控制脚本
    private TurnControl turnScript;

    //动画组件  
    private Animator playerAnimator;

    //获取敌人脚本的引用 
    private EnemyControl enemyScript;

    void Start()
    {
        turnScript = GameObject.Find("TurnSystem").GetComponent<TurnControl>();
        playerAnimator = GetComponent<Animator>();
        
        enemyScript = GameObject.FindGameObjectWithTag("EnemyUnit").GetComponent<EnemyControl>();
    }

    void OnGUI()
    {
        //游戏状态是Game才会进行
        if (turnScript.currentState == TurnControl.GameState.Game)
        {
            //如果处于等待玩家输入状态,则显示操作窗口
            if (turnScript.isWaitForPlayer)
            {
                GUI.Window(1, new Rect(Screen.width / 2 + 200, Screen.height / 2, 100, 100), PlayerUnitAction, "选择技能");
            }
        } 
    }

    void PlayerUnitAction(int ID)
    {
        if (GUI.Button(new Rect(10, 20, 80, 30), "普通攻击"))
        {
            turnScript.isWaitForPlayer = false;
            playerAnimator.SetTrigger("attack");
            int damage = Mathf.Max(0, attack - enemyScript.defence);
            enemyScript.ReceiveDamage(damage);
            Debug.Log("主角使用了普通攻击");
            StartCoroutine("EnemyWait");
        }
        if (GUI.Button(new Rect(10, 60, 80, 30), "英勇打击"))
        {
            turnScript.isWaitForPlayer = false;
            playerAnimator.SetTrigger("attack");
            int damage = Mathf.Max(0, attack - enemyScript.defence);
            enemyScript.ReceiveDamage(damage);
            Debug.Log("主角使用了英勇打击");
            StartCoroutine("EnemyWait");
        }
    }

    //在切换到敌人操作前添加延迟
    IEnumerator EnemyWait()
    {
        yield return new WaitForSeconds(1);
        turnScript.isEnemyAction = true;
    }
    
    //承受伤害  
    public void ReceiveDamage(int damage)
    {
        hp -= damage;
        playerAnimator.SetTrigger("damage");
        if (hp <= 0)
        {
            playerAnimator.SetTrigger("dead");
        }
    }
}

怪物对象脚本

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

public class EnemyControl : MonoBehaviour {
    //怪物属性
    public int hp = 50;
    public int attack = 10;
    public int defence = 1;

    //回合控制脚本
    private TurnControl turnScript;

    //动画组件  
    private Animator enemyAnimator;

    //获取玩家脚本的引用 
    private PlayerControl playerScript;

    void Start()
    {
        turnScript = GameObject.Find("TurnSystem").GetComponent<TurnControl>();
        enemyAnimator = GetComponentInChildren<Animator>();

        playerScript = GameObject.FindGameObjectWithTag("PlayerUnit").GetComponent<PlayerControl>();
    }

    void Update()
    {
        //游戏状态是Game才会进行
        if (turnScript.currentState == TurnControl.GameState.Game)
        {
            if (turnScript.isEnemyAction)
            {
                Debug.Log("敌人使用了普通攻击");
                //播放攻击动画
                enemyAnimator.SetTrigger("attack");
                int damage = Mathf.Max(0, attack - playerScript.defence);
                playerScript.ReceiveDamage(damage);
                //延迟1s出现玩家操作UI
                StartCoroutine("PlayerUIWait");
                turnScript.isEnemyAction = false;
            }
        }
    }

    //在切换到玩家UI前延迟
    IEnumerator PlayerUIWait()
    {
        yield return new WaitForSeconds(1);
        turnScript.isWaitForPlayer = true;
    }

    //承受伤害  
    public void ReceiveDamage(int damage)
    {
        hp -= damage;
        enemyAnimator.SetTrigger("damage");
        if (hp <= 0)
        {
            enemyAnimator.SetTrigger("dead");
        }
    }

}


回合控制对象脚本

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

public class TurnControl : MonoBehaviour {

    //控制玩家操作及操作窗口是否出现
    public bool isWaitForPlayer = true;
    //控制怪物操作
    public bool isEnemyAction = false;

    //获取玩家及敌人脚本的引用 
    private PlayerControl playerScript;
    private EnemyControl enemyScript;

    //定义游戏状态枚举  
    public enum GameState
    {
        Menu,//游戏开始菜单  
        Game,//游戏中 
        Over//游戏结束
    }
    //游戏初始状态
    public GameState currentState = GameState.Menu;

    void Start()
    {
        //获取玩家及敌人脚本引用 
        playerScript = GameObject.FindGameObjectWithTag("PlayerUnit").GetComponent<PlayerControl>();
        enemyScript = GameObject.FindGameObjectWithTag("EnemyUnit").GetComponent<EnemyControl>();
    }
    
    void OnGUI()
    {
        if (currentState == GameState.Menu)
        {
            GUI.Window(0, new Rect(Screen.width / 2-100, Screen.height / 2-30, 200, 60), GameStartConfirm, "战斗开始确认");
        }
        else if (currentState == GameState.Over)
        {
            GUI.Window(2, new Rect(Screen.width / 2 - 100, Screen.height / 2 - 30, 200, 60), GameRestartConfirm, "战斗结束");
        }
    }



    void GameStartConfirm(int ID)
    {
        if (GUI.Button(new Rect(50, 30, 100, 20), "开始战斗"))
        {
            currentState = GameState.Game;
        }
    }

    void GameRestartConfirm(int ID)
    {
        if (GUI.Button(new Rect(50, 30, 100, 20), "重新开始"))
        {
            playerScript.hp = 100;
            enemyScript.hp = 50;
            isWaitForPlayer = true;
            isEnemyAction = false;
            currentState = GameState.Game;
        }
    }

    void Update()
    {
        if (currentState == GameState.Game)
        {
            //如果任意一方生命值为0,则游戏结束  
            if (playerScript.hp <= 0)
            {
                Debug.Log("战斗失败");
                currentState = GameState.Over;
            }
            if (enemyScript.hp <= 0)
            {
                Debug.Log("战斗胜利");
                currentState = GameState.Over;
            }
        }
        
    }

}


添加完脚本后即可测试这个战斗系统了~

  • 27
    点赞
  • 171
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Unity是一款流行的游戏开发引擎,可以用于创建各种类型的游戏,包括回合制战斗系统回合制战斗系统是一种常见的游戏战斗机制,玩家和敌人轮流进行行动。 在Unity中创建回合制战斗系统可以遵循以下步骤: 首先,需要创建表示玩家和敌人的角色。可以使用Unity的角色生成工具或自定义角色模型进行创建。每个角色都应该有相关的属性,如血量、攻击力和防御力等。 接下来,需要设计战斗场景。可以创建一个2D或3D的地图,并设置战斗场景的背景、障碍物和其他元素。这样可以让玩家和敌人在合适的环境中进行战斗。 然后,需要编写回合制战斗系统的逻辑。可以使用Unity提供的脚本编写工具,创建角色行动和战斗规则的逻辑。例如,当轮到玩家行动时,可以让玩家选择技能或道具进行攻击或治疗。而当轮到敌人时,可以设置敌人的行为模式,如随机攻击或使用特定技能。 在战斗过程中,可以显示角色的状态和动作。可以创建UI界面,显示每个角色的血量、能量和效果状态。还可以使用动画和特效来展示角色的攻击和受伤过程,增强游戏的沉浸感。 最后,需要对战斗系统进行测试和优化。可以通过与游戏好友或使用Unity的测试工具进行测试,确保战斗系统的平衡性和流畅性。如果发现问题,可以调整角色属性、战斗规则或优化代码,以获得更好的游戏体验。 总的来说,Unity提供了强大的工具和功能,可以方便地实现回合制战斗系统。通过合理的设计和编码,可以创建出令人满意的游戏战斗体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值