Unity ScriptableObject初探

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w1594731007/article/details/71747793

开发游戏的过程中,经常会遇到数据的存取,例如,技能信息,人物信息,物品信息等等。通常的做法就是使用序列化,反序列化的方式例如,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,就像材质一样,都是拿到了它的引用而不是复制,所以也解决了数据的唯一性和共享性。

展开阅读全文

没有更多推荐了,返回首页