Unity ScriptableObject初探

来源:互联网 发布:开发sql语句美化小工具 编辑:程序博客网 时间:2024/06/07 20:08

开发游戏的过程中,经常会遇到数据的存取,例如,技能信息,人物信息,物品信息等等。通常的做法就是使用序列化,反序列化的方式例如,xml,json,二进制构造器。但是这些方式对策划来说是不友好的,而且如果我们在unity编辑器模式下运行,修改后的值一旦停止运行就会恢复原样。还有一点就是我们需要使数据唯一性(只有一份数据)。Unity意识到了这一点,于是给我们提供了ScriptableObject数据容器。

下面我们来看一下它是怎么使用的

首先我们新建一个场景,在场景中添加俩个技能图标

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

这里主要看一下技能冷却图标怎么做


现在开始结合ScriptableObject

using UnityEngine;using System.Collections;public abstract class AbstractAbility : ScriptableObject {    public string aName = "New Ability";//技能名字    public Sprite aSprite;//技能图片    public AudioClip aSound;//技能使用时的声音    public float aBaseCoolDown = 1f;//技能冷却时间    public abstract void TriggerAbility ();//技能触发函数}

创建一个技能的抽象类,让它继承ScriptableObject


using UnityEngine;using System.Collections;[CreateAssetMenu (menuName = "Abilities/Ability1")]public class Ability1 : AbstractAbility {    public int damage = 100;//技能伤害值    public override void TriggerAbility()    {        //释放技能    }}

继承了ScriptableObject的脚本不能添加到游戏物体上,它们可以作为asset保存在我们的项目中,现在回到Unity中

这里写图片描述

点击Assets按钮,发现出现了我们自定义的Ability1,点击后

这里写图片描述

发现在项目视图中出现了一个asset文件,我们改名为Ability1,鼠标点击后,看Inspector视图,之前脚本中的变量都显示出来了(可以试一下在运行状态下去改变值,停止后值也跟着变了)

这里写图片描述

再添加一个Ability2


下面再写一个脚本

using UnityEngine;using System.Collections;using UnityEngine.UI;public class AbilityController : MonoBehaviour {    public string abilityButtonAxisName = "Fire1";//释放技能的按钮名字    public Image darkMask;//技能图标的遮罩    public Text coolDownTextDisplay;//技能冷却文字    public AbstractAbility ability;//技能    private Image myButtonImage;//技能图标    private AudioSource abilitySource;//声音源    private float coolDownDuration;//技能冷却时间    private float nextReadyTime;//下次释放技能的时间    private float coolDownTimeLeft;//冷却剩余时间    void Start(){        myButtonImage = GetComponent<Image> ();        abilitySource = GetComponent<AudioSource> ();        myButtonImage.sprite = ability.aSprite;        darkMask.sprite = ability.aSprite;        coolDownDuration = ability.aBaseCoolDown;        AbilityReady ();    }    void Update ()     {        bool coolDownComplete = (Time.time > nextReadyTime);//判断释放可以释放技能        if (coolDownComplete)         {            AbilityReady ();//准备技能            if (Input.GetButtonDown (abilityButtonAxisName)) //如果按下释放技能的按钮            {                ButtonTriggered ();            }        } else         {            CoolDown();//冷却中        }    }    private void AbilityReady()    {        coolDownTextDisplay.enabled = false;//隐藏技能冷却文字        darkMask.enabled = false;//隐藏技能图标遮罩    }    private void CoolDown()    {        coolDownTimeLeft -= Time.deltaTime;        float roundedCd = Mathf.Round (coolDownTimeLeft);//四舍五入        coolDownTextDisplay.text = roundedCd.ToString ();        darkMask.fillAmount = (coolDownTimeLeft / coolDownDuration);    }    private void ButtonTriggered()//释放技能    {        nextReadyTime = coolDownDuration + Time.time;        coolDownTimeLeft = coolDownDuration;        darkMask.enabled = true;        coolDownTextDisplay.enabled = true;        abilitySource.clip = ability.aSound;        abilitySource.Play ();        ability.TriggerAbility ();    }}

再次回到Unity中

这里写图片描述
这里写图片描述

将Ability1,Ability2分别拖到俩个技能图标的AbilityController上,此时运行,然后分别点击鼠标左右键

这里写图片描述

当你在多个脚本中关联同样的ScriptableObject时,做的所以操作都是针对这一个ScriptableObject,就像材质一样,都是拿到了它的引用而不是复制,所以也解决了数据的唯一性和共享性。

0 0
原创粉丝点击