zoukankan      html  css  js  c++  java
  • 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现

    本文首发蛮牛,次发博客园。接系列 第一篇第二篇,本文为第三篇,再次感谢“武装三藏”在前两篇无私且精彩的问题解答

    写在最前,时光煮雨,为了怀念

    以下引用曾今读过的一些教程文章

      其实这3种动画都有它特定的使用场合。

        第一种动画适合创建简单的对象位移及直接性质的属性更改(在后面的教程中,我还将更深入的挖掘Storyboard动画的潜力,动态创建更复杂的基于KeyFrame的关键帧动画)。

        第二种动画适合全局属性的时时更改,例如我们后面要讲到的敌人或NPC以及地图等全体性的相对位移及属性更改时就要用到它了。

        第三种动画则非常适合运用在Spirit(角色)的个人动画中,例如角色的移动,战斗,施法等动作。

        小结:前三节分别讲解了Storyboard动画,CompositionTarget动画,DispatcherTimer动画,并横向分析了不同的场合对应不同的动画应用模式,这些将是构成WPF/Silverlight游戏引擎的基础。

    这里的三种动画形式分别可以类比到Unity3d中的,

    第一种,基于DoTween的各种MoveTo(Vector3,duration),或者是第一篇的直接移动;

    第二种,基于Update的逐帧更新;

    第三种,基于FixUpdate的定时更新,比如这里提到的战斗可能是有物理碰撞,或者是一种类似自定义的计时器的Timer(下篇会分析下)。

    这些东西比较底层了,需要了解FixUpdate和Update的区别,以及UI线程和非UI线程之间的关系(wpf中的DispatcherTimer的概念)

    这块东西有点深,我也不敢妄言,是否正确有大师路过,可以解惑一下。列出两篇参考文章,供延伸阅读吧

    Difference between Update method and FixedUpdate in Unity?

    WPF中的Timer与DispatcherTimer的区别与应用

    这三种动画形式,很多人都知道,但是如何使用和区别,却在博文中只字未提。

    这里引用列出来只为怀念。

    背景

     

    前两篇都比较基础,运用一些基础知识,其实早都有一些大牛封装好了插件和工具,不必大家再重复制造轮子。但各种封装难免有功能重叠,且可能用法也会有不同,这可能是我们需要稍微留意的东西。这篇主要罗列下基于DoTween插件UGUI的直接移动和Unity Native2D实现鼠标点击逐帧移动的功能实现,关于这两个插件和功能不再详解,因为有的是教程,若想学习自己搜索吧。图片还是一样的

    run

    实现一

    基于DoTween的UGUI平移,这里自己计算了下 duration可能不对欢迎指正,代码如下:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    using DG.Tweening;
    public class PanelContollerDoTween : MonoBehaviour {
    
    	// Use this for initialization
        public Image sprite;
        private float speed=2;
    	void Start ()
    	{
    	   
    	}
    	
    	// Update is called once per frame
    	void Update () {
            if (Input.GetButton("Fire1"))
            {
                //这里写的该坐标是像素坐标,也就是屏幕坐标的意思(比世界坐标小)
                Vector3 mouseWorldPostion = Input.mousePosition;//Camera.main.ScreenToWorldPoint();
                float duration = Vector3.Distance(mouseWorldPostion , sprite.transform.position) / speed * Application.targetFrameRate;
                sprite.transform.DOMove(mouseWorldPostion, duration).SetEase(Ease.Linear);
    
            }
    	}
    }
    

      

    实现二

    这块稍微说一下,看过很多教程一般都是单讲UGUI或者单讲Natvie2D,很少有一起使用的,这里自己实验了下,直接建立一个Scene和UGUI一起使用即可,比较简单,深色的框是我给Panel设置的颜色便于区别,这里发现二者可以很好的共存的,效果图如下:

    4

    代码如下:

    using UnityEngine;
    using System.Collections;
    
    public class PlayerController : MonoBehaviour
    {
        private Vector3 currentPositon;
        private Vector3 moveDirection;
        private float speed = 2;
        private Vector3 targetPositon;
        Vector3 mouseWorldPositon = Vector3.zero;
        // Use this for initialization
        void Start()
        {
            moveDirection = Vector3.right;
    
        }
    
        // Update is called once per frame
        void Update()
        {
            currentPositon = transform.position;
            //是鼠标左键点击
            if (Input.GetButton("Fire1"))
            {
                mouseWorldPositon = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    
                moveDirection = mouseWorldPositon - currentPositon;
                moveDirection.z = 0;
                moveDirection.Normalize();
            }
    
            
            //Debug.Log(string.Format("x1:{0},y1:{1},z1:{2},x2:{3},y2:{4},z2:{5},d:{6}", mouseWorldPositon.x, mouseWorldPositon.y,mouseWorldPositon.z, currentPositon.x, currentPositon.y,currentPositon.z, Vector3.Distance(mouseWorldPositon, currentPositon)));
            if (Vector3.Distance(new Vector3( mouseWorldPositon.x,mouseWorldPositon.y,0), currentPositon) > 1)
            {
                targetPositon = moveDirection * speed + currentPositon;
                transform.position = Vector3.Lerp(currentPositon, targetPositon, Time.deltaTime);
            }
            else
            {
                transform.position = targetPositon;
            }
        }
    
    
    }
    

      

    这里留下了一个小问题就是关于移动了某一点的判断问题,这里我简单的使用了两点的距离小与某个绝对值来做的,但在Natvie2D下发现移动有跳跃,主要是坐标系的单位问题,如果有高手路过可以帮忙提供更好的方法。

    问题总结

    根据三篇的学习,这篇是收获比较大的,特别是通过这篇的学习,找到了上篇中遇到的问题,主要是

    1、鼠标点击的坐标问题?

    2、是关于Vecotr3.Lerp插值的问题

    如果细心的朋友可能会发现2个函数我在UGUI中都是注释掉的 

    Camera.main.ScreenToWorldPoint(Input.mousePosition)

    Vector3.Lerp(currentPositon, targetPositon, Time.deltaTime);

    主要的问题其实是在坐标系的值上,UGUI专门做了一次优化,使用的2D世界的屏幕坐标单位是像素,值都很大,而Native2D使用的是3D世界的坐标系统单位是浮点百分值,所以在转换和使用上有差异的。

    这篇也留下了一个问题,就是UGUI和Native2D的鼠标事件的遮挡问题,现在看到的现象是鼠标事件是可以穿越的,这个问题等到以后再解决吧。

  • 相关阅读:
    C# 运用StreamReader类和StreamWriter类实现文件的读写操作
    C# 理解FileInfo类的Open()方法
    C# 运用FileInfo类创建、删除文件
    C# 创建子目录
    C# 目录下的文件操作
    C# 运用DirectoryInfo类和FileInfo类
    C# 文件操作概述
    LINUX介绍
    linux iso 下载地址
    ADO.NET梳理
  • 原文地址:https://www.cnblogs.com/IlidanStormRage/p/5999158.html
Copyright © 2011-2022 走看看