背景

上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印证了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;
} } }

  

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

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

本文旨在通过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到底是什么坐标是屏幕坐标还是世界坐标,文档模棱两可并没有说明

总结

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

【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动的更多相关文章

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

    背景 首先还是先声明自己是比较笨的一个人,总是找不到高效的学习方法,目前自己学习Unity3D的方式主要是两种,一种是直接看高质量的源码,另一种是光看不行还要自己动手,自己写一些有代表性的小程序,这也 ...

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

    本文首发蛮牛,次发博客园.接系列 第一篇,第二篇,本文为第三篇,再次感谢“武装三藏”在前两篇无私且精彩的问题解答 写在最前,时光煮雨,为了怀念 以下引用曾今读过的一些教程文章 其实这3种动画都有它特定 ...

  3. Unity3D鼠标点击物体产生事件

    如果需要处理鼠标点击物体的情况, 可以当数据接触物体时,鼠标手势改变,然后点击后和NPC产生对话等: using UnityEngine; using System.Collections; publ ...

  4. Unity3D基础学习 NGUI Example 7-Scroll View(Panel)制作固定包裹栏,点击传递参数显示物体

    最终效果如下: 实现ScrollView主要是NGUI的三个脚本"UIDraggable Panel","UIGrid","UIDrag Panel ...

  5. 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...

  6. unity3d基础01

    Unity3d 五大视图: 1 Scene:存放hierarchy中创建的游戏对象,但实际只能看到一部分 *Scene浏览: ①右键进入“飞行模式”,方便查看整个场景 ②选中摄像机,按ALT进入浏览的 ...

  7. Android开发 Unity3D基础 Android Development

    开发环境 Window 7 Unity3D 3.3.0 MB525 defy Android 2.1-update1 本次学习: 1.认识Unity 2.Unity3D环境搭建与Android软件生成 ...

  8. unity提高----------射线使用【unity3d 怎样获得当前鼠标点击的对象】

    unity3d 怎样获得当前鼠标点击的对象 最佳答案   var ray = Camera.main.ScreenPointToRay (Input.mousePosition);var hit : ...

  9. webgl学习总结画线面及场景和物体动

    WebGL是在浏览器中实现三维效果的一套规范.是浏览器中的3D引擎,是利用js代码来实现加载3D模型,渲染.输出等功能,从而实现在浏览器和微信中浏览三维文件的效果. three.js是基于WebGL的 ...

随机推荐

  1. iOS9 tableVIewCell的分割线不显示,只有在滑动的时候才显示?

    1.如果用6plus模拟器的话,电脑分辨率达不到那么高,因此就看不到分割线. 2.把模拟器换成6s 或 5s,就没问题了.

  2. js小效果-轮播图

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  3. 前端自动化工具 -- grunt 使用简介

    grunt作为一个前端构建工具,有资源压缩,代码检查,文件合并等功能. 下面就简单了解grunt的使用. 一.环境配置 grunt是基于nodejs的,所以需要一个 nodejs 环境,未了解的可以  ...

  4. oracle中number类型的数据使用as string 得到的值为null

    1,如果数据的运行时类型(和数据库字段类型相同)不是字符串类型,比如number/date等,将ds.Tables[0].Rows[i][j] 调用 as string 时,不管 这个字段是否有值,这 ...

  5. android夜间模式实现

    一.概述 android夜间模式实现分为两大类 重启activity的实现 不重启activity的实现 二.正文 1.重启activity实现夜间模式[在界面文件中的实现部分] 1.1在attrs. ...

  6. [LintCode] Longest Increasing Continuous Subsequence 最长连续递增子序列

    Give an integer array,find the longest increasing continuous subsequence in this array. An increasin ...

  7. DOS运行命令

    运行命令主要是DOS操作系统的运行方式.DOS时代的时候,为了方便用户的操作,微软公司将一些常用的命令,如DIR,CD等命令全部集成在系统里面. 基本定义 对于DOS来说是一个很大的优点.而存放这些内 ...

  8. 无法删除DLL文件解决方法(转)

    手动解决dll文件无法删除的终极方法 手动解决dll文件无法删除的终极方法 相信大家都遇见过:在删除一些软件的时候弹出某某文件正在运行或磁盘写保护不能删除这样的报错提示吧.而常常删除不掉的都一些后缀为 ...

  9. static静态结合&符号理解

    上代码,方法定义为静态变量 <?php function &test(){ static $c=222; return $c; } $a=&test(); echo $a; ec ...

  10. wget 下载整个网站,或者特定目录

    需要下载某个目录下面的所有文件.命令如下 wget -c -r -np -k -L -p www.xxx.org/pub/path/ 在下载时.有用到外部域名的图片或连接.如果需要同时下载就要用-H参 ...