• Unity 从0开始编写一个技能编辑器_01_分析需求


    入职以来一直很想实现一个技能编辑器,在积累了一些经验以后,决定利用ScriptableObject开发一个,在此记录
    1.简单的需求分析
    游戏开发中,技能系统是一个至关重要的组成部分。技能决定了游戏角色可以执行的各种动作,例如攻击、治疗、移动等。通常,技能由多个元素组成,包括技能效果(Effect)、技能触发条件(triggerr)、技能冷却时间(Cooldown)等。为了更好地管理和调整这些技能,我们需要一个可视化的编辑器。
    2.粗略的实现哪些功能
    Buff 类似计时器功能 startscript endscript delaytime(开始延时时间) lasttime(buff持续时间-1为永久) TrickTime(脚本执行间隔) TrickScript(持续时间内按间隔时间刷新执行的脚本)

    Trigger 一些事件触发 触发条件 判断是否执行后续脚本 触发后执行的脚本,要在特定位置埋下事件

    Effect 生成bullet 执行Script (设计一个skillbyEffect 凭此释放技能可以让怪物NPC靠Buff释放技能)

    Bullet 子弹 子弹形态 链接track

    Skill 技能应该具有各种属性,包括伤害、冷却时间、目标、范围等。编辑器需要允许用户定义这些属性,并且能够将 Effect、Buff 和 Bullet 与技能关联。

    3.ScriptableObject的意义
    可以创建多个不同类型的ScriptableObject,例如Skill、Buff、Effect、Bullet等,以满足不同的需求。
    ScriptableObject的数据是独立的,它们不依赖于特定的场景或游戏对象。这使得技能可以轻松地跨不同场景和游戏对象共享和重用。
    脚本化操作:可以通过脚本在运行时创建、修改和管理ScriptableObject。

    例如

    using UnityEngine;
    using UnityEngine.Events;
    
    [CreateAssetMenu(fileName = "New Skill", menuName = "Skill System/Skill")]
    public class SkillSo : ScriptableObject
    {
    	[SerializeField]
    	public SkillType skillType;
    
    	[SerializeField]
    	public AttackType attackType;
    
    	[SerializeField]
    	public float spiritCost;
    
    	[SerializeField]
    	public float damageRatio;
    
    	[SerializeField]
    	public float skillCD;
    
    	public float lifeTime;
    
    	public Vector3 direction;
    
    	public float speed;
    
    	public float damage = 1f;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    [CreateAssetMenu(fileName = “New Skill”, menuName = “Skill System/Skill”)] 是一个特性(Attribute),用于在Unity编辑器中创建新的技能资产(Asset)。它指定了在Unity项目中创建新技能时的默认文件名和菜单路径。这使得在Unity编辑器中可以右键点击创建新技能,并将其保存为一个ScriptableObject。
    下面一系列的 public 字段是用来存储技能的各种属性和参数。这些字段包括:

    skillType:技能的类型,可能是一个自定义枚举类型 SkillType。
    attackType:技能的攻击类型,可能是一个自定义枚举类型 AttackType。
    spiritCost:使用技能所需的精力消耗。
    damageRatio:技能的伤害比率。
    skillCD:技能的冷却时间。
    lifeTime:技能在游戏中存在的时间。
    direction:技能的方向。
    speed:技能的速度。
    damage:技能的伤害值,默认为1。
    后续我可能会扩展它和SkillType的枚举

    在编写这段代码后即可右键创建so文件
    在这里插入图片描述

    using System;
    
    // 技能类型枚举
    public enum SkillType
    {
        MeteorSword,             // 陨剑术
        SkySword,           // 天剑
        SpeedBuff,          // 速度增益
        SwordRain,          // 剑雨
        WaterDrawSword,     // 提水剑
        None                // 无
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    一个简单的skillType枚举
    在这里插入图片描述
    然后设计一个skill基类去读取和利用其中的信息

    public abstract class SkillBase : MonoBehaviour
    {
    	public SkillSo so;
    
    	public SkillType GetSkillType()
    	{
    		return so.skillType;
    	}
    
    
    	public AttackType GetAttackType()
    	{
    		return so.attackType;
    	}
    
    
    	public float SpiritCost()
    	{
    		return so.spiritCost;
    	}
    
    
    	public float DamageRatio()
    	{
    		return so.damageRatio;
    	}
    
    
    	public float SkillCD()
    	{
    		return so.skillCD;
    	}
    
    
    	protected void Awake()
    	{
    		so.sr = base.GetComponentInChildren<SpriteRenderer>();
    	}
    
    
    
    
    	protected virtual void SkillFinish()
    	{
            UnityEngine.Object.Destroy(base.gameObject);
    	}
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    后续应该在skillbase写一些逻辑去处理,例如对外提供skill图标让UImanager加载,对碰撞或范围内的敌人造成伤害。

    在贴一个attackType

    using System;
    
    // 攻击类型枚举
    public enum AttackType
    {
        Metal,    // 金
        Wood,     // 木
        Water,    // 水
        Fire,     // 火
        Earth,    // 土
        Thunder,  // 雷
        Sword,    // 剑
        None      // 无
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    然后我会设计palyerManager去读取预制体身上实例的SkillSo文件进行相应的处理

    今天就先分享到这,管他能不能用,先写了再说

  • 相关阅读:
    种草文案怎么写吸引人?纯干货
    LeetCode LCP 06.拿硬币
    华为od德科面试数据算法解析 2022-7-1 参赛团队能力值
    对比分析小游戏引擎孰优孰劣
    【C++】命名空间深度理解
    Typora+Node.js+PicGo+Gitee 设置图片自动上传
    参加Ultimate Harvest Moon活动,立即赢取终极版月光女神NFT
    2024.2.25 模拟实现 RabbitMQ —— 网络通信设计(服务器)
    代码随想录算法训练营第23期day7| 454.四数相加II 、383. 赎金信 、15. 三数之和、18. 四数之和
    瑞芯微:基于RK3568的深度估计模型部署
  • 原文地址:https://blog.csdn.net/qq_45498613/article/details/132785403