unity3d 物体抖动怎么做

2020-02-02 14:53:20 weixin_43455008 阅读数 257
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity中实现物体动态动画效果

实现游戏物体上下抖动一样的动态效果。
效果图 :
在这里插入图片描述
代码如下 :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PictureShake : MonoBehaviour
{
    public float shakeSpeed = 1;

    public float shakeTimeValue = 0.5f;
    private float shakeTime;
    private int isUp = 1;

    private void Start()
    {
        shakeTime = shakeTimeValue;
    }

    void Update()
    {
        if (shakeTime > 0)
        {
            transform.localPosition += new Vector3(0, Time.deltaTime * shakeSpeed * isUp);
            shakeTime -= Time.deltaTime;
        }
        else
        {
            isUp *= -1;
            shakeTime = shakeTimeValue;
        }
    }
}

游戏物体图片作为角色子物体存在,脚本挂在图片上,这样可以不用改变角色本身位置。

2016-05-24 20:28:08 yutyliu 阅读数 9896
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

把外部软件制作的动画文件,导入到untiy3d里面的时候,你会发现很多动画文件会一抖一抖的,特别是动画比较精细的部分,诸如腿部,手部末端。

这个问题困扰了很久,然后某天把动作文件在Animation中打开,一帧一帧的观看,一个骨骼一个骨骼的看位移和旋转,发现抖动的时候,这个骨骼的数字都非常的小,很多时候都到了小数点后面很多位。这个时候,我把动画文件拷出来,通过修改帧里数值到一个比较大的数值后,发现不抖动了。此时,想到了一个问题,那就是精度丢失。

unity3d里将导入的动画文件,每帧数的位移,旋转和缩放都存放为一个个的浮点型的数据。然后在播放的时候,是基于世界缩放的,也就是把这些数值,都会乘以上层的缩放,然后改变骨骼的数据信息,赋予数值上去,如果要乘以的缩放比较小,就会导致小数位占比较多,浮点型的精度是有限的,就会导致动画的一些精度丢失。这个时候,将上层缩放乘以10倍,就好了很多,基本上抖动幅度非常小了,如果乘以100,那就不会有任何的抖动了。

这个只是在unity3d里做文章,会有一个坏处就是,模型的比例和场景的比例对不上,还要调整场景的缩放。所以比较好一些的做法,应该是美术那边,调动作的时候,尽量保证精度,避免出现这个问题

2014-09-13 00:20:22 yxriyin 阅读数 16041
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

     用unity3d 如果你没有碰到摄像机抖动的问题,那么你是幸运的。我相信如果你的摄像机控制比较复杂,或者人物移动比较复杂,或多或少总会有这样的疑惑:摄像机好像再抖,或许是模型在抖。总之就是各种抖。当你以为发现问题并解决了,一切都很好,突然有一天,它又开始抖了,而且不止一次这样。我就碰到过这种情况,特此做下总结。

    首先你要理解摄像机什么情况下会给你抖动的感觉,简单来说你如果想让摄像机抖动,那么肯定是让摄像机不停变换位置,而且是无规则的。说白了,就是不规则的速度变化会引起抖动。注意这里是相对速度,因为如果绝对速度在变化,但相对速度是一致的,其实你看到的物体是不抖的。这一点在后面的一种情况会用到。接下来就分析下各种情况和原因以级解决方案。

1.摄像机控制很简单,却有大幅度的抖动。

这种情况其实一般不是摄像机控制的问题,而是你摄像机所看物体的策略的问题。首先你要确保摄像机是没帧都更新位置的,你可以放在Update()函数中或者LateUpdate()函数中,切忌不要放在FixedUpdate中去更新位置,因为FixedUpdate不保证没帧都执行,这样就会有断续的现象。然后你要确保摄像机看向的物体的移动是正常的,就是说物体不是在那里抖动的,但摄像机却没有一起抖,这可能和你的逻辑有关。不过这种情况并不常见。大部分时候,相信简单的摄像机控制是最能保证稳定的画面的。


2.摄像机控制简单,大部分时候不抖动,偶尔抖一下,时断时续。

这种情况非常令人困惑,因为理论上应该是不会抖动的,甚至很多时候你要怀疑是不是unity3d自己的问题或者我的帧数不稳定引起的?这里我首先要非常明确一点:Unity3d是一个成熟的商业产品,如果你能够确保正确使用里面的组件和写下正确的代码,那么是不会有这些问题的,包括摄像机抖动和其他一些常见的问题。你首先要看自己的代码和用法是否有问题。

这种情况的原因可能会比较多,我这里只列举我自己碰到的。第一种是因为不必要的平滑算法引起的。你可能会觉得奇怪,平滑算法难道不是为了摄像机不抖而存在的吗?怎么反而会引起摄像机抖动。甚至有的时候你感觉摄像机抖,然后加了平滑算法就不抖了。这里我要解释一下,也是一开始说的,摄像机抖动是基于相对速度的变化不稳定。那么假设你的摄像机本身控制比较简单,其实我们可以基本肯定相对变化速度是一致的。比如你摄像机就是看着一个人,这个去哪摄像机看哪,那么是不是说两人相对速度其实为0。然后你说人抖动怎么办?那么摄像机会一起抖,只不过由于他们相对速度为0,所以你看人是不抖的,但是如果你有场景作为背景,那么你会感觉地面有点抖。这是必须权衡的,因为在场景和人物不同步的情况下,肯定会有一个相对稳定而另一个相对抖动,一般我们和人物一致就好了,毕竟人的视觉肯定是聚焦人物的。那么在这样的基础上,我加了平滑算法,会怎么样呢?平滑无非两种,一种是延迟,一种是根据以前的速度进行加速度计算,然速度变化变慢。不论哪种,在摄像机控制简单的情况下都是画蛇添足。因为首先你已经确保了人和摄像机之间的稳定性。你却加了这种算法,导致了他们不再稳定,而且同时你也无法弥补场景那边被牺牲的抖动,可能反而更抖了。那么照这么说,平滑算法岂不是没用?不是的,后面的情况你会看到平滑算法的引用。只是在摄像机规则很简单的情况下,并不需要额外的平滑算法。

这里还有个小细节,就是你的摄像机一定要先设置好位置,再LookAt,如果你先LookAt,再设置摄像机的位置的话,那么你的摄像机其实LookAt了另一个地方了。这也是引起抖动的原因之一。

3.摄像机控制比较复杂,有时经常抖动,有时候又不抖,神经病一样的。

这种情况就开始复杂起来了。首先我建议你将摄像机改成简单的规则,看是否有抖动。有的话参考1和2里面的先处理。

如果你发现规则简单的时候是不抖动的,但规则复杂的时候抖动,那么你就要好好看看你的规则的代码了。如果你的摄像机移动有速度的概念,一定要将速度和Time.dealtTime联系在一起。也就是这一帧跑了多久时间,这是很重要的,因为每一帧的时间不同,你如果采用相同的位移,其实会引起不同的速度感。

其次,你要明确你的移动算法是基于匀速的,不论是移动还是旋转,都应该是匀速的(也许也可以基于某种速度变化规则,但务必是有规则的运动)。这里特别要注意匀速运动如果到了终点之前,其实是要一个减速的,不然就会过头,过头的话下一帧可能需要回到正确的位置,就会回退了,如此反复,也会抖动。

第三,不建议用ITween这种插件控制摄像机运动,因为它内部的代码其实并没有考虑这些,所以你用ITween导致摄像机抖动是很正常的。当然你图方便然后觉得抖就抖吧那倒是无所谓。

最后,如果还是找不到原因,就排除法,一句句注释掉代码,看到底是哪一句引起了抖动,然后再仔细分析原因。


4. 从正常的逻辑角度来讲摄像机确实会抖动,客观原因。

这种情况也不多,但确实存在。比如你的摄像机的规则是对准多个目标的中心,或者还和力啊,人的转向啊,人的速度变化很突然啊等等有关。如果本身的设计就是导致摄像机抖动的原因,那么这个时候就是平滑算法的用途了,平滑算法本身就是为了让本来变化的不稳定的速度趋于稳定。具体平滑算法有时间再写吧。今天要睡觉了。


2019-06-24 19:50:51 weixin_34268310 阅读数 209
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

这里是一个简单的摄像机抖动方法,记录下来便于查阅。

public class CameraShake : MonoBehaviour {

    // 抖动目标的transform(若未添加引用,怎默认为当前物体的transform)
    public Transform camTransform;

    //持续抖动的时长
    public float shake = 0f;

    // 抖动幅度(振幅)
  //振幅越大抖动越厉害
public float shakeAmount = 0.7f; public float decreaseFactor = 1.0f; Vector3 originalPos; void Awake() { if (camTransform == null) { camTransform = GetComponent(typeof(Transform)) as Transform; } } void OnEnable() { originalPos = camTransform.localPosition; } void Update() { if (shake > 0) { camTransform.localPosition = originalPos + Random.insideUnitSphere * shakeAmount; shake -= Time.deltaTime * decreaseFactor; } else { shake = 0f; camTransform.localPosition = originalPos; } } }

实际上可以抖动任何物体。

转载于:https://www.cnblogs.com/seancheung/p/3990567.html

2017-08-23 17:56:37 yongh701 阅读数 7574
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

《【Unity3D】自动寻路》(点击打开链接)给我们带来很多方便,尤其是3D游戏的主角移动方面,但是这个东西同样也会带来很多问题。如下图所示。这是一个比较失败的自动寻路例子,由于蓝色的球并不是让玩家主控,只是一个NPC,而这个NPC未来又可能像主角一样进行移动,我们无法像白色的立方体如同墙一样,在自动寻路界面给它上一个Navigation Static属性,因此,我们只是给红球和蓝球共同上一个刚体RigidBody的属性。

此时大家就可以看到如下图的问题,虽然蓝色球作为一个刚体被撞产生移动是没问题,但首先我们不像这个球被撞出白色平面。由于蓝色球不像,也不可能像红色球上一个Nav Mesh Agent组件,不然会影响自动寻路的。同时,还有更严重的问题,红色球在自动寻路的移动中,不可避免地有可能和蓝色的球产生碰撞,然而才产生碰撞之后,红色球的开始鬼畜地抖动,同时不停控制在无须移动了——大家可以看到我的鼠标根本没点Plane任何一个地方,这种鬼畜的抖动和不停使唤的情况在自动寻路Nav Mesh Agent组件的加速度Acceleration设置得越高越为明显。


以下是上述两个大问题的解决方案,让自动寻路至少看起来更合理更完美一些。

一、刚体自动寻路的抖动问题

首先,正如上面提到的,对于上了Nav Mesh Agent组件的自动寻路主角,如果你想它移动快一些,你应该将其Speed调大,而不是Acceleration。


当然,以上仅仅是一个治标不治本的做法,更多的是,需要同时给自动寻路主角,也就是上例红色的球,上一个Rigidbody属性,同时将Is Kinematic勾上,

至于诸如上图的蓝色球,这类不是诸如白色墙Navigation Static一动不动的,而是未来或许会和自动寻路主角,也就是上例的红色球,发生交互的物体,你也同样上一个Rigidbody属性,但要将Is Kinematic取消掉。


这时,红色球的自动寻路就不会有鬼畜抖动的效果,能够做到完美寻路了,你并不需要还在脚本特意写些条件,视图锁定xyz轴的position和rotation这么复杂。

你只需要弄好Is Kinematic这个属性就好。Is Kinematic的官方定义是这样的:


上述文字取自Unity3D的对于刚体Rigidbody的官方API。这个属性之所以这么大魔力,主要是因为它控制了,这个刚体首先是影响物理引擎的东西,也就是像蓝色球被撞,它根据3D碰撞力会向其余地方移动,还是首先响应运动学,也就是人为改变其transform的动作。

我们在不停对这个红色球进行自动寻路动作,其实就是,不停人为改变其transform。大部分情况下,在刚体自动寻路产生严重的抖动问题,也就是不停地在鬼畜,原因就是,默认情况下,刚体是没有勾上Is Kinematic的。导致其不停计算碰撞又不停计算我们对其下达的自动寻路命令,因此导致了严重的鬼畜。

二、运动边界空气墙的制作

之后,我们借防止蓝色球滑落Plane,说说运动边界,空气墙的制作。运动边界,空气墙在3D游戏中很常见的,毕竟地图再大如《上古卷轴》或者《辐射》也就是有边界的,更不用说《极品飞车》这种规定路线移动的游戏了,我们注定要设置一个运动边界,不可能让玩家移动到地图外面去,诸如这个例子,蓝色球被碰到Plane外面了。

所以我们要制作运动边界和空气墙。毕竟,蓝球,并非自动寻路的主角红球,不会自动产生运动边界。至于红球如何取消运动边界可以参看《【Unity3D】自动寻路的跳跃》(点击打开链接)。

空气墙实质就是一个看不到的立方体而已,如下图所示:


其制作不是通过cube弄出来的,而是在一个空物体Empty中加一个特定位置的Box Collider完成的。当然,墙也不一定是立方体的形状,Unity3D本身就有Sphere Collider等各种形状的碰撞体。这样刚体碰到这个透明的东西,就真的像碰到空气墙一样了。


或许有人说我为何不直接弄个大的边界碰撞盒子来完成这个问题,也就是这样,多省事啊!


这样当然不行,因为Unity3D所有的碰撞体都不是实心的。这样做,最后的效果,就是这个碰撞盒子里面的所有刚体,直接被击飞不知道飞哪里去的。因为Unity3D对于碰撞的计算是根据刚体与刚体在下一帧的可能相交体积来决定的。


上述两个物体解决之后,就能收到以下比较完美的效果图,可以看到红球在自动寻路的过程中,就算碰到蓝球都没鬼畜和不可控现象,并且蓝球也不会被撞出Plane,掉下去。

其实完全可以根据上述原理来完成一个台球游戏啊!