精华内容
下载资源
问答
  • 人物模型是从live2d下载下来的,这么可爱的二次元不可能是我画的。 live2d本身有对鼠标...3.通过y值去设置人物本身在unity中的动作幅度转动从python基础教程而实现跟随鼠标发生相应肢体变化的效果 先贴码源 using Sy

    人物模型是从live2d下载下来的,这么可爱的二次元不可能是我画的。
    live2d本身有对鼠标监测的封装方法(见对象L2DTargetPoint),鼠标在live2d的拖拽管理坐标系内会反馈一个c#教程鼠标的影响度,可看成一个在-1到1之间的比例值;
    这里的方法是:
    1.先获取鼠标当前在屏幕的位置
    2.利用已有公式将当前鼠标物理位置x转换成live2d内的世界坐标值y
    3.通过y值去设置人物本身在unity中的动作幅度转动从python基础教程而实现跟随鼠标发生相应肢体变化的效果
    先贴码源

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using live2d;
    using live2d.framework;
    
    public class Live2dModel : MonoBehaviour
    {
        public TextAsset modelFile;
        public Texture2D[] textures;
        public TextAsset[] motionFiles; //加载模型动画数组
    
        private Live2DMotion[] motions; //动作数组
    
        private L2DMotionManager l2DMotionManager;
        //优先级的设置标准
        //1.动作未进行的状态,优先级为0
        //2.待机动作发生时,优先级为1
        //3.其他动作进行时,优先级为2
        //4.无视优先级,强制发生的动作
    
        private Live2DModelUnity live2dModel;
    
        private Matrix4x4 live2DCanvasPos;
    
        private MotionQueueManager motionQueueManager; //动作的管理
        private MotionQueueManager motionQueueManagerA;
    
        private EyeBlinkMotion eyeBlinkMotion;
    
        //鼠标拖拽引起的动作变化
        private L2DTargetPoint drag;
    
        public int motionIndex;
    
        public float a;
    
        // Start is called before the first frame update
        void Start()
        {
            //初始化
            Live2D.init();
    
            for (int i = 0; i < textures.Length; i++)
            {
                live2dModel.setTexture(i, textures[i]);
            }
    
            //指定显示位置和尺寸(使用正交矩阵与相关API显示图像,再由游戏物体)
            float modelWidth = live2dModel.getCanvasWidth();
    
            live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50, 50);
    
            //播放动作
            //实例化动作对象
            //1.直接获取路径赋值来获取动画播放
            //live2DMotionIdle = Live2DMotion.loadMotion(Application.dataPath + "");
            //2.用textasset来加载动画播放资源 
            //TextAsset mtnFile = Resources.Load<TextAsset>("");
            //live2DMotionIdle = Live2DMotion.loadMotion(mtnFile.bytes);
            motions = new Live2DMotion[motionFiles.Length];
            for (int i = 0; i < motionFiles.Length; i++)
            {
                motions[i] = Live2DMotion.loadMotion(motionFiles[i].bytes);     //遍历完成所有动作的加载
            }
    
            //设置某一个动画的一些属性
            //setLoopFadeIn方法:重复播放的时候是否加上动作渐变淡入(即当前动作帧数较多 False是不淡入
            //setFadeOut方法:如果不设置那么默认淡出时间是1000ms 动作播放时长
            motions[0].setLoopFadeIn(false);
            motions[0].setFadeOut(1000);
    
        
    
            //动作的优先级使用
            l2DMotionManager = new L2DMotionManager();
    
            //眨眼
            eyeBlinkMotion = new EyeBlinkMotion();
    
            //鼠标拖拽
            drag = new L2DTargetPoint();
    
        }
    
        // Update is called once per frame
        void Update()
        {
            //具体是为了让camera把人物显示出来
            live2dModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos); 
    
            //模型跟随鼠标转向与看向
            //得到的live2d鼠标监测点的比例值是-11(对应一个live2d的拖拽管理坐标系,或者说叫影响度)
            //然后我们通过这个值去设置我们的参数 比如选择30°*当前得到的值
            //就会按照这个值所带来的影响度去影响我们的模型
            //从而达到看向鼠标点位置的效果
            Vector3 pos = Input.mousePosition;
            if (Input.GetMouseButton(0))     //0按下鼠标左键   1按下鼠标右键
            {
                //把当前的屏幕鼠标坐标转化成l2d内的鼠标监测坐标
                drag.Set(pos.x/Screen.width*2-1,pos.y/Screen.height*2-1);
            }else if (Input.GetMouseButtonUp(0))
            {
                drag.Set(0, 0);
            }
    
            //参数及时更新,考虑加速度等自然因素,计算坐标,进行逐帧更新
            drag.update();
    
            //模型转向
            if (drag.getX() != 0)
            {
                live2dModel.setParamFloat("PARAM_ANGLE_X", 30 * drag.getX());
                live2dModel.setParamFloat("PARAM_ANGLE_Y", 30 * drag.getY());
                live2dModel.setParamFloat("PARAM_BODY_ANGLE_X", 10 * drag.getX());
                live2dModel.setParamFloat("PARAM_EYE_BALL_X", -drag.getX());
                live2dModel.setParamFloat("PARAM_EYE_BALL_Y", -drag.getY());
            }
    
            //眨眼
            eyeBlinkMotion.setParam(live2dModel);
    
            //更新模型定点、参数、贴图
            live2dModel.update();
    
            
        }
    
        //绘图
        private void OnRenderObject()
        {
            live2dModel.draw();
        }
    
        private void StartMotion(int motionIndex, int priority)
        {
            //当前播放的动画优先级比传进来的高 返回
            if (l2DMotionManager.getCurrentPriority() >= priority)
            {
                return;
            }
    
            l2DMotionManager.startMotion(motions[motionIndex]);
        }
    
    }
    

    详细见注释。

    没研究出来怎么发GIF图,动作效果待补充。

    展开全文
  • 实现思路,当鼠标点击的时候开始在当前位置实例化LineRenderer对象,然后移动的过程中记录移动的点并赋值给LineRenderer中的Positions属性动态修改LineRenderer的形状和长度。碰撞器方面使用Edge Collider 2D通过类....

    使用Unity原生LineRenderer+Edge  Collider2D实现在2D场景中画线并带碰撞体。

    我们先来看看效果

    实现思路,当鼠标点击的时候开始在当前位置实例化LineRenderer对象,然后移动的过程中记录移动的点并赋值给LineRenderer中的 Positions属性动态修改LineRenderer的形状和长度。碰撞器方面使用Edge Collider 2D 通过类似方式,记录点并赋值给碰撞器的Points。

    OK看完了大概原理还是来看看具体的代码吧。

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System;
    public class DrawLineScripts : MonoBehaviour
    {
        //得到带有LineRender物体对象
        [Tooltip("The GameObject of LineObject")]
        public GameObject lineRenderer;
     
        //定义一个公共类来存储初始化成成的物体对象
        [Tooltip("The number of instantiate LineObject")]
        public int preFabLineCount = 6;
     
        //初始化LineRenderer 物体对象的集合
        [HideInInspector]
        public List<GameObject> lineList;
     
        //存储鼠标移动过的点
        [HideInInspector]
        public List<Vector2> linePos;
     
        //移动点索引
        private int idx = 0;
     
        //全局线段对象变量
        private GameObject gameObj;
     
        void Awake()
        {
            //激活阶段生成固定数量的物体对象
            for (int i = 0; i < preFabLineCount; i++)
            {
                GameObject go = Instantiate(lineRenderer, new Vector3(0f, 0f, 0f), Quaternion.identity);
                //将生成的对象隐藏,当需要使用的时候修改位置并显示出来。
                go.SetActive(false);
                //设置实例化出来物体的父级对象
                go.transform.SetParent(gameObject.transform);
                //将对象添加到全局列表中
                lineList.Add(go);
            }
        }
        // Update is called once per frame
        void Update()
        {
            if(Input.GetMouseButtonDown(0)) //鼠标左键点击的时候
            {
                gameObj = GetLineRenderer();
                //得到鼠标移动的坐标并将屏幕坐标转换为世界坐标
                Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
                //得到对象身上的LineRenderer组件
                LineRenderer lineRenderer = gameObj.GetComponent<LineRenderer>();
                //设置LineRenderer组件的起始位置
                lineRenderer.SetPosition(idx, new Vector3(ve3.x,ve3.y,0f));
                //设置LineRenderer的宽度
                lineRenderer.startWidth = 0.4f;
                //将二维坐标存到数组中
                Vector2 v2 = new Vector2(ve3.x, ve3.y);
                linePos.Add(v2);
            }
            else if(Input.GetMouseButton(0))    //鼠标左键移动或者静止的时候
            {
                ++idx;  //设置LineRenderer位置的索引每移动一次增加一次
                LineRenderer lineRenderer = gameObj.GetComponent<LineRenderer>();
                Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
                lineRenderer.positionCount = idx + 1;
                lineRenderer.SetPosition(idx, new Vector3(ve3.x, ve3.y, 0f));
                Vector2 v2 = new Vector2(ve3.x, ve3.y);
                linePos.Add(v2);
            }
            else if(Input.GetMouseButtonUp(0))  //鼠标左键抬起的时候
            {
                Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
                EdgeCollider2D edge = gameObj.GetComponent<EdgeCollider2D>();   //得到物体身上的EdgeCollider2D组件
                edge.points = linePos.ToArray();    //将存起来的二维向量点赋值到碰撞器实现碰撞器初始化
                linePos.Clear();    //清除点集合方便下次点击记录
                idx = 0;    //索引归零
            }
        }
        /// <summary>
        /// 获取LineRenderer对象,如果对象集合中有未激活对象则取出未激活对象并激活,否则生成新对象
        /// </summary>
        /// <returns></returns>
        private GameObject GetLineRenderer()
        {
            for (int i = 0; i < lineList.Count; i++)
            {
                if (lineList[i].activeInHierarchy == false)
                {
                    lineList[i].SetActive(true);
                    lineList[i].transform.position = new Vector3(0f, 0f, 0f);
                    return lineList[i];
                }
            }
            GameObject go = Instantiate(lineRenderer,new Vector3(0f,0f,0f),Quaternion.identity);
            go.transform.SetParent(gameObject.transform);
            lineList.Add(go);
            return go;
        }
    }
    代码里面有详细的注释,大部分讲清了实现原理,我们看一下Inspector面板。

     

    LineRenderer对象面板

     

     

     

     

     这里讲一下这个实现存在的问题,这个实现是基于2D场景的,如果要实现3D场景,只要修改其中的屏幕坐标转换成世界坐标的方法,然后LineRenderer设置点的时候直接使用三维向量坐标即可,但是在3D场景中Edge Collider 2D便不能使用了。具体使用什么碰撞器以后再研究。

     

    展开全文
  • Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D...

    系列目录

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

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

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

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

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

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

    前言

    上篇提到的引用的“图片切换法”,以及这篇要讲的“图片截取法”(这两个说法都是引用的大牛深蓝色右手的原话),实际上序列帧动画的本质就是定时器,已经反复强调过了。这里“图片切换法”和“图片截取法”主要是针对纹理资源的获取途径方式来划分的,主要原因还是渲染效率的问题,如果会写网页的同学也一定都知道有CSS有一种Sprite雪碧技术,就是把松散的小图合并成一张大图来减少网络请求数,这里原理是可以类比的。实际上在Unity3D中这个问题已经很好的解决了,这也是本文的一个主题。

    本文的两个主题分别是

    一、使用Animation编辑器实现2D人物序列帧动画

    二、Unity3D中2D资源的优化工具简介

    效果图

    1(1)

    实现

    一、使用Animation编辑器实现2D人物序列帧动画

    这里由于方面的教程很多,所以这里也就是点到为止,记录关键点和关键部分,需要学习的朋友自己按照其它教程实现一遍自然明白,这里就不用浪费口舌了。

    A、制作素材,这里直接引用深蓝的原话了

    准备工作:这里我以创建主角向右方向施法动画为例。首先需要将10帧150*150的图片通过Photoshop或其他方式合成为一张1500*150的大图,如下图:

    5

    从图上可以很清晰的看出主角的整个流畅的施法流程。接着,我将该文件取名叫PlayerMagic.png保存。还记得上篇引用的文字吗,个人觉得挺赞的 (因为是提取的素材,初始宽和高是不均衡值,所以必须扩大成自己的需求,这样人物会在图片中居中,并且为后期加入武器或坐骑留好余地。稍微的偏离也可以在后期进行微调

    红字部分觉得比较赞的。将该图导入到Unity3d中(很多种方法拖拽即可)

    B、使用Sprite Editor工具(点击Project下的图片)进行分割,这里有了A的上下文思想,所以个人觉得使用静态分割是比较合理的,图片素材由美工或者自己按照规格调好,符合单一原则,以下是截图

    spriteEditor

    2

    C、使用Animation工具窗口,制作序列帧动画即可(其实我觉得有点像关键帧动画不知道为什么叫序列帧),这里需要注意的就是制作动画必须选中GameObject(也是Animation工具必须的)这样动画控制组件和动画就自动挂接绑定到了选中的GameObject上,

    两个关键点:

    1、移动关键帧的时候,可以使用滚轮放大时间线,然后逐个拖拽(感觉不是很方便,不知道有没有更方便的方法)

    2、注意调节采样率已达到最好的显示效果

    animation

    二、Unity3D中2D资源的优化工具简介

    实际我们通过一,已经介绍了一个纹理分割的工具Sprite Editor了,下面还有一个工具,就是针对上篇中的非组合打包的图片,Unity3d也提供了一个工具,叫做sprite Packer,使用很简单了(注意下图红圈即可),主要的疑问是性能的提高的效果,这里就需要介绍Unity3d 性能查看工具了,但是发现Unity3d 5.x以后和很多教程上显示的不一样(可能是更新了,这里先不深究以后慢慢研究了)

    sprite Packer

    Stats

    总结

    万里长征第二步终于完成了,没有什么好说的,简单还是简单。

    转载于:https://www.cnblogs.com/IlidanStormRage/p/6043865.html

    展开全文
  • Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D...

    系列目录

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

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

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

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

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

    背景

    最近研究Unity3d,2d寻路的实现。所以又一次涉及到了角色坐标位移的问题。系统的对于这个简单问题进行整理和总结。本来就是一个简单的几何问题,结果发现已经有两个小坑,顺便填上,这里做下总结。

    move1

    实现

    需求:通过鼠标点击,控制2d角色移动,就是点哪里,角色向移动到哪里

    问题分解:按照时间进行动画分解,鼠标输入(动画开始)、平移(动画进行)、移动结束(动画结束)

    前提:这里前面的文章基本解决了一些基础的知识,比如IO获取(鼠标输入),移动的基本方式(Unity中的位置系统transform)

    坑:1、平移中的平滑移动,2、如何确定移动了目标点,并使物体停止下来

    坑1:平移中的平滑移动

    补充知识,关于角色的平移和位置更新,Unity无非就几种方式

    A、transform.Translate(new Vector3(1, 1, 1) * moveSpeed * Time.deltaTime); // Translate方法移动不会考虑刚体等碰撞(会直接穿过物体)

    // 确保我们的速度不会超过maxDistanceDelta
    B、Vector3.MoveTowards(transform.position, targetPos.position, speed * Time.deltaTime);

    // 速度会超过移动速度,像弹簧一样
    C、Vector3.Lerp(transform.position, targetPos.position, speed * Time.deltaTime);

    D、直接设置transform.Positon,最简单的方式

    这个坑,真是坑了很多很多人,目前网上一半以上的教程,从严格意义上都是错误的,这里真的想吐槽一下(太他妈不负责了),这个问题我在群里问过一次,结果还被怀疑是菜鸟,其实焦点还是 我用红色标出的这个线性插值函数,其实简单的不得了,就是个直线方程。这里可以参考,以下这两篇文章

    unity3d问题集 <2> 对Vector3.Lerp 插值的理解

    unity3d Vector3.Lerp解析 http://www.cnblogs.com/shenggege/p/5658650.html

    分析为什么“速度会超过移动速度,像弹簧一样”和 线性插值的函数,后来我仔细想了想,其实还是自己知识掌握的不够透彻,具体我们了解以后分析下,经典教程中的函数

        public float moveSpeed;
        public float turnSpeed;

        private Vector3 moveDirection;
        // Use this for initialization
        void Start () {
            moveDirection = Vector3.right;
        }
       
        // Update is called once per frame
        void Update () {

            // 1
            Vector3 currentPosition = transform.position;
            // 2
            if( Input.GetButton("Fire1") ) {
                // 3
                Vector3 moveToward = Camera.main.ScreenToWorldPoint( Input.mousePosition );
                // 4
                moveDirection = moveToward - currentPosition;
                moveDirection.z = 0;
                moveDirection.Normalize();
            }

            Vector3 target = moveDirection * moveSpeed + currentPosition;
            transform.position = Vector3.Lerp( currentPosition, target, Time.deltaTime );

        }
    }

    这里我们看红色部分的文字,这里之所以不会出现弹簧移动的效果,主要是每次插值都是当前点和这帧将要移动点的位置的插值,其实这里根本没有必要 ,直接设置 transform.position = moveDirection * moveSpeed*Time.deltaTime + currentPosition;(其实本身就是一个 基于时间的线性移动)

    还有 本身 Vector3.Lerp(transform.position, targetPos.position, speed * Time.deltaTime); 这么用就有很大的问题

    A、speed * Time.deltaTime 当speed设置很大而帧率很低的时候这个系数可能全是1,这样根本就是不插值,

    B、当用UGUI时坐标系统是屏幕坐标值很大,这样插值会很不准(这也是我曾经问过的问题,不过没有人回答我)

    至此第一个坑填上了,下面我列出使用不同方式来进行移动的相关代码

    第一种,改进型插值移动

    /// <summary>
    /// 使用Vector3的插值进行更新位置
    /// </summary>
    private void MoveByVector3Lerp()
    {
        //1、获得当前位置
        Vector3 curenPosition = this.transform.position;
        //2、获得方向
        if (Input.GetButton("Fire1"))
        {
            Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            moveTowardPosition = moveToward;
            moveTowardPosition.z = 0;
    
            moveDirection = moveToward - curenPosition;
            moveDirection.z = 0;
            moveDirection.Normalize();
        }
    
        var distance = Vector3.Distance(curenPosition, moveTowardPosition);
       // Debug.Log(string.Format("curenPosition:{0}, moveTowardPosition{1},distance:{2},speed:{3}", curenPosition, moveTowardPosition, distance, speed * Time.deltaTime));
        if (distance < 0.01f)
        {
            transform.position = moveTowardPosition;
        }
        else
        {
            //3、插值移动
            //目标位置方向加上速度移动
            Vector3 target = moveDirection*speed*Time.deltaTime + curenPosition;
            target.z = 0;
            transform.position = target;
        }
    }
    

      

    第二种,MoveTowards进行移动更新

    /// <summary>
    /// 使用Vector3的MoveTowards 直接进行位置更新 
    /// </summary>
    private void MoveByVector3MoveTowards()
    {
        //1、获得当前位置
        Vector3 curenPosition = this.transform.position;
        //2、获得方向
        if (Input.GetButton("Fire1"))
        {
            moveTowardPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            moveTowardPosition.z =0;
        }
        if (Vector3.Distance(curenPosition, moveTowardPosition) < 0.01f)
        {
            transform.position = moveTowardPosition;
        }
        else
        {
            //3、插值移动
            //距离就等于 间隔时间乘以速度即可
            float maxDistanceDelta = Time.deltaTime * speed;
            transform.position = Vector3.MoveTowards(curenPosition, moveTowardPosition, maxDistanceDelta);
        }
    }
    

      

    第三种,transform.Translate

    /// <summary>
    /// 使用Vector3的Translate 直接进行位置更新 
    /// </summary>
    private void MoveByTransformTranslate()
    {
        //1、获得当前位置
        Vector3 curenPosition = this.transform.position;
        //2、获得方向
        if (Input.GetButton("Fire1"))
        {
            moveTowardPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            moveTowardPosition.z = 0;
    
            moveDirection = moveTowardPosition - curenPosition;
            moveDirection.z = 0;
            moveDirection.Normalize();
        }
        //3、插值移动
        Vector3 target = moveDirection * speed * Time.deltaTime + curenPosition;
        target.z = 0;
        if (Vector3.Distance(curenPosition, moveTowardPosition) < 0.01f)
        {
            transform.position = moveTowardPosition;
        }
        else
        {
            transform.Translate(target - curenPosition);
        }
    }
    

      

    坑2:如何确定移动了目标点,并使物体停止下来

    补充知识:其实坑1中列出的三种平移方法,其实并不是什么套路,不是什么标准的动画移动方式,虽然他们也是基于时间的,只能归纳成一种简单的顺序帧移动,这里我查了很多资料还有一种基于时间线的移动方式。

    问题描述:这里先说下坑2是怎么回事,就是我们希望角色移动到鼠标点击的点以后停下来,结果发现停不下来,通过调试日志主要的问题在这一行(这也是我以前提出过的一个问题,但无人解答)

    if (Vector3.Distance(curenPosition, moveTowardPosition) < 0.01f)

    实际上这行代码非常不靠谱,至少有两点

    A、单位差异,UGUI中是屏幕坐标也是localPositon像素,Native中是Unit两个单位不同判断的这个距离常量不一样

    B、由于speed * Time.deltaTime 每帧移动的距离是与速度和帧率有关的,这个常量(0.01)必须与之匹配需要设置合理的值

    C、使用插值计算3维坐标误差会扩大,这里我用“第一种,改进型插值移动”,“第三种,transform.Translate”都出现了误差较大的情况,而“第二种,MoveTowards进行移动更新”,就很准确。

    所以系统给出的函数

    Vector3.MoveTowards(curenPosition, moveTowardPosition, maxDistanceDelta);

    不是白给的,这也是很多人推荐使用这个函数的原因(但不告诉我们为什么)

    最后给出我自己写的基于时间线的位移实现

    /// <summary>
        /// 鼠标点击移动,目标点
        /// </summary>
        private Vector3 moveTowardPosition = Vector3.zero;
        private Vector3 moveStartPosition = Vector3.zero;
        private float totalTime = 0.0f;
        private float costTime = 0.0f;
        private float timePrecent = 0.0f;
    
        private bool _isRuning = false;
    
        /// <summary>
        /// 是否正在移动
        /// </summary>
        public bool IsRuning
        {
            get { return _isRuning; }
            set { _isRuning = value; }
        }
    
        private void MoveByTimeline()
        {
            /*
             * 获得移动的最终目标位置,根据移动速度获得一共需要移动的时间 totalTime
             * 每一帧,
             *   1、累加 已经逝去的时间,并得到costTime,并获得移动的百分比 precent = costTime/totalTime
             *   2、获得当前精灵的位置,根据precent 进行位置插值,得到这一帧应该移动的位置
             *   3、使用设置移动
             *   4、通过precent判断是否<1 来判断是否移动到了目标位置
             *   5、如果完成,则调用最后一次移动实现,终点移动误差,并置为一些标志位
             */
            //获得当前位置
            Vector3 curenPosition = this.transform.position;
            if (Input.GetButton("Fire1"))
            {
                moveStartPosition = curenPosition;
                //获得移动终点位置
                moveTowardPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                moveTowardPosition.z = 0;
    
                costTime = 0.0f;
                //计算记录
                var subVector3 = moveTowardPosition - curenPosition;
                //计算需要移动的总时间
                totalTime = subVector3.magnitude / speed;
    
                _isRuning = true;
            }
            //如果已经移动
            if (_isRuning)
            {
                //如果时间百分比小于1 说明还没有移动到终点
                if (timePrecent < 1)
                {
                    //累加时间
                    costTime += Time.deltaTime;
                    timePrecent = costTime/totalTime;
    
                    Vector3 target = Vector3.Lerp(moveStartPosition, moveTowardPosition, timePrecent);
                    transform.position = target;
      
                }
                else //大于或者等于1 了说明是最后一次移动
                {
                    transform.position = moveTowardPosition;
                    _isRuning = false;
                    moveTowardPosition = Vector3.zero;
                    timePrecent = 0.0f;
                    costTime = 0.0f;
                }
            }
        }
    

      

    这种方法基本排除了,移动到终点的位移误差问题,缺点是使用的临时变量较多(我不喜欢),而“第二种,MoveTowards进行移动更新”可以基本不使用临时变量。时间线动画实际上这也是一些小的平移组件及itween的核心原理(为什么,还需要进一步探索,也许扩展性更强)

    总结

    反正被坑很不爽,不过也怪不了别人,还是自己才疏学浅(不是天才,就使劲干)。下一篇 继续探索角色的系列目标点的移动

    转载于:https://www.cnblogs.com/IlidanStormRage/p/6126362.html

    展开全文
  • 环境:Unity 2019.4.0f1 CubismSdkForUnity-4-r.1 导入SDK之后打开路径D:\Unity\Live2DTEST\Assets\Live2D\Cubism\Samples...记住以后要做到模型视线跟随鼠标/物体移动,这个Look Controller脚本就挂载在我们的Live2D
  • UGUI鼠标点击移动

    千次阅读 2016-11-04 10:34:12
    本章的需求很简单,就是“通过在屏幕中点击鼠标,在2d视图中控制物体进行移动”。在别的平台和引擎中简直是Hello world级别的需求在Unity3d中却变得有些棘手了,主要有几个问题困扰着我, 1、IO输入是怎么样的; ...
  • unity 2D 多边形碰撞框编辑修改

    千次阅读 2014-11-19 11:31:24
    选中多边形碰撞框组件,  可按住shift键,再用鼠标在多边形碰撞器的边框上,添加、移动顶点。要删除一个顶点,只按住Ctrl键,再用鼠标点击相 应的顶点,就可以删除它了
  • 看到这个标题我相信大家应该并不陌生,一般在PC网络游戏中玩家通过鼠标左键在游戏世界中选择角色目标移动位置,接着主角将面朝点击的那 个方向移动。首先就本文来说我们应当掌握的知识点是“鼠标拣选”。这是什么...
  • Unity拖动2d游戏物体

    千次阅读 2018-10-30 22:48:37
    1、 做2d游戏 鼠标点击物体并拖动2d游戏物体移动 2、简单粗暴 上代码 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DragObj : MonoBehaviour { public ...
  • Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D...
  • 今天修改了之前写的飞机大战的代码,原来的不足之处是点击屏幕的任意一点都可以移动飞机,也就是没有检测鼠标到底有没有点到飞机上。 我先是用之前的3D拾取技术,发现没有反应,才意识到我这个plane飞机节点挂载的...
  • Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D...
  • Unity3d 序列目标点的移动

    千次阅读 2017-07-03 17:46:39
    上篇对于角色鼠标点击移动的总结后,感觉自己经验值有点爆棚感觉,可以小小升一级了,虽然这个主题比较小但是是动画的基础,而游戏本身就是又是基于动画基础的,所以还是很有意义的。 由于要研究2d的寻路算法,A*...
  • Unity3D基础】让物体动起来①--基于UGUI的鼠标点击移动Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D...
  • unity给LineRenderer添加collider

    千次阅读 2015-09-16 21:13:32
    需求:在使用LineRenderer的时候,需要能够使其能够触发鼠标点击事件。想实现如下图,点击线能够实现向相邻的节点移动: 我们的线是使用LineRenderer画的, 那么问题来了,给这条线加上一个BoxCollider2D...
  • World Map 2D Edition 2添加到您的场景一个美丽的,可定制和互动的二维政治地图只需点击几下。将地图预设拖到场景中,然后自定义外观。 这个新的主要版本改进了视觉效果,并支持标准/内置和LWRP。所有的新特性和...
  • 终于到了本系列完结的时候了。 现在,大家对LuaFramework有个全方位的理解了吧!接下来通过一个例子总结tolua,作为“lua逻辑”的延伸,说明lua的写法...当玩家点击鼠标左键,角色会发射一颗炮弹。 2、游戏资源 ...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

unity2d鼠标点击移动