zoukankan      html  css  js  c++  java
  • 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动

    背景

    上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印证了Unity3d的复杂性(同样的功能多次封装),代码如下:

    public class DebugTest : MonoBehaviour
    {
    RectTransform m_Rect;
    
    void Start ()
    {
    m_Rect = GetComponent<RectTransform>();
    }
    
    void Update()
    {
    if(Input.GetMouseButtonUp(0))
    {
    m_Rect.position = Input.mousePosition;
    }
    
    }
    
    }
    

      

    效果如下(由于效果基本相似,接上一篇的预览图):

    run

    这一篇主要解决上一篇最后提出的问题,也就是通过这样鼠标移动物体时不够平滑的,不管有多远都是瞬移过去的,视觉体验不够优秀。

    本文旨在通过Update中逐帧移动。达到平滑移动的效果

    原理

    1、记录鼠标点击的点,这个点是如果是屏幕坐标
    2、将这个屏幕坐标转换成世界坐标
    3、使用鼠标的世界坐标-精灵的世界坐标||也可以使用鼠标的本地坐标-精灵的本地坐标
    4、通过3获得移动方向,做插值在Update里面移动精灵
    5、移动精灵可以使用世界坐标移动,也可以通过local本地坐标移动

    实现1

    通过UGUI 事件系统中的IPointerClickHandler实现鼠标点击,然后在Update中逐帧移动,所有坐标使用LocalPosition,原理很简单这里代码不啰嗦

       private RectTransform childPlayTransform;
        private float speed =10.0f;
        private Vector2 pointClickPostion;
        private Vector3 currentLocalPostion;
        private Vector3 moveDirect;
        // Use this for initialization
        void Start ()
        {
           //获得Image的Transform
            childPlayTransform = transform.Find("Image").GetComponent<RectTransform>();
           }
        
        // Update is called once per frame
        void Update ()
        {
                currentLocalPostion = childPlayTransform.localPosition;
                Vector3 targetPosition = moveDirect * speed + currentLocalPostion;
            childPlayTransform.localPosition = Vector3.Lerp(currentLocalPostion, targetPosition, Time.deltaTime*4f);
            }
    
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 localPoint;
            //在矩形范围内检测,全局鼠标点击点,到local点的转换
            RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.GetComponent<RectTransform>() , eventData.position,
                eventData.enterEventCamera, out localPoint);
    
            pointClickPostion = localPoint;
    
            moveDirect = new Vector3(pointClickPostion.x, pointClickPostion.y, 0) - currentLocalPostion;
            moveDirect.z = 0;
            moveDirect.Normalize();
        }
    

      

    实现2

    通过Unity3d 输入系统Input输入得鼠标位置,然后再Update中使用世界坐标进行精灵的逐帧平移,代码如下:

    private Transform spriteTransform;
      Vector3 direction;
      Vector3 spriteCurentPoistion;
      Vector3 targetPosition;
      float speed = 2.0f;
      void Start () {
          spriteTransform = transform.Find("Image") as Transform;
      }
    
      // Update is called once per frame
      void Update () {
          spriteCurentPoistion = spriteTransform.position;
          //向量加法(向鼠标方向)
          targetPosition = direction * speed + spriteCurentPoistion;
    
          spriteTransform.position = targetPosition;
      }
    
      public void OnPointerClick(PointerEventData eventData)
      {
          Vector3 mouseWorldPointer = new Vector3(eventData.position.x, eventData.position.y, 0);
          //屏幕坐标转换成世界坐标
          //Vector3 mouseWorldPointer = Camera.main.ScreenToWorldPoint(mouseScreenPointer);
          //向量减法获得指向鼠标点的方向
          direction = mouseWorldPointer - spriteTransform.position;
          direction.z = 0;
          direction.Normalize();
          Debug.Log(string.Format("x:{0},y:{1}-- {2},{3}", mouseWorldPointer.x, mouseWorldPointer.y, eventData.position.x, eventData.position.y));
      }
    

      

    问题记录

    在试验的时候遇到一些小问题,特此记录,也希望高手路过慷慨回答

    1、关于进行显性插值函数

    Vector3.Lerp(currentLocalPostion, targetPosition, Time.deltaTime*4f);

    实际这是一个公式也很简单,就是我看教程(Unity3d)的时候Time.deltaTime这个值很大,而实际中发现这个值很小,造成插值的时候很微量的移动,不知为何只能乘以一个系数

    2、关于Unity3d的Input输入的函数提示很弱

    比如 eventData.position和Input.mousePosition到底是什么坐标是屏幕坐标还是世界坐标,文档模棱两可并没有说明

    总结

    在实现一个如此小的功能,给人深刻影响的可以使用的方法很多,遇到一些知识点,原理也很简单,但你不深入却得不到答案。这个世界就像快餐,变得太快。

  • 相关阅读:
    常见面试题
    性能测试注意点
    orm 事物的使用
    mvc 页面如何引用命名空间并且直接使用枚举类型对象
    ef 动态拼接参数查询
    ef指定字段更新
    jquery 如何传递对象本身
    整数除以整数后转成百分比并且保留一位小数
    sql 表变量的使用
    echart的label标签文字过长显示不全怎么办?
  • 原文地址:https://www.cnblogs.com/IlidanStormRage/p/5993772.html
Copyright © 2011-2022 走看看