Unity通过协程实现回合制战斗

Unity通过协程实现回合制战斗(一、1v1部分) - 技术专栏 - Unity官方开发者社区本文详细地阐述了如何实现回合制战斗,从配置文件到战斗数据,最后再通过协程实现战斗 - Unity技术专栏是中国Unity官方为开发者准备的中文技术分享社区,极简高效的markdown文本编辑器体验更适合Unity开发者日常记录开发经验和灵感,通过输出倒逼输入,加快自身学习成长速度;每一位开发者都可以通过技术分享与社区中的伙伴们交流学习,一起成为更优秀的创作者。https://developer.unity.cn/projects/61ca5b53edbc2a4c844ae7bcUnity通过协程实现回合制战斗(二、1v多/多v多部分) - 技术专栏 - Unity官方开发者社区本文详细地阐述了如何通过协程实现多人VS多人的回合制战斗 - Unity技术专栏是中国Unity官方为开发者准备的中文技术分享社区,极简高效的markdown文本编辑器体验更适合Unity开发者日常记录开发经验和灵感,通过输出倒逼输入,加快自身学习成长速度;每一位开发者都可以通过技术分享与社区中的伙伴们交流学习,一起成为更优秀的创作者。https://developer.unity.cn/projects/61cd42bfedbc2a244ffc81e6
Unity通过协程实现回合制战斗(三、多样化角色属性及技能类型设计) - 技术专栏 - Unity官方开发者社区本文阐述了如何使得回合制战斗多样性,以及探讨了回合制游戏的技能设计 - Unity技术专栏是中国Unity官方为开发者准备的中文技术分享社区,极简高效的markdown文本编辑器体验更适合Unity开发者日常记录开发经验和灵感,通过输出倒逼输入,加快自身学习成长速度;每一位开发者都可以通过技术分享与社区中的伙伴们交流学习,一起成为更优秀的创作者。https://developer.unity.cn/projects/61ee2fd2edbc2a0c23822dfa

回合制自己写的 战斗DEMO 加动画状态 Q键移动并攻击。 代码很简单。不要抱有太大希望 。作为新手学习使用。 public enum HeroStatus { idle = 0, //空闲 attack, //攻击 other, //其他 hit, //受击 die, //死亡 defense, //防御 cast, //施法 miss, //闪避 seriousInjury, //重伤 move, //移动 exit, //获取下一个状态 MAX, } public class hero : MonoBehaviour { public UISpriteAnimation m_spriteAnimation = null; public HeroStatus m_staus = HeroStatus.exit; //身体碰撞盒 public BoxCollider m_bodyBC = null; public string m_name = ""; public AttackCrash m_attackCrash = null; public byte m_posIndex = 0; void Awake() { m_spriteAnimation = transform.GetComponent(); m_bodyBC = transform.GetComponent(); } // Use this for initialization void Start () { m_spriteAnimation.AddFrameCallBack("attack", 1, AttackCallBack); m_spriteAnimation.AddFrameCallBack("attack", 4, AttackCallBack); m_spriteAnimation.AddFrameCallBack("attack", 7, AttackCallBack); } public float m_speed = 1f; public float m_offset = 0.5f; public Vector3 m_destination = Vector3.zero; public List m_actionList = new List(); // Update is called once per frame void Update () { switch (m_staus) { case HeroStatus.idle: //空闲状态 if (m_actionList.Count > 0) m_staus = HeroStatus.exit; break; case HeroStatus.attack: if (!m_spriteAnimation.isPlaying) { //攻击动画播放完毕 m_staus = HeroStatus.exit; } break; case HeroStatus.defense: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.hit: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.die: break; case HeroStatus.cast: break; case HeroStatus.miss: break; case HeroStatus.seriousInjury: break; case HeroStatus.move: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.exit: //获取下一个状态 if (m_actionList.Count > 0) { string str = "idle"; switch(m_actionList[0].status) { case HeroStatus.move: str = "idle"; break; default: str = Enum.GetName(typeof(HeroStatus), m_actionList[0].status); break; } m_spriteAnimation.namePrefix = str; m_spriteAnimation.loop = m_actionList[0].loop; m_destination = m_actionList[0].destinationMove; m_speed = m_actionList[0].speed; m_spriteAnimation.ResetToBeginning(); m_staus = m_actionList[0].status; m_actionList.RemoveAt(0); } else { m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); m_spriteAnimation.loop = true; m_spriteAnimation.ResetToBeginning(); m_staus = HeroStatus.idle; } break; // case HeroStatus.moveback: // //transform.position = Vector3.SmoothDamp(transform.position, destinationMove, ref cameraVelocity, smoothTime); // transform.position = Vector3.MoveTowards(transform.position, destinationMove, m_speed * Time.deltaTime); // if (transform.position == destinationMove) // m_staus = HeroStatus.idle; // break; } } public void SetPosition(byte pos, float x, float y) { m_posIndex = pos; transform.localPosition = new Vector3(x, y); } public void AttackCallBack() { //创建攻击特效 A攻击B B掉血222 B反击A闪避 UnityEngine.Object sourceObj = Resources.Load("AttackCrash"); GameObject go = UnityEngine.Object.Instantiate(sourceObj) as GameObject; go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localPosition = new Vector3(-70, 0, 0); } private void OnCollisionEnter(Collision co) { //进入碰撞 Debug.Log("进入碰撞!"); UnityEngine.Object sourceObj = Resources.Load("Effect"); GameObject go = UnityEngine.Object.Instantiate(sourceObj) as GameObject; go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localPosition = new Vector3(0, 0, 0); //Defense(); Hit(); } public void Attack(GameObject aims) { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.move; tmpAD.loop = true; UISprite tmpS = transform.GetComponent(); tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(aims.transform.localPosition.x + (tmpS.width/2), aims.transform.localPosition.y)); tmpAD.speed = Vector3.Distance(transform.position, tmpAD.destinationMove) * 4; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.attack; tmpAD1.loop = false; tmpAD1.destinationMove = Vector3.zero; tmpAD1.speed = 0; m_actionList.Add(tmpAD1); ActionData tmpAD2 = new ActionData(); tmpAD2.status = HeroStatus.move; tmpAD2.loop = true; tmpAD2.destinationMove = transform.position; tmpAD2.speed = Vector3.Distance(tmpAD.destinationMove, tmpAD2.destinationMove) * 4; //4/1秒到达目的地 m_actionList.Add(tmpAD2); } public void Defense() { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.defense; tmpAD.loop = false; tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(transform.localPosition.x - 25, transform.localPosition.y)); tmpAD.speed = 0.25f; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.move; tmpAD1.loop = false; tmpAD1.destinationMove = transform.position; tmpAD1.speed = 0.8f; //4/1秒到达目的地 m_actionList.Add(tmpAD1); } public void Hit() { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.hit; tmpAD.loop = false; tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(transform.localPosition.x - 25, transform.localPosition.y)); tmpAD.speed = 0.3f; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.move; tmpAD1.loop = false; tmpAD1.destinationMove = transform.position; tmpAD1.speed = 0.8f; //4/1秒到达目的地 m_actionList.Add(tmpAD1); } public void Idle() { m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); m_spriteAnimation.loop = true; m_spriteAnimation.ResetToBeginning(); m_staus = HeroStatus.idle; } public void Move() { // //transform.GetComponent().depth = 99; // GameObject go = GameObject.Find("enemy").gameObject; // destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(go.transform.localPosition.x + 98,go.transform.localPosition.y,go.transform.localPosition.z)); // m_speed = Vector3.Distance(transform.position, destinationMove) * 4; //4/1秒到达目的地 // m_staus = HeroStatus.moveto; // m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); // m_spriteAnimation.loop = true; // m_spriteAnimation.ResetToBeginning(); }
### 使用Unity进行回合制游戏开发的最佳实践 #### 关键技术概述 在Unity3D中构建回合制游戏涉及多个关键技术领域,包括但不限于关卡设计、编程基础、AI行为树、战斗逻辑处理、动画控制以及UI交互。对于这类游戏而言,良好的架构设计至关重要,这不仅有助于提高代码可维护性和扩展性,还能简化后续功能迭代过程。 #### 游戏结构规划 为了确保项目的清晰度和模块化程度,在创建新项目之初就应该定义好整体框架。通常情况下会采用MVC(Model-View-Controller)模式或是ECS(Entity Component System)[^2]来进行组织。前者强调数据模型与视图分离;后者则更加注重实体及其属性之间的关系表达,特别适合于复杂的游戏对象管理和高效能表现需求较高的场合。 #### AI决策机制 针对敌方单位的行为模拟可以借助Behavior Tree(行为树)工具完成。它允许开发者以图形化方式编辑不同角色的动作序列,并支持条件判断分支操作。这样既方便调试又易于调整策略参数设置,从而让玩家体验到更具挑战性的对手反应模式[^1]。 #### 战斗系统实现 核心玩法部分主要围绕着回合切换展开。每当一方行动完毕后即触发下一阶段准备动作,期间可能涉及到技能释放效果呈现、伤害结算计算等内容。此时应当充分利用协程(Coroutine)特性来同步执行多线程任务而不影响主线流程顺畅度。此外还需注意资源消耗判定规则的设计合理性,保证数值平衡性得以体现。 #### 动画与特效集成 视觉反馈是吸引用户注意力的重要手段之一。因此除了基本的人物移动路径外,还需要精心制作攻击姿态变化、受伤倒地等动态片段。与此同时配合粒子发射器(Particle System)创造出绚丽多彩的魔法光效或爆炸冲击波画面,增强临场感沉浸氛围。 #### 用户界面布局 最后便是至关重要的前端显示区域安排工作了。考虑到不同类型终端屏幕尺寸差异较大,建议采取响应式设计理念灵活适应各种分辨率规格。菜单按钮位置摆放要遵循人体工程学原则便于手指点击触控;而进度条样式风格也应保持简洁明快利于快速获取信息要点[^4]。 ```csharp // 示例:简单的回合制战斗函数 public IEnumerator BattleTurn() { yield return new WaitForSeconds(1f); // 延迟一秒等待前一回合结束 foreach (var unit in activeUnits) { if (!unit.IsDead()) { PerformAction(unit); yield return null; } } CheckEndCondition(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值