Unity基于响应式编程(Reactive programming)入门

系列目录

【Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动

【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动

时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现

时光煮雨 Unity3D实现2D人物动画① UGUI&Native2D序列帧动画

时光煮雨 Unity3D实现2D人物动画② Unity2D 动画系统&资源效率

背景

前有慕容小匹夫的一篇《解构C#游戏框架uFrame兼谈游戏架构设计》,引用文中内容

uFrame是提供给3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分)。因为用于Unity3D,所以它向开发者提供了一套基于Editor的可视化编辑工具,可以用来管理代码结构等。需要指出的是它的一个重要的理念,同时也是软件工程中的一个重要理念就是关注分离(Separation of concern,SoC)。uFrame借助控制反转(IoC)/依赖注入(DI)实现了这种分离,从而进一步实现了MVVM这种模式。且在1.5版本之后,引入了UniRx库,引进了响应式编程的思想。

读起来高大上,本文主要想从实际出发,着手最后一句“且在1.5版本之后,引入了UniRx库,引进了响应式编程的思想。”,在Unity中如何使用响应式编程,如何使用UniRx库。

当然一下列出这么多新概念性的东西,作为新手必然理解起来有困难的,当然我也希望你是天赋迥异的人。这里列出几点,如果你不了解,请自行去学习或者复习,回来在看也不迟。

1、Linq基础,Linq的本质及与传统命令式编程的区别和优点

2、声明式编程和命令式编程的概念和区别

3、什么是响应式编程

4、什么是观察者模式

5、软件编程中Stream的概念

好了装b时间过去了,让我们简单的说下什么是响应式编程。这里也不废话,引用一段,看的懂得自然明白,不懂得还是不明白

什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LINQ风格编写基于观察者模式的异步编程模型。简单点说Rx = Observables + LINQ + Schedulers。

这里为什么要在游戏开发中引入响应式编程Rx,答案是游戏特别适合RX编程,因为在游戏中广泛应用了时间(帧)和事件(UI)的概念,时间本身是一种流,而事件也是基于时间的一种信号(并不是特别准确,意会),而这正是RX所擅长的。

实现

本文以系列文章中的精灵鼠标移动和序列帧动画为基础,没有基础的先参考下传统实现方式一下两篇文章

时光煮雨 Unity3D实现2D人物动画① UGUI&Native2D序列帧动画

时光煮雨 Unity3D实现2D人物动画② Unity2D 动画系统&资源效率

这里引入了UniRx库,来实现基于响应式编程及声明式编程代码重构,代码如下:

using UnityEngine;
using UniRx;

public class PlayerController : MonoBehaviour
{
    public float speed;
    private Vector3 moveDirection;

private int currentTexture = 0;
    public Sprite[] textureArray;
    // Use this for initialization
    void Start()
    {
        //鼠标控制移动,每帧更新
        Observable.EveryUpdate()
         .Subscribe(_ =>
         {
             //1、获得当前位置
             Vector3 curenPosition = this.transform.position;
             //2、获得方向
             if (Input.GetButton("Fire1"))
             {
                 Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);

moveDirection = moveToward - curenPosition;
                 moveDirection.z = 0;
                 moveDirection.Normalize();
             }
             //3、插值移动
             Vector3 target = moveDirection * speed + curenPosition;
             transform.position = Vector3.Lerp(curenPosition, target, Time.deltaTime);
         });

//帧动画
        SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
        //定时器每隔5帧
        Observable.IntervalFrame(5).Subscribe(_ =>
        {
            currentTexture++;
            if (currentTexture >= textureArray.Length)
            {
                currentTexture = 0;
            }
            spriteRenderer.sprite = textureArray[currentTexture];
        });
    }

}
是的没有看错,你没有发现熟悉的Update函数,如果说以上函数让你看到就是把所有代码就放在了Start里面而已,我们再重构一下代码,使用提取方法,看看效果,这就是声明式编程的魅力,程序可读性增强,更适合人类的思维方式

using UnityEngine;
using UniRx;

public class PlayerController : MonoBehaviour
{
    public float speed;
    private Vector3 moveDirection;

private int currentTexture = 0;
    public Sprite[] textureArray;
    // Use this for initialization
    void Start()
    {
        //鼠标控制移动,每帧更新
        PlayerMove();

//角色 帧动画
        PlayerAnimation();
    }

/// <summary>
    /// 角色 帧动画控制
    /// </summary>
    private void PlayerAnimation()
    {
        SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
        //定时器每隔5帧
        Observable.IntervalFrame(5).Subscribe(_ =>
        {
            currentTexture++;
            if (currentTexture >= textureArray.Length)
            {
                currentTexture = 0;
            }
            spriteRenderer.sprite = textureArray[currentTexture];
        });
    }

/// <summary>
    /// 鼠标控制移动,每帧更新
    /// </summary>
    private void PlayerMove()
    {
        Observable.EveryUpdate()
            .Subscribe(_ =>
            {
                //1、获得当前位置
                Vector3 curenPosition = this.transform.position;
                //2、获得方向
                if (Input.GetButton("Fire1"))
                {
                    Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);

moveDirection = moveToward - curenPosition;
                    moveDirection.z = 0;
                    moveDirection.Normalize();
                }
                //3、插值移动
                Vector3 target = moveDirection*speed + curenPosition;
                transform.position = Vector3.Lerp(curenPosition, target, Time.deltaTime);
            });
    }
}

总结

这里记住UniRx两个方法 Observable.EveryUpdate,Observable.IntervalFrame(这里还记得以前文章里提的定时器吗,这个定时器怎么样简单吧),还有ObservableWWW.GetWWW(上一篇的一个异步加载资源的函数),采用声明式编程的方式,看看函数名就知道是干什么的了吧,还用看文档或者解释什么吗?

文章内容比较简单,实现的功能也简单,函数也简单,希望你们喜欢。

时间: 2024-10-12 23:34:05

Unity基于响应式编程(Reactive programming)入门的相关文章

响应式编程系列(一):什么是响应式编程?reactor入门

响应式编程 系列文章目录 (一)什么是响应式编程?reactor入门 (二)Flux入门学习:流的概念,特性和基本操作 (三)Flux深入学习:流的高级特性和进阶用法 (四)reactor-core响应式api如何测试和调试? (五)Spring reactive: Spring WebFlux的使用 (六)Spring reactive: webClient的使用 引言 Spring framework 5 的一大新特性:响应式编程(Reactive Programming).那么什么是响应式

Net中的反应式编程(Reactive Programming)

目录 系列主题:基于消息的软件架构模型演变 系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LINQ风格编写基于观察者模式的异步编程模型.简单点说Rx = Observables + LINQ + Schedulers. 2.为什么会产生这种风格的编程模型?我在本系列文章开始的时候说过一个使用事件的例子: 1 2 3 4 5 6 7 8 9 var 

IOS开发之OC篇-响应式编程Reactive Cocoa

一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:https://github.com/ReactiveCocoa/ReactiveCocoa 二.相关概念 1> 响应式编程 举个栗子,在一般程序开发时  a = b + c , 赋值之后 b 或者 c 的值变化后,a 的值不会跟着变化, 如果使用响应式编程,目标就是,如果 b 或者 c 的数值发生变化,

1小时让你掌握响应式编程,并入门Reactor

我看同步阻塞 “你知道什么是同步阻塞吗”,当然知道了.“那你怎么看它呢”,这个... 在同步阻塞的世界里,代码执行到哪里,数据就跟到哪里.如果数据很慢跟不上来,代码就停在那里等待数据的到来,然后再带着数据一起往下执行. 可以说是,代码执行和数据是结伴而行,不离不弃.执子之手与子偕老.让人老感动了. 如果还不太理解的话,可以认为代码执行其实就是一些行为动作,这些行为动作的目的就是为了获取/操作数据. 例如加法,这里的行为动作就是执行相加,数据就是加数和被加数.操作结果就是得到了另一个数据,即两个数

[译] Swift 的响应式编程

原文  https://github.com/bboyfeiyu/iOS-tech-frontier/blob/master/issue-3/Swift的响应式编程.md 原文链接 : Reactive Swift 原文作者 : Agnes Vasarhelyi 译文出自 : 开发技术前线 www.devtf.cn 译者 :Mr.Simple 校对者:Lollypo 状态 : 完成 让我们首先回到Apple刚推出Objective-C的继任者-Swift的时候,那真是一个非比寻常的时刻. Sir

RxJava入门系列三,响应式编程

RxJava入门系列三,响应式编程 在RxJava入门系列一,我向你介绍了RxJava的基础架构.RxJava入门系列二,我向你展示了RxJava提供的多种牛逼操作符.但是你可能仍然没能劝服自己使用RxJava,这一篇博客里我将向你展示RxJava提供的其他优势,没准了解了这些优势,你就真的想去使用RxJava了. 异常处理 直到目前为止,我都没有去介绍onComplete()和onError()方法.这两个方法是用来停止Observable继续发出事件并告知观察者为什么停止(是正常的停止还是因

使用ReactiveCocoa实现iOS平台响应式编程

使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Programming,响应式编程),在维基百科中有这样一个例子介绍: 在命令式编程环境中,a = b + c 表示将表达式的结果赋给a,而之后改变b或c的值不会影响a.但在响应式编程中,a的值会随着b或c的更新而更新. Excel就是响应式编程的一个例子.单元格可以包含字面值或类似"=B1+C1″的公式,

ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!

ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一! 简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模式的完美搭档,更多关于MVVM与ReactiveCocoa的讨论,参考这篇文章: [长篇高能]ReactiveCocoa 和 MVVM 入门 注意: ReactiveCocoa 最新3.0版本,使用Swift重写,

[转帖]浅谈响应式编程(Reactive Programming)

浅谈响应式编程(Reactive Programming) https://www.jianshu.com/p/1765f658200a 例子写的非常好呢. 0.9312018.02.14 21:22:16字数 1877阅读 9816 这是告别CSDN后第一次使用简书写IT类的博客,还在适应.最不适应的就是不能直接手输markdown语法标记.(好像原因是我没有切换编辑器) 什么是响应式编程(Reactive Programming) In computing, reactive program